diff --git a/Core/Src/Components/EXTIHandler_STM32.cpp b/Core/Src/Components/EXTIHandler_STM32.cpp index a367fdd..ec7a56d 100644 --- a/Core/Src/Components/EXTIHandler_STM32.cpp +++ b/Core/Src/Components/EXTIHandler_STM32.cpp @@ -7,9 +7,11 @@ #include "EXTIHandler_STM32.hpp" +/* void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ EXTIHandler_STM32::EXTI_Callback(GPIO_Pin); } +*/ EXTIHandler_STM32::EXTIHandler_STM32() { diff --git a/Core/Src/Components/ExampleInterruptibleClass.cpp b/Core/Src/Components/ExampleInterruptibleClass.cpp index 302bece..a6392bd 100644 --- a/Core/Src/Components/ExampleInterruptibleClass.cpp +++ b/Core/Src/Components/ExampleInterruptibleClass.cpp @@ -8,7 +8,7 @@ #include "ExampleInterruptibleClass.hpp" #include -ExampleInterruptibleClass::ExampleInterruptibleClass(GPIO_Pin_STM32* pin) : pin(pin) { +ExampleInterruptibleClass::ExampleInterruptibleClass(GPIO_Pin* pin) : pin(pin) { } @@ -18,10 +18,10 @@ ExampleInterruptibleClass::~ExampleInterruptibleClass() { int32_t ExampleInterruptibleClass::init(){ int32_t errors = 0; - errors += registerCallback(pin); + errors += pin->registerExtiCallback(this); return errors; } -void ExampleInterruptibleClass::irqHandler(void*parameter){ +void ExampleInterruptibleClass::irqHandler(InterruptReason* reason){ printf("Interrupted\n"); } diff --git a/Core/Src/Components/ExampleInterruptibleClass.hpp b/Core/Src/Components/ExampleInterruptibleClass.hpp index 82d28f0..b87655e 100644 --- a/Core/Src/Components/ExampleInterruptibleClass.hpp +++ b/Core/Src/Components/ExampleInterruptibleClass.hpp @@ -8,16 +8,17 @@ #ifndef SRC_COMPONENTS_EXAMPLEINTERRUPTIBLECLASS_HPP_ #define SRC_COMPONENTS_EXAMPLEINTERRUPTIBLECLASS_HPP_ -#include "EXTIHandler_STM32.hpp" +#include "Interruptible.hpp" +#include "GPIO_Pin.hpp" -class ExampleInterruptibleClass : protected EXTIHandler_STM32{ +class ExampleInterruptibleClass : protected Interruptible{ public: - ExampleInterruptibleClass(GPIO_Pin_STM32* pin); + ExampleInterruptibleClass(GPIO_Pin* pin); virtual ~ExampleInterruptibleClass(); int32_t init(); private: - void irqHandler(void*parameter); - GPIO_Pin_STM32* pin; + void irqHandler(InterruptReason* reason); + GPIO_Pin* pin; }; #endif /* SRC_COMPONENTS_EXAMPLEINTERRUPTIBLECLASS_HPP_ */ diff --git a/Core/Src/Components/GPIO_Pin.hpp b/Core/Src/Components/GPIO_Pin.hpp index 15d65b0..6f5aa79 100644 --- a/Core/Src/Components/GPIO_Pin.hpp +++ b/Core/Src/Components/GPIO_Pin.hpp @@ -9,8 +9,9 @@ #define SRC_COMPONENTS_GPIO_PIN_HPP_ #include +#include "Interruptible.hpp" -class GPIO_Pin { +class GPIO_Pin : public InterruptReason { public: virtual int32_t init() = 0; virtual int32_t read(uint8_t* state) = 0; @@ -18,6 +19,10 @@ public: virtual int32_t set() = 0; virtual int32_t reset() = 0; virtual int32_t toggle() = 0; + virtual int32_t registerExtiCallback(Interruptible* object) = 0; + virtual int32_t deregisterExtiCallback() = 0; +protected: + Interruptible* irqObject = nullptr; }; #endif /* SRC_COMPONENTS_GPIO_PIN_HPP_ */ diff --git a/Core/Src/Components/GPIO_Pin_STM32.cpp b/Core/Src/Components/GPIO_Pin_STM32.cpp index 08a321a..6ac361b 100644 --- a/Core/Src/Components/GPIO_Pin_STM32.cpp +++ b/Core/Src/Components/GPIO_Pin_STM32.cpp @@ -6,9 +6,14 @@ */ #include "GPIO_Pin_STM32.hpp" +#include -GPIO_Pin_STM32::GPIO_Pin_STM32(GPIO_TypeDef *gpio_port, uint16_t gpio_pin) : - gpio_port(gpio_port), gpio_pin(gpio_pin){ +void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin){ + GPIO_Pin_STM32::extiDispatch(GPIO_Pin); +} + +GPIO_Pin_STM32::GPIO_Pin_STM32(GPIO_TypeDef *gpio_port, uint16_t gpio_pin) : gpio_port(gpio_port), gpio_pin(gpio_pin) { + pinNumber = gpioPinToPinNumber(gpio_pin); } GPIO_Pin_STM32::~GPIO_Pin_STM32() { @@ -51,3 +56,73 @@ GPIO_TypeDef* GPIO_Pin_STM32::getPort() { uint16_t GPIO_Pin_STM32::getPin() { return gpio_pin; } + +void GPIO_Pin_STM32::extiDispatch(uint16_t GPIO_Pin){ + // TODO Protect array with mutex + GPIO_Pin_STM32* object = pinObjects[gpioPinToPinNumber(GPIO_Pin)]; + if(!object){ + printf("EXTI called for uninitialized GPIO_Pin_STM32 %u", gpioPinToPinNumber(GPIO_Pin)); + return; + } + if(!object->irqObject){ + printf("EXTI called for GPIO_Pin_STM32 %u without callback registered", object->pinNumber); + return; + } + object->irqObject->irqHandler(object); +} + +int32_t GPIO_Pin_STM32::registerExtiCallback(Interruptible* object){ + if(pinObjects[pinNumber] || irqObject){ + // Already registered + return -1; + } + pinObjects[pinNumber] = this; + irqObject = object; + return 0; +} + +int32_t GPIO_Pin_STM32::deregisterExtiCallback(){ + pinObjects[pinNumber] = nullptr; + irqObject = nullptr; + return 0; +} + +int8_t GPIO_Pin_STM32::gpioPinToPinNumber(uint16_t GPIO_Pin) { + assert_param(IS_GPIO_PIN(GPIO_Pin)); + switch(GPIO_Pin){ + case GPIO_PIN_0: + return 0; + case GPIO_PIN_1: + return 1; + case GPIO_PIN_2: + return 2; + case GPIO_PIN_3: + return 3; + case GPIO_PIN_4: + return 4; + case GPIO_PIN_5: + return 5; + case GPIO_PIN_6: + return 6; + case GPIO_PIN_7: + return 7; + case GPIO_PIN_8: + return 8; + case GPIO_PIN_9: + return 9; + case GPIO_PIN_10: + return 10; + case GPIO_PIN_11: + return 11; + case GPIO_PIN_12: + return 12; + case GPIO_PIN_13: + return 13; + case GPIO_PIN_14: + return 14; + case GPIO_PIN_15: + return 15; + } + // TODO implement error handling here + return -1; +} diff --git a/Core/Src/Components/GPIO_Pin_STM32.hpp b/Core/Src/Components/GPIO_Pin_STM32.hpp index 155bf45..92d9813 100644 --- a/Core/Src/Components/GPIO_Pin_STM32.hpp +++ b/Core/Src/Components/GPIO_Pin_STM32.hpp @@ -15,17 +15,23 @@ class GPIO_Pin_STM32 : public GPIO_Pin { public: GPIO_Pin_STM32(GPIO_TypeDef* gpio_port, uint16_t gpio_pin); virtual ~GPIO_Pin_STM32(); + static void extiDispatch(uint16_t GPIO_Pin); int32_t init(); int32_t read(uint8_t* state); int32_t write(uint8_t state); int32_t set(); int32_t reset(); int32_t toggle(); + int32_t registerExtiCallback(Interruptible* object); + int32_t deregisterExtiCallback(); GPIO_TypeDef* getPort(); uint16_t getPin(); private: + static int8_t gpioPinToPinNumber(uint16_t GPIO_Pin); + static inline GPIO_Pin_STM32* pinObjects[16]; GPIO_TypeDef* gpio_port; uint16_t gpio_pin; + int8_t pinNumber = -1; }; #endif /* SRC_COMPONENTS_GPIO_PIN_STM32_HPP_ */ diff --git a/Core/Src/Components/InterruptReason.hpp b/Core/Src/Components/InterruptReason.hpp new file mode 100644 index 0000000..1ce38d5 --- /dev/null +++ b/Core/Src/Components/InterruptReason.hpp @@ -0,0 +1,15 @@ +/* + * InterruptReason.hpp + * + * Created on: Apr 20, 2024 + * Author: Gabriel + */ + +#ifndef SRC_COMPONENTS_INTERRUPTREASON_HPP_ +#define SRC_COMPONENTS_INTERRUPTREASON_HPP_ + +class InterruptReason { + +}; + +#endif /* SRC_COMPONENTS_INTERRUPTREASON_HPP_ */ diff --git a/Core/Src/Components/Interruptible.hpp b/Core/Src/Components/Interruptible.hpp new file mode 100644 index 0000000..cf6a096 --- /dev/null +++ b/Core/Src/Components/Interruptible.hpp @@ -0,0 +1,18 @@ +/* + * Interruptible.hpp + * + * Created on: Apr 20, 2024 + * Author: Gabriel + */ + +#ifndef SRC_COMPONENTS_INTERRUPTIBLE_HPP_ +#define SRC_COMPONENTS_INTERRUPTIBLE_HPP_ + +#include "InterruptReason.hpp" + +class Interruptible { +public: + virtual void irqHandler(InterruptReason* reason) = 0; +}; + +#endif /* SRC_COMPONENTS_INTERRUPTIBLE_HPP_ */