Skip to content

Commit 0482ac4

Browse files
committed
feat: add exti drivers
1 parent 388827c commit 0482ac4

6 files changed

Lines changed: 194 additions & 71 deletions

File tree

src/fw/board/board_sf32lb.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,8 @@ enum {
7272
IRQ_MAP(DMA##cnum##_Stream##snum, dma_stream_irq_handler, &DMA##cnum##_STREAM##snum##_DEVICE)
7373

7474
typedef struct {
75-
//! One of EXTI_PortSourceGPIOX
76-
uint8_t exti_port_source;
77-
78-
//! Value between 0-15
79-
uint8_t exti_line;
75+
GPIO_TypeDef* const peripheral; ///< One of GPIOX. For example, GPIOA.
76+
const uint32_t gpio_pin; ///< One of GPIO_Pin_X.
8077
} ExtiConfig;
8178

8279
typedef enum {

src/fw/drivers/exti.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ void exti_configure_pin(ExtiConfig cfg, ExtiTrigger trigger, ExtiHandlerCallback
4242
//! Configures the given EXTI and NVIC for the given configuration.
4343
void exti_configure_other(ExtiLineOther exti_line, ExtiTrigger trigger);
4444

45-
#ifndef MICRO_FAMILY_NRF5
45+
#if !defined(MICRO_FAMILY_NRF5) && !defined(MICRO_FAMILY_SF32LB)
4646
static inline void exti_enable(ExtiConfig config);
4747
static inline void exti_disable(ExtiConfig config);
4848
#else

src/fw/drivers/exti.inl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
//!
1919
//! Helper functions intended to be inlined into the calling code.
2020

21-
#ifndef MICRO_FAMILY_NRF5
21+
#if !defined(MICRO_FAMILY_NRF5) && !defined(MICRO_FAMILY_SF32LB)
2222
static inline void exti_enable(ExtiConfig config) {
2323
exti_enable_other(config.exti_line);
2424
}

src/fw/drivers/sf32lb/exti.c

Lines changed: 189 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,189 @@
1+
#include "drivers/exti.h"
2+
3+
#include "board/board.h"
4+
#include "drivers/periph_config.h"
5+
#include "kernel/events.h"
6+
#include "mcu/interrupts.h"
7+
#include "system/passert.h"
8+
9+
#include <stdbool.h>
10+
11+
#define EXTI_MAX_GPIO1_PIN_NUM 8
12+
#define EXTI_MAX_GPIO2_PIN_NUM 1
13+
14+
typedef struct {
15+
uint32_t gpio_pin;
16+
ExtiHandlerCallback callback;
17+
} ExtiHandlerConfig_t;
18+
19+
static ExtiHandlerConfig_t exti_gpio1_handler_configs[EXTI_MAX_GPIO1_PIN_NUM] = {0};
20+
static ExtiHandlerConfig_t exti_gpio2_handler_configs[EXTI_MAX_GPIO2_PIN_NUM] = {0};
21+
22+
static GPIO_TypeDef *prv_gpio_get_instance(GPIO_TypeDef *hgpio, uint16_t gpio_pin, uint16_t *offset)
23+
{
24+
uint16_t max_num;
25+
uint16_t inst_idx;
26+
GPIO_TypeDef *gpiox;
27+
28+
if ((GPIO_TypeDef *)hwp_gpio1 == hgpio)
29+
{
30+
max_num = GPIO1_PIN_NUM;
31+
}
32+
else
33+
{
34+
max_num = GPIO2_PIN_NUM;
35+
}
36+
37+
HAL_ASSERT(gpio_pin < max_num);
38+
39+
if (gpio_pin >= max_num)
40+
{
41+
return (GPIO_TypeDef *)NULL;
42+
}
43+
44+
inst_idx = gpio_pin >> 5;
45+
*offset = gpio_pin & 31;
46+
47+
gpiox = (GPIO_TypeDef *)hgpio + inst_idx;
48+
49+
return gpiox;
50+
}
51+
52+
static void prv_insert_handler(GPIO_TypeDef *hgpio, uint8_t gpio_pin,ExtiHandlerCallback cb) {
53+
// Find the handler index for this pin
54+
uint8_t index = 0;
55+
while (index < (hgpio == hwp_gpio1 ? EXTI_MAX_GPIO1_PIN_NUM : EXTI_MAX_GPIO2_PIN_NUM) &&
56+
exti_gpio1_handler_configs[index].callback != NULL) {
57+
index++;
58+
}
59+
if (index >= (hgpio == hwp_gpio1 ? EXTI_MAX_GPIO1_PIN_NUM : EXTI_MAX_GPIO2_PIN_NUM)) {
60+
// No available slot
61+
return;
62+
}
63+
// Store the callback and index
64+
exti_gpio1_handler_configs[index].gpio_pin = gpio_pin;
65+
exti_gpio1_handler_configs[index].callback = cb;
66+
}
67+
68+
static void prv_delete_handler(GPIO_TypeDef *hgpio, uint8_t gpio_pin) {
69+
// Find the handler index for this pin
70+
uint8_t index = 0;
71+
while (index < (hgpio == hwp_gpio1 ? EXTI_MAX_GPIO1_PIN_NUM : EXTI_MAX_GPIO2_PIN_NUM) &&
72+
exti_gpio1_handler_configs[index].callback != NULL &&
73+
exti_gpio1_handler_configs[index].gpio_pin != gpio_pin) {
74+
index++;
75+
}
76+
if (index >= (hgpio == hwp_gpio1 ? EXTI_MAX_GPIO1_PIN_NUM : EXTI_MAX_GPIO2_PIN_NUM)) {
77+
// Handler not found
78+
return;
79+
}
80+
// Clear the callback and index
81+
exti_gpio1_handler_configs[index].callback = NULL;
82+
exti_gpio1_handler_configs[index].gpio_pin = 0;
83+
}
84+
85+
void exti_configure_pin(ExtiConfig cfg, ExtiTrigger trigger, ExtiHandlerCallback cb) {
86+
prv_insert_handler(cfg.peripheral, cfg.gpio_pin, cb);
87+
88+
uint16_t offset;
89+
GPIO_TypeDef *gpiox = prv_gpio_get_instance(cfg.peripheral, cfg.gpio_pin, &offset);
90+
91+
switch (trigger) {
92+
case ExtiTrigger_Rising:
93+
gpiox->ITSR |= (1UL << offset);
94+
gpiox->IPHSR = (1UL << offset);
95+
gpiox->IPLCR = (1UL << offset);
96+
break;
97+
case ExtiTrigger_Falling:
98+
gpiox->ITSR |= (1UL << offset);
99+
gpiox->IPHCR = (1UL << offset);
100+
gpiox->IPLSR = (1UL << offset);
101+
break;
102+
case ExtiTrigger_RisingFalling:
103+
gpiox->ITSR |= (1UL << offset);
104+
gpiox->IPHSR = (1UL << offset);
105+
gpiox->IPLSR = (1UL << offset);
106+
break;
107+
}
108+
}
109+
110+
void exti_enable(ExtiConfig cfg) {
111+
uint16_t offset;
112+
GPIO_TypeDef *gpiox = prv_gpio_get_instance(cfg.peripheral, cfg.gpio_pin, &offset);
113+
if (cfg.peripheral == hwp_gpio1) {
114+
// Enable the EXTI line for GPIO1
115+
gpiox->IESR |= (1 << offset);
116+
} else {
117+
gpiox->IESR_EXT |= (1 << offset);
118+
}
119+
120+
HAL_NVIC_SetPriority(GPIO1_IRQn, 2, 1); // Configure NVIC priority
121+
HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_2);
122+
HAL_NVIC_EnableIRQ(GPIO1_IRQn);
123+
}
124+
125+
void exti_disable(ExtiConfig cfg) {
126+
uint16_t offset;
127+
GPIO_TypeDef *gpiox = prv_gpio_get_instance(cfg.peripheral, cfg.gpio_pin, &offset);
128+
if (cfg.peripheral == hwp_gpio1) {
129+
// Disable the EXTI line for GPIO1
130+
gpiox->IECR |= (1 << offset);
131+
} else {
132+
gpiox->IECR_EXT |= (1 << offset);
133+
}
134+
}
135+
136+
void HAL_GPIO_EXTI_Callback(GPIO_TypeDef *hgpio, uint16_t GPIO_Pin)
137+
{
138+
int index = 0;
139+
ExtiHandlerCallback cb = NULL;
140+
if (hgpio == hwp_gpio1) {
141+
while (index < EXTI_MAX_GPIO1_PIN_NUM &&
142+
exti_gpio1_handler_configs[index].callback != NULL) {
143+
if (exti_gpio1_handler_configs[index].gpio_pin == GPIO_Pin) {
144+
cb = exti_gpio1_handler_configs[index].callback;
145+
break;
146+
}
147+
index++;
148+
}
149+
}
150+
151+
if (cb != NULL) {
152+
bool should_context_switch = false;
153+
cb(&should_context_switch);
154+
if (should_context_switch) {
155+
portEND_SWITCHING_ISR(should_context_switch);
156+
}
157+
}
158+
}
159+
160+
void GPIO1_IRQHandler(void)
161+
{
162+
HAL_GPIO_IRQHandler(hwp_gpio1);
163+
}
164+
165+
void GPIO2_IRQHandler(void) // Define the interrupt siervice routine (ISR) according to the interrupt vector table
166+
{
167+
HAL_GPIO_IRQHandler(hwp_gpio2);
168+
}
169+
170+
void exti_configure_other(ExtiLineOther exti_line, ExtiTrigger trigger) {
171+
172+
}
173+
174+
void exti_enable_other(ExtiLineOther exti_line) {
175+
176+
}
177+
178+
void exti_disable_other(ExtiLineOther exti_line) {
179+
180+
}
181+
182+
void exti_set_pending(ExtiConfig cfg) {
183+
184+
}
185+
186+
void exti_clear_pending_other(ExtiLineOther exti_line) {
187+
188+
}
189+

src/fw/drivers/sf32lb/stubs/exti.c

Lines changed: 0 additions & 63 deletions
This file was deleted.

src/fw/drivers/wscript_build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1720,7 +1720,7 @@ if mcu_family == 'SF32LB':
17201720
#'nrf5/qspi.c',
17211721
'sf32lb/stubs/button.c',
17221722
'sf32lb/stubs/debounced_button.c',
1723-
'sf32lb/stubs/exti.c',
1723+
'sf32lb/exti.c',
17241724
'sf32lb/stubs/qspi.c',
17251725
'sf32lb/uart.c',
17261726
#'nrf5/gpio.c',

0 commit comments

Comments
 (0)