From 8b4402e4c8bdf3d0637867ad933005b9e28c7b74 Mon Sep 17 00:00:00 2001 From: Luca Date: Fri, 5 Sep 2025 21:21:35 -0700 Subject: [PATCH] Begin functionality for EXTI callbacks --- CMakeLists.txt | 1 + .../Peripheral/EXT/SHAL_EXTI_CALLBACK.h | 41 +++++++++++++++++++ .../GPIO/Reg/SHAL_GPIO_REG_F072xB.h | 1 + SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h | 26 +++++++++++- SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp | 19 ++++++++- SHAL/Src/Peripheral/SHAL_EXTI_CALLBACK.cpp | 35 ++++++++++++++++ 6 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 SHAL/Include/Peripheral/EXT/SHAL_EXTI_CALLBACK.h create mode 100644 SHAL/Src/Peripheral/SHAL_EXTI_CALLBACK.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8326571..8d78d5e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,6 +34,7 @@ set(PROJECT_INCLUDE_DIRECTORIES SHAL/Include/Peripheral/Timer/Reg SHAL/Include/Peripheral/GPIO SHAL/Include/Peripheral/GPIO/Reg + SHAL/Include/Peripheral/EXT/ ${CMAKE_CURRENT_SOURCE_DIR}/SHAL/Include ) diff --git a/SHAL/Include/Peripheral/EXT/SHAL_EXTI_CALLBACK.h b/SHAL/Include/Peripheral/EXT/SHAL_EXTI_CALLBACK.h new file mode 100644 index 0000000..bfbda11 --- /dev/null +++ b/SHAL/Include/Peripheral/EXT/SHAL_EXTI_CALLBACK.h @@ -0,0 +1,41 @@ +/** + ****************************************************************************** + * @file SHAL_TIM.h + * @author Luca Lizaranzu + * @brief Callbacks for external interrupts + ****************************************************************************** + */ + +#ifndef SHMINGO_HAL_SHAL_EXTI_CALLBACK_H +#define SHMINGO_HAL_SHAL_EXTI_CALLBACK_H + +#include "SHAL_CORE.h" +#include "SHAL_GPIO_REG_F072xB.h" + +#define DEFINE_EXTI_IRQ(EXTI_Channel) \ +extern "C" void EXTI##EXTI_Channel##_IRQHandler(void) { \ + if (EXTI->PR & (1 << EXTI_Channel)) { \ + EXTI->PR |= (1 << EXTI_Channel); /*clear flag */ \ + auto cb = EXTI_callbacks[EXTI_Channel]; \ + if (cb) cb(); \ + }; \ +}; + +#define DEFINE_MULTI_EXTI_IRQ(EXTI_Channel_Min, EXTI_Channel_Max) \ +extern "C" void EXTI##EXTI_Channel_Max##_##EXTI_Channel_Min##_IRQHandler(void) { \ + for(uint8_t line = EXTI_Channel_Min; line <= EXTI_Channel_Max; line++){ \ + if (EXTI->PR & (1 << line)) { \ + EXTI->PR |= (1 << line); /*clear flag */ \ + auto cb = EXTI_callbacks[line]; \ + if (cb) cb(); \ + }; \ + } \ +}; + +typedef void (*EXTICallback)(); //Typedef for callback function + +[[maybe_unused]] static EXTICallback EXTI_callbacks[NUM_EXTI_LINES] = {nullptr}; //Timer IRQ Callback table + +void registerEXTICallback(GPIO_Key key, EXTICallback callback); + +#endif //SHMINGO_HAL_SHAL_EXTI_CALLBACK_H diff --git a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h index e344505..9b237f8 100644 --- a/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h +++ b/SHAL/Include/Peripheral/GPIO/Reg/SHAL_GPIO_REG_F072xB.h @@ -12,6 +12,7 @@ #define AVAILABLE_PORTS 3 #define PINS_PER_PORT 16 +#define NUM_EXTI_LINES 16 #define AVAILABLE_GPIO \ X(A0) X(A1) X(A2) X(A3) X(A4) X(A5) X(A6) X(A7) X(A8) X(A9) X(A10) X(A11) X(A12) X(A13) X(A14) X(A15) \ diff --git a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h index bd017d8..44f4ed8 100644 --- a/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h +++ b/SHAL/Include/Peripheral/GPIO/SHAL_GPIO.h @@ -9,6 +9,9 @@ #include #include "SHAL_GPIO_REG_F072xB.h" +#include "SHAL_EXTI_CALLBACK.h" + + enum class PinMode : uint8_t{ INPUT_MODE, @@ -17,9 +20,21 @@ enum class PinMode : uint8_t{ ANALOG_MODE, INVALID }; - unsigned long getPinMode(PinMode mode); +enum class TriggerMode : uint8_t{ + RISING_EDGE, + FALLING_EDGE, + RISING_FALLING_EDGE +}; + +unsigned long getTriggerMode(TriggerMode mode); + + + + + + //Abstraction of GPIO registers class GPIO{ @@ -42,15 +57,21 @@ private: }; - +//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) + //Manages instances of GPIO objects class GPIOManager{ public: static GPIO& get(GPIO_Key, PinMode pinMode); + + static void getInterruptGPIO(GPIO_Key key, TriggerMode mode, EXTICallback callback); + GPIOManager() = delete; private: @@ -59,4 +80,5 @@ inline static GPIO m_gpios[AVAILABLE_PORTS][PINS_PER_PORT] = {{}}; }; + #endif //SHMINGO_HAL_SHAL_GPIO_H diff --git a/SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp b/SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp index 2652f62..e8615c9 100644 --- a/SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp +++ b/SHAL/Src/Peripheral/GPIO/SHAL_GPIO.cpp @@ -72,4 +72,21 @@ GPIO& GPIOManager::get(GPIO_Key key, PinMode pinMode) { } return m_gpios[gpioPort][gpioPin]; -} \ No newline at end of file +} + +void GPIOManager::getInterruptGPIO(GPIO_Key key, TriggerMode mode, EXTICallback callback) { + 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::INPUT_MODE); //Hardcode input mode for interrupt + } + + RCC->APB2ENR |= RCC_APB2ENR_SYSCFGCOMPEN; //TODO check if this is different across STM32 models, enable EXT + + SHAL_EXTIO_Register EXTILineEnable = getGPIOEXTICR(key); + + *EXTILineEnable.EXT_ICR |= EXTILineEnable.mask; //Set bits to enable correct port on correct line + + +} diff --git a/SHAL/Src/Peripheral/SHAL_EXTI_CALLBACK.cpp b/SHAL/Src/Peripheral/SHAL_EXTI_CALLBACK.cpp new file mode 100644 index 0000000..b8676ea --- /dev/null +++ b/SHAL/Src/Peripheral/SHAL_EXTI_CALLBACK.cpp @@ -0,0 +1,35 @@ +// +// Created by Luca on 9/3/2025. +// + +#include "SHAL_EXTI_CALLBACK.h" + +#if defined(STM32F030x6) +#elif defined(STM32F030x8) +#elif defined(STM32F031x6) +#elif defined(STM32F038xx) +#elif defined(STM32F042x6) +#elif defined(STM32F048xx) +#elif defined(STM32F051x8) +#elif defined(STM32F058xx) +#elif defined(STM32F070x6) +#elif defined(STM32F070xB) +#elif defined(STM32F071xB) +#elif defined(STM32F072xB) + +DEFINE_MULTI_EXTI_IRQ(0,1); +DEFINE_MULTI_EXTI_IRQ(2,3); +DEFINE_MULTI_EXTI_IRQ(4,15); + +#elif defined(STM32F078xx) +#include "stm32f078xx.h" +#elif defined(STM32F091xC) + #include "stm32f091xc.h" +#elif defined(STM32F098xx) + #include "stm32f098xx.h" +#elif defined(STM32F030xC) + #include "stm32f030xc.h" +#else + #error "Please select first the target STM32F0xx device used in your application (in stm32f0xx.h file)" +#endif +