From 2f8ba8d9ee3fe58a8cd63c040dcd19a03db663af Mon Sep 17 00:00:00 2001 From: Ea-r-th <39779954+Ea-r-th@users.noreply.github.com> Date: Wed, 10 Sep 2025 01:20:50 -0700 Subject: [PATCH] Major refactor for entire system - wrong branch but get over it --- .../Peripheral/GPIO/Reg/SHAL_GPIO_TYPES.h | 44 ++++++++++++- SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h | 65 +++++-------------- .../Peripheral/I2C/Reg/SHAL_I2C_REG_F072xB.h | 10 +-- .../Peripheral/I2C/Reg/SHAL_I2C_TYPES.h | 4 +- .../Peripheral/UART/Reg/SHAL_UART_TYPES.h | 4 +- SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp | 58 ++++++++--------- SHAL/Src/Peripheral/UART/SHAL_UART.cpp | 21 ++---- SHAL/Src/main.cpp | 11 ++-- 8 files changed, 106 insertions(+), 111 deletions(-) diff --git a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_TYPES.h b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_TYPES.h index a4fa55f..0dcbeb1 100644 --- a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_TYPES.h +++ b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_TYPES.h @@ -7,7 +7,6 @@ #include "SHAL_CORE.h" - struct SHAL_EXTIO_Register{ volatile uint32_t* EXT_ICR; uint32_t mask; @@ -24,6 +23,49 @@ struct SHAL_Peripheral_Register { unsigned long offset; }; +enum class PinMode : uint8_t{ + INPUT_MODE = 0x00, + OUTPUT_MODE = 0x01, + ALTERNATE_FUNCTION_MODE = 0x02, + ANALOG_MODE = 0x03, + INVALID = 0x00, +}; + +enum class GPIO_Alternate_Function : uint8_t{ + AF0 = 0x00, + AF1 = 0x01, + AF2 = 0x02, + AF3 = 0x03, + AF4 = 0x04, + AF5 = 0x05, + AF6 = 0x06, + AF7 = 0x07, +}; + +enum class PinType : uint8_t{ + PUSH_PULL = 0x00, + OPEN_DRAIN = 0x01, +}; + +enum class InternalResistorType : uint8_t{ + NO_PULL = 0x00, + PULLUP = 0x01, + PULLDOWN = 0x02, +}; + +enum class OutputSpeed : uint8_t{ + LOW_SPEED = 0x00, + MEDIUM_SPEED = 0x01, + HIGH_SPEED = 0x02, + VERY_HIGH_SPEED = 0x03, +}; + +enum class TriggerMode : uint8_t{ + RISING_EDGE, + FALLING_EDGE, + RISING_FALLING_EDGE +}; + #endif //SHMINGO_HAL_SHAL_GPIO_TYPES_H diff --git a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h index 597c3f6..b8fdccf 100644 --- a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h +++ b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h @@ -11,48 +11,7 @@ #include "SHAL_EXTI_CALLBACK.h" -enum class PinMode : uint8_t{ - INPUT_MODE = 0x00, - OUTPUT_MODE = 0x01, - ALTERNATE_FUNCTION_MODE = 0x02, - ANALOG_MODE = 0x03, - INVALID = 0x00, -}; -enum class GPIO_Alternate_Function : uint8_t{ - AF0 = 0x00, - AF1 = 0x01, - AF2 = 0x02, - AF3 = 0x03, - AF4 = 0x04, - AF5 = 0x05, - AF6 = 0x06, - AF7 = 0x07, -}; - -enum class PinType : uint8_t{ - PUSH_PULL = 0x00, - OPEN_DRAIN = 0x01, -}; - -enum class InternalResistorType : uint8_t{ - NO_PULL = 0x00, - PULLUP = 0x01, - PULLDOWN = 0x02, -}; - -enum class OutputSpeed : uint8_t{ - LOW_SPEED = 0x00, - MEDIUM_SPEED = 0x01, - HIGH_SPEED = 0x02, - VERY_HIGH_SPEED = 0x03, -}; - -enum class TriggerMode : uint8_t{ - RISING_EDGE, - FALLING_EDGE, - RISING_FALLING_EDGE -}; @@ -67,6 +26,8 @@ public: void setHigh(); void setLow(); + void setPinMode(PinMode mode) volatile; + void setAlternateFunction(GPIO_Alternate_Function AF) volatile; void setPinType(PinType type) volatile; @@ -75,31 +36,39 @@ public: void setInternalResistor(InternalResistorType type) volatile; + + void useAsExternalInterrupt(TriggerMode mode, EXTICallback callback); + private: friend class GPIOManager; - explicit GPIO(GPIO_Key key, PinMode pinMode); + explicit GPIO(GPIO_Key key); GPIO(); GPIO_Key m_GPIO_KEY = GPIO_Key::INVALID; }; -//Init GPIO for normal use -#define initGPIO(GPIO_KEY, PIN_MODE) GPIOManager::get(GPIO_KEY, PIN_MODE) -//Init GPIO for use as an external interrupt -#define useGPIOAsInterrupt(GPIO_KEY, Trigger_Mode, Callback) GPIOManager::getInterruptGPIO(GPIO_KEY, Trigger_Mode, Callback) + + + +//Init GPIO for normal use +#define PIN_TO_KEY(name) GPIO_Key::name +#define PIN(name) GPIOManager::get(PIN_TO_KEY(name)) + +#define GET_GPIO(key) GPIOManager::get(key) + +#define GPIO_A //Manages instances of GPIO objects class GPIOManager{ public: - static GPIO& get(GPIO_Key, PinMode pinMode); + static GPIO& get(GPIO_Key); - static void getInterruptGPIO(GPIO_Key key, TriggerMode mode, EXTICallback callback); GPIOManager() = delete; diff --git a/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_F072xB.h b/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_F072xB.h index 7e458e8..53ed576 100644 --- a/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_F072xB.h +++ b/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_REG_F072xB.h @@ -25,14 +25,14 @@ enum class I2C_Pair : uint8_t{ constexpr SHAL_I2C_Pair getI2CPair(const I2C_Pair pair){ switch(pair){ - case I2C_Pair::SCL1B6_SDA1B7: return {I2C1,GPIO_Key::B6,GPIO_Key::B7,AF_Mask::AF1,AF_Mask::AF1}; - case I2C_Pair::SCL1B8_SDA1B9: return {I2C1,GPIO_Key::B8,GPIO_Key::B9,AF_Mask::AF1,AF_Mask::AF1}; - case I2C_Pair::SCL2B10_SDA2B11: return {I2C2,GPIO_Key::B10,GPIO_Key::B11,AF_Mask::AF1,AF_Mask::AF1}; - case I2C_Pair::SCL2B13_SDA2B14: return {I2C2,GPIO_Key::B13,GPIO_Key::B14,AF_Mask::AF5,AF_Mask::AF5}; + case I2C_Pair::SCL1B6_SDA1B7: return {I2C1,GPIO_Key::B6,GPIO_Key::B7,GPIO_Alternate_Function::AF1,GPIO_Alternate_Function::AF1}; + case I2C_Pair::SCL1B8_SDA1B9: return {I2C1,GPIO_Key::B8,GPIO_Key::B9,GPIO_Alternate_Function::AF1,GPIO_Alternate_Function::AF1}; + case I2C_Pair::SCL2B10_SDA2B11: return {I2C2,GPIO_Key::B10,GPIO_Key::B11,GPIO_Alternate_Function::AF1,GPIO_Alternate_Function::AF1}; + case I2C_Pair::SCL2B13_SDA2B14: return {I2C2,GPIO_Key::B13,GPIO_Key::B14,GPIO_Alternate_Function::AF5,GPIO_Alternate_Function::AF5}; case I2C_Pair::NUM_PAIRS: case I2C_Pair::INVALID: assert(false); - return {nullptr,GPIO_Key::INVALID,GPIO_Key::INVALID,AF_Mask::AF0,AF_Mask::AF0}; + return {nullptr,GPIO_Key::INVALID,GPIO_Key::INVALID,GPIO_Alternate_Function::AF0,GPIO_Alternate_Function::AF0}; } __builtin_unreachable(); } diff --git a/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_TYPES.h b/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_TYPES.h index c88a007..3b93c27 100644 --- a/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_TYPES.h +++ b/SHAL/Include/Peripheral/I2C/Reg/SHAL_I2C_TYPES.h @@ -13,8 +13,8 @@ struct SHAL_I2C_Pair { I2C_TypeDef* I2CReg; GPIO_Key SCL_Key; GPIO_Key SDA_Key; - AF_Mask SCL_Mask; - AF_Mask SDA_Mask; + GPIO_Alternate_Function SCL_Mask; + GPIO_Alternate_Function SDA_Mask; }; struct SHAL_I2C_Enable_REG{ diff --git a/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_TYPES.h b/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_TYPES.h index 8441948..b6a658d 100644 --- a/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_TYPES.h +++ b/SHAL/Include/Peripheral/UART/Reg/SHAL_UART_TYPES.h @@ -15,8 +15,8 @@ struct SHAL_UART_Pair{ USART_TypeDef* USARTReg; GPIO_Key TxKey; GPIO_Key RxKey; - GPIO_Alternate_Function TxMask; - GPIO_Alternate_Function RxMask; + GPIO_Alternate_Function TxAlternateFunctionMask; + GPIO_Alternate_Function RxAlternateFunctionMask; }; struct SHAL_UART_ENABLE_REG{ diff --git a/SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp b/SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp index 82739d6..326a2ec 100644 --- a/SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp +++ b/SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp @@ -11,20 +11,12 @@ GPIO::GPIO() : m_GPIO_KEY(GPIO_Key::INVALID){ //Do not initialize anything } -GPIO::GPIO(GPIO_Key key, PinMode pinMode) : m_GPIO_KEY(key) { - - SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(key); - - auto gpioRegister = gpioPeripheral.reg; - unsigned long registerOffset = gpioPeripheral.global_offset; +GPIO::GPIO(GPIO_Key key) : m_GPIO_KEY(key) { volatile unsigned long* gpioEnable = getGPIORCCEnable(key).reg; unsigned long gpioOffset = getGPIORCCEnable(key).offset; *gpioEnable |= (1 << gpioOffset); //Set enable flag - - gpioRegister->MODER &= ~(0x03 << (2 * registerOffset)); //Clear any previous mode - gpioRegister->MODER |= (static_cast(pinMode) << (2 * registerOffset)); //Set mode based on pinmode bit structure } void GPIO::setLow() { @@ -42,6 +34,8 @@ void GPIO::toggle() volatile { gpioPeripheral.reg->ODR ^= (1 << gpioPeripheral.global_offset); } + + void GPIO::setPinType(PinType type) volatile { SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY); gpioPeripheral.reg->OTYPER &= ~(1 << gpioPeripheral.global_offset); @@ -68,41 +62,30 @@ void GPIO::setAlternateFunction(GPIO_Alternate_Function AF) volatile { gpioPeripheral.reg->AFR[afrIndex] |= (static_cast(AF) << (gpioPeripheral.global_offset * 4)); } - -GPIO& GPIOManager::get(GPIO_Key key, PinMode pinMode) { - - unsigned int gpioPort = getGPIOPortNumber(key); - unsigned long gpioPin = getGPIORegister(key).global_offset; //Use existing structs to get offset - - if (m_gpios[gpioPort][gpioPin].m_GPIO_KEY == GPIO_Key::INVALID){ - m_gpios[gpioPort][gpioPin] = GPIO(key,pinMode); - } - - return m_gpios[gpioPort][gpioPin]; +void GPIO::setPinMode(PinMode mode) volatile { + SHAL_GPIO_Peripheral gpioPeripheral = getGPIORegister(m_GPIO_KEY); + gpioPeripheral.reg->MODER &= ~(0x03 << (2 * gpioPeripheral.global_offset)); //Clear any previous mode + gpioPeripheral.reg->MODER |= (static_cast(mode) << (2 * gpioPeripheral.global_offset)); //Set mode based on pinmode bit structure } -void GPIOManager::getInterruptGPIO(GPIO_Key key, TriggerMode triggerMode, EXTICallback callback) { +void GPIO::useAsExternalInterrupt(TriggerMode mode, EXTICallback callback) { - uint32_t gpioPort = getGPIOPortNumber(key); - uint32_t gpioPin = getGPIORegister(key).global_offset; //Use existing structs to get offset + uint32_t gpioPin = getGPIORegister(m_GPIO_KEY).global_offset; //Use existing structs to get offset - if (m_gpios[gpioPort][gpioPin].m_GPIO_KEY == GPIO_Key::INVALID){ - m_gpios[gpioPort][gpioPin] = GPIO(key,PinMode::INPUT_MODE); //Hardcode input mode for interrupt - } + setPinMode(PinMode::INPUT_MODE); //Explicitly set mode to input RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN; //Enable EXT, TODO check if this is different across STM32 models - NVIC_EnableIRQ(getGPIOEXTICR(key).IRQN); //Enable IRQN for pin + NVIC_EnableIRQ(getGPIOEXTICR(m_GPIO_KEY).IRQN); //Enable IRQN for pin EXTI->IMR |= (1 << gpioPin); //Enable correct EXTI line - SHAL_EXTIO_Register EXTILineEnable = getGPIOEXTICR(key); + SHAL_EXTIO_Register EXTILineEnable = getGPIOEXTICR(m_GPIO_KEY); *EXTILineEnable.EXT_ICR |= EXTILineEnable.mask; //Set bits to enable correct port on correct line TODO Find way to clear bits before - uint32_t rising_mask = 0x00; uint32_t falling_mask = 0x00; //Set rising and falling edge triggers based on pin offset (enabled EXTI line) - switch(triggerMode){ + switch(mode){ case TriggerMode::RISING_EDGE: rising_mask = 1 << gpioPin; break; @@ -119,7 +102,20 @@ void GPIOManager::getInterruptGPIO(GPIO_Key key, TriggerMode triggerMode, EXTICa EXTI->FTSR |= falling_mask; //Set callback - registerEXTICallback(key,callback); + registerEXTICallback(m_GPIO_KEY,callback); __enable_irq(); //Enable IRQ just in case +} + + +GPIO& GPIOManager::get(GPIO_Key key) { + + unsigned int gpioPort = getGPIOPortNumber(key); + unsigned long gpioPin = getGPIORegister(key).global_offset; //Use existing structs to get offset + + if (m_gpios[gpioPort][gpioPin].m_GPIO_KEY == GPIO_Key::INVALID){ + m_gpios[gpioPort][gpioPin] = GPIO(key); + } + + return m_gpios[gpioPort][gpioPin]; } \ No newline at end of file diff --git a/SHAL/Src/Peripheral/UART/SHAL_UART.cpp b/SHAL/Src/Peripheral/UART/SHAL_UART.cpp index 990ff41..093d471 100644 --- a/SHAL/Src/Peripheral/UART/SHAL_UART.cpp +++ b/SHAL/Src/Peripheral/UART/SHAL_UART.cpp @@ -17,24 +17,11 @@ UART::UART(const UART_Pair pair) : m_UARTPair(pair){ GPIO_Key Tx_Key = uart_pair.TxKey; //Tx pin GPIO_Key Rx_Key = uart_pair.RxKey; //Rx pin - uint8_t Tx_Pin = getGPIORegister(Tx_Key).global_offset; - uint8_t Rx_Pin = getGPIORegister(Rx_Key).global_offset; + GET_GPIO(Tx_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); + GET_GPIO(Rx_Key).setPinMode(PinMode::ALTERNATE_FUNCTION_MODE); - initGPIO(Tx_Key,PinMode::ALTERNATE_FUNCTION_MODE); //Initialize Tx GPIO with alternate function (initializes GPIO port as well) - initGPIO(Rx_Key,PinMode::ALTERNATE_FUNCTION_MODE); //Initialize Rx GPIO with alternate function - - //Determine which AFR register (high or low) to write depending on pin - uint8_t TxAFR = Tx_Pin < 8 ? 0 : 1; //Use AFR[0] if pin < 8, AFR[1] if pin >= 8 - uint8_t RxAFR = Rx_Pin < 8 ? 0 : 1; - - /*Apply Alternate Function masks to the AFR registers for each GPIO to enable alternate functions - * The AFR register for GPIO_Typedef* is actually two registers - a low reg and high reg. - * The low reg handles pins 0-7, and the high reg handles 8-15. - * Each pin gets 4 bits in the register for AFR0 - AFR7. Hence 8 * 4 = 32 bits. - * Each AFR is a different function, look at the DATASHEET (not reference manual) to find these alternate function mappings - */ - getGPIORegister(Tx_Key).reg->AFR[TxAFR] |= getAFMask(uart_pair.TxMask) << (4 * (Tx_Pin % 8)); - getGPIORegister(Rx_Key).reg->AFR[RxAFR] |= getAFMask(uart_pair.RxMask) << (4 * (Rx_Pin % 8)); + GET_GPIO(Tx_Key).setAlternateFunction(uart_pair.TxAlternateFunctionMask); + GET_GPIO(Rx_Key).setAlternateFunction(uart_pair.RxAlternateFunctionMask); SHAL_UART_ENABLE_REG pairUARTEnable = getUARTEnableReg(pair); //Register and mask to enable the UART channel diff --git a/SHAL/Src/main.cpp b/SHAL/Src/main.cpp index 3cb0c19..2a19add 100644 --- a/SHAL/Src/main.cpp +++ b/SHAL/Src/main.cpp @@ -7,11 +7,12 @@ volatile GPIO* greenLED = nullptr; volatile UART* uart2; void c3Interrupt(){ - greenLED->toggle(); + PIN(A5).toggle(); + uart2->sendString("test"); } void tim2Handler(){ - blueLED->toggle(); + PIN(A4).toggle(); } int main() { @@ -20,12 +21,12 @@ int main() { uart2->begin(115200); - useGPIOAsInterrupt(GPIO_Key::C3,TriggerMode::RISING_EDGE, c3Interrupt); + PIN(C3).useAsExternalInterrupt(TriggerMode::RISING_EDGE,c3Interrupt); Timer timer2 = getTimer(Timer_Key::S_TIM2); - blueLED = &initGPIO(GPIO_Key::A4, PinMode::OUTPUT_MODE); - greenLED = &initGPIO(GPIO_Key::A5, PinMode::OUTPUT_MODE); + PIN(A4).setPinMode(PinMode::OUTPUT_MODE); + PIN(A5).setPinMode(PinMode::OUTPUT_MODE); timer2.setPrescaler(8000 - 1); timer2.setARR(1500 - 1);