182 lines
5.9 KiB
C++
182 lines
5.9 KiB
C++
module;
|
|
#include "STM32L4x2.h"
|
|
export module io;
|
|
|
|
/// Asociace port Adress a RCC clock
|
|
struct GpioAssocPort {
|
|
GPIOA_Type * const portAdr;
|
|
uint32_t clkMask;
|
|
};
|
|
|
|
/**
|
|
* @brief GPIO Configuration Mode enumeration
|
|
*/
|
|
typedef enum {
|
|
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 */
|
|
}GPIOMode_TypeDef;
|
|
|
|
/**
|
|
* @brief GPIO Output type enumeration
|
|
*/
|
|
typedef enum {
|
|
GPIO_OType_PP = 0x00,
|
|
GPIO_OType_OD = 0x01
|
|
}GPIOOType_TypeDef;
|
|
/**
|
|
* @brief GPIO Output Maximum frequency enumeration
|
|
*/
|
|
typedef enum {
|
|
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 */
|
|
}GPIOSpeed_TypeDef;
|
|
/**
|
|
* @brief GPIO Configuration PullUp PullDown enumeration
|
|
*/
|
|
typedef enum {
|
|
GPIO_PuPd_NOPULL = 0x00,
|
|
GPIO_PuPd_UP = 0x01,
|
|
GPIO_PuPd_DOWN = 0x02
|
|
}GPIOPuPd_TypeDef;
|
|
|
|
/** Vstupní parametry metod */
|
|
typedef enum {
|
|
GPIO_Dir_Mode_IN = 0x00, /*!< GPIO Input Mode */
|
|
GPIO_Dir_Mode_OUT = 0x01, /*!< GPIO Output Mode */
|
|
} GPIODir_TypeDef;
|
|
|
|
/// Enum pro PortNumber
|
|
typedef enum {
|
|
GpioPortA,
|
|
GpioPortB,
|
|
GpioPortC,
|
|
GpioPortD,
|
|
GpioPortE,
|
|
GpioPortH,
|
|
} GpioPortNum;
|
|
namespace io {
|
|
/** @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 {
|
|
if (b) io->BSRR.R = (uint32_t) pos;
|
|
else io->BSRR.R = (uint32_t) pos << 16;
|
|
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;
|
|
|
|
};
|
|
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 */
|
|
|
|
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 */
|
|
|
|
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);
|
|
}
|
|
};
|