Module/io.cpp

183 lines
5.9 KiB
C++
Raw Permalink Normal View History

2024-01-16 16:14:54 +01:00
module;
#include "STM32L4x2.h"
export module io;
/// Asociace port Adress a RCC clock
struct GpioAssocPort {
2024-01-16 20:23:10 +01:00
GPIOA_Type * const portAdr;
2024-01-18 11:42:56 +01:00
uint32_t clkMask;
2024-01-16 16:14:54 +01:00
};
2024-01-18 11:42:56 +01:00
namespace io {
/**
* @brief GPIO Configuration Mode enumeration
*/
enum GPIOMode_TypeDef {
GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */
GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */
GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */
GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */
};
2024-01-16 16:14:54 +01:00
2024-01-18 11:42:56 +01:00
/**
* @brief GPIO Output type enumeration
*/
enum GPIOOType_TypeDef {
GPIO_OType_PP = 0x00,
GPIO_OType_OD = 0x01
};
/**
* @brief GPIO Output Maximum frequency enumeration
*/
enum GPIOSpeed_TypeDef {
GPIO_Speed_LS = 0x00, /*!< Low speed */
GPIO_Speed_MS = 0x01, /*!< Medium speed */
GPIO_Speed_FS = 0x02, /*!< Fast speed */
GPIO_Speed_HS = 0x03 /*!< Very High speed */
};
/**
* @brief GPIO Configuration PullUp PullDown enumeration
*/
enum GPIOPuPd_TypeDef {
GPIO_PuPd_NOPULL = 0x00,
GPIO_PuPd_UP = 0x01,
GPIO_PuPd_DOWN = 0x02
};
2024-01-16 16:14:54 +01:00
2024-01-18 11:42:56 +01:00
/** Vstupní parametry metod */
enum GPIODir_TypeDef {
GPIO_Dir_Mode_IN = 0x00, /*!< GPIO Input Mode */
GPIO_Dir_Mode_OUT = 0x01, /*!< GPIO Output Mode */
};
2024-01-16 16:14:54 +01:00
2024-01-18 11:42:56 +01:00
/// Enum pro PortNumber
enum GpioPortNum {
GpioPortA = 0,
GpioPortB,
GpioPortC,
GpioPortD,
GpioPortE,
GpioPortH,
};
2024-01-16 16:14:54 +01:00
/** @file
* @brief Obecný GPIO pin.
*
* @class GpioClass
* @brief Obecný GPIO pin.
*
*/
export class GpioClass {
public:
/** Konstruktor
@param port GpioPortA | GpioPortB | GpioPortC | GpioPortD | GpioPortF
@param no číslo pinu na portu
@param type IN, OUT, AF, AN default OUT
*/
GpioClass (GpioPortNum const port, const uint32_t no, const GPIOMode_TypeDef type = GPIO_Mode_OUT);
/// Nastav pin @param b na tuto hodnotu
const GpioClass& operator<< (const bool b) const {
2024-01-18 11:42:56 +01:00
const uint32_t sh = b ? pos : pos << 16;
io->BSRR.R = sh;
2024-01-16 16:14:54 +01:00
return *this;
}
/// Nastav pin na log. H
const GpioClass& operator+ (void) const {
io->BSRR.R = (uint32_t) pos;
return *this;
}
/// Nastav pin na log. L
const GpioClass& operator- (void) const {
io->BSRR.R = (uint32_t) pos << 16;
return *this;
}
/// Změň hodnotu pinu
const GpioClass& operator~ (void) const {
io->ODR.R ^= pos;
return *this;
};
/// Načti logickou hodnotu na pinu
const bool get (void) const {
if (io->IDR.R & pos) return true;
else return false;
};
/// A to samé jako operátor
const GpioClass& operator>> (bool& b) const {
b = get();
return *this;
}
/// Různá nastavení
void setMode (GPIOMode_TypeDef p) {
uint32_t dno = num * 2;
io->MODER.R &= ~(3UL << dno);
io->MODER.R |= (p << dno);
}
void setOType (GPIOOType_TypeDef p) {
io->OTYPER.R &= ~(1UL << num);
io->OTYPER.R |= (p << num);
}
void setSpeed (GPIOSpeed_TypeDef p) {
uint32_t dno = num * 2;
io->OSPEEDR.R &= ~(3UL << dno);
io->OSPEEDR.R |= (p << dno);
}
void setPuPd (GPIOPuPd_TypeDef p) {
uint32_t dno = num * 2;
io->PUPDR.R &= ~(3UL << dno);
io->PUPDR.R |= (p << dno);
}
void setAF (unsigned af) {
unsigned int pd,pn = num;
pd = (pn & 7) << 2; pn >>= 3;
if (pn) {
io->AFRH.R &= ~(0xFU << pd);
io->AFRH.R |= ( af << pd);
} else {
io->AFRL.R &= ~(0xFU << pd);
io->AFRL.R |= ( af << pd);
}
}
void setDir (GPIODir_TypeDef p) {
uint32_t dno = num * 2;
if (p) io->MODER.R |= (1UL << dno);
else io->MODER.R &= ~(3UL << dno);
}
private:
/// Port.
GPIOA_Type * const io; // může být klidně i odkaz, ale je to stejné, necháme to tak jak bylo
/// A pozice pinu na něm, stačí 16.bit
const uint16_t pos;
/// pro funkce setXXX necháme i číslo pinu
const uint16_t num;
};
2024-01-16 20:23:10 +01:00
static constexpr uint32_t RCC_AHB2ENR_GPIOAEN = (0x00000001u); /*!< Ofs=0 IO port A clock enable */
static constexpr uint32_t RCC_AHB2ENR_GPIOBEN = (0x00000002u); /*!< Ofs=1 IO port B clock enable */
static constexpr uint32_t RCC_AHB2ENR_GPIOCEN = (0x00000004u); /*!< Ofs=2 IO port C clock enable */
static constexpr uint32_t RCC_AHB2ENR_GPIODEN = (0x00000008u); /*!< Ofs=3 IO port D clock enable */
static constexpr uint32_t RCC_AHB2ENR_GPIOEEN = (0x00000010u); /*!< Ofs=4 IO port E clock enable */
static constexpr uint32_t RCC_AHB2ENR_GPIOHEN = (0x00000080u); /*!< Ofs=7 IO port H clock enable */
2024-01-16 16:14:54 +01:00
2024-01-16 20:23:10 +01:00
static GPIOA_Type * const pGPIOA = ((GPIOA_Type * const) 0x48000000u); /*!< General-purpose I/Os */
static GPIOA_Type * const pGPIOB = ((GPIOA_Type * const) 0x48000400u); /*!< General-purpose I/Os */
static GPIOA_Type * const pGPIOC = ((GPIOA_Type * const) 0x48000800u); /*!< General-purpose I/Os */
static GPIOA_Type * const pGPIOD = ((GPIOA_Type * const) 0x48000C00u); /*!< General-purpose I/Os */
static GPIOA_Type * const pGPIOE = ((GPIOA_Type * const) 0x48001000u); /*!< General-purpose I/Os */
static GPIOA_Type * const pGPIOH = ((GPIOA_Type * const) 0x48001C00u); /*!< General-purpose I/Os */
2024-01-16 16:14:54 +01:00
static const struct GpioAssocPort cPortTab[] = {
{pGPIOA, RCC_AHB2ENR_GPIOAEN},
{pGPIOB, RCC_AHB2ENR_GPIOBEN},
{pGPIOC, RCC_AHB2ENR_GPIOCEN},
{pGPIOD, RCC_AHB2ENR_GPIODEN},
{pGPIOE, RCC_AHB2ENR_GPIOEEN},
{pGPIOH, RCC_AHB2ENR_GPIOHEN},
};
GpioClass::GpioClass (GpioPortNum const port, const uint32_t no, const GPIOMode_TypeDef type) :
io (cPortTab[port].portAdr), pos(1UL << no), num(no) {
// Povol hodiny
RCC.AHB2ENR.R |= cPortTab[port].clkMask;
setMode (type);
}
};