LibreVNA/Software/VNA_embedded/Application/Drivers/Exti.cpp

139 lines
2.7 KiB
C++

#include "Exti.hpp"
using Entry = struct {
GPIO_TypeDef *gpio;
Exti::Callback cb;
void *ptr;
};
static constexpr uint8_t MaxEntries = 16;
static Entry entries[MaxEntries];
void Exti::Init() {
HAL_NVIC_SetPriority(EXTI0_IRQn, 1, 0);
HAL_NVIC_SetPriority(EXTI1_IRQn, 1, 0);
HAL_NVIC_SetPriority(EXTI2_IRQn, 1, 0);
HAL_NVIC_SetPriority(EXTI3_IRQn, 1, 0);
HAL_NVIC_SetPriority(EXTI4_IRQn, 1, 0);
HAL_NVIC_SetPriority(EXTI9_5_IRQn, 1, 0);
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(EXTI0_IRQn);
HAL_NVIC_EnableIRQ(EXTI1_IRQn);
HAL_NVIC_EnableIRQ(EXTI2_IRQn);
HAL_NVIC_EnableIRQ(EXTI3_IRQn);
HAL_NVIC_EnableIRQ(EXTI4_IRQn);
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
for (uint8_t i = 0; i < MaxEntries; i++) {
entries[i].gpio = NULL;
entries[i].cb = NULL;
entries[i].ptr = NULL;
}
}
bool Exti::SetCallback(GPIO_TypeDef *gpio, uint16_t pin, EdgeType edge,
Pull pull, Callback cb, void *ptr) {
uint8_t index = 31 - __builtin_clz(pin);
if (entries[index].gpio && entries[index].gpio != gpio) {
return false;
}
GPIO_InitTypeDef g;
g.Pin = pin;
switch (edge) {
case EdgeType::Falling:
g.Mode = GPIO_MODE_IT_FALLING;
break;
case EdgeType::Rising:
g.Mode = GPIO_MODE_IT_RISING;
break;
case EdgeType::Both:
g.Mode = GPIO_MODE_IT_RISING_FALLING;
break;
}
switch (pull) {
case Pull::None:
g.Pull = GPIO_NOPULL;
break;
case Pull::Up:
g.Pull = GPIO_PULLUP;
break;
case Pull::Down:
g.Pull = GPIO_PULLDOWN;
break;
}
HAL_GPIO_Init(gpio, &g);
entries[index].gpio = gpio;
entries[index].cb = cb;
entries[index].ptr = ptr;
return true;
}
bool Exti::ClearCallback(GPIO_TypeDef *gpio, uint16_t pin) {
uint8_t index = 31 - __builtin_clz(pin);
if (entries[index].gpio) {
if (gpio != entries[index].gpio) {
return false;
}
}
entries[index].gpio = NULL;
entries[index].cb = NULL;
entries[index].ptr = NULL;
return true;
}
static inline void ExtiHandler(uint16_t source) {
const uint32_t mask = 1 << source;
if (__HAL_GPIO_EXTI_GET_IT(mask) != RESET) {
__HAL_GPIO_EXTI_CLEAR_IT(mask);
if (entries[source].cb) {
entries[source].cb(entries[source].ptr);
}
}
}
extern "C" {
void EXTI0_IRQHandler(void) {
ExtiHandler(0);
}
void EXTI1_IRQHandler(void) {
ExtiHandler(1);
}
void EXTI2_IRQHandler(void) {
ExtiHandler(2);
}
void EXTI3_IRQHandler(void) {
ExtiHandler(3);
}
void EXTI4_IRQHandler(void) {
ExtiHandler(4);
}
void EXTI9_5_IRQHandler(void) {
ExtiHandler(5);
ExtiHandler(6);
ExtiHandler(7);
ExtiHandler(8);
ExtiHandler(9);
}
void EXTI15_10_IRQHandler(void) {
ExtiHandler(10);
ExtiHandler(11);
ExtiHandler(12);
ExtiHandler(13);
ExtiHandler(14);
ExtiHandler(15);
}
}