Merge pull request #1877 from openmv/gpio_hal_refactor

ports/stm32: Share GPIO IRQ descriptor with other ports.
This commit is contained in:
Ibrahim Abdelkader 2023-06-27 19:09:46 +03:00 committed by GitHub
commit e6572097b1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 50 additions and 45 deletions

View File

@ -53,7 +53,7 @@ void nm_bsp_sleep(uint32 u32TimeMsec) {
mp_hal_delay_ms(u32TimeMsec); mp_hal_delay_ms(u32TimeMsec);
} }
static void nm_bsp_extint_callback(omv_gpio_t pin, void *data) { static void nm_bsp_extint_callback(void *data) {
if (gpfIsr) { if (gpfIsr) {
gpfIsr(); gpfIsr();
} }

@ -1 +1 @@
Subproject commit 69975b0c4b8fc078f43122bc977628b2d1edefd7 Subproject commit 832393b522acfaca4ccc60a8ee200087aa6ca345

View File

@ -17,7 +17,17 @@
// Config options are defined in ports so they can be used // Config options are defined in ports so they can be used
// directly to initialize peripherals without remapping them. // directly to initialize peripherals without remapping them.
typedef void (*omv_gpio_callback_t)(omv_gpio_t pin, void *data); typedef void (*omv_gpio_callback_t)(void *data);
typedef struct _omv_gpio_irq_descr {
bool enabled;
void *data;
omv_gpio_callback_t callback;
#ifdef OMV_GPIO_IRQ_DESCR_PORT_BITS
// Additional port-specific fields used internally.
OMV_GPIO_IRQ_DESCR_PORT_BITS
#endif
} omv_gpio_irq_descr_t;
void omv_gpio_init0(void); void omv_gpio_init0(void);
void omv_gpio_config(omv_gpio_t pin, uint32_t mode, uint32_t pull, uint32_t speed, uint32_t af); void omv_gpio_config(omv_gpio_t pin, uint32_t mode, uint32_t pull, uint32_t speed, uint32_t af);

View File

@ -201,7 +201,7 @@ static void fir_lepton_spi_callback_full(SPI_HandleTypeDef *hspi)
#if defined(OMV_FIR_LEPTON_VSYNC_PIN) #if defined(OMV_FIR_LEPTON_VSYNC_PIN)
static mp_obj_t fir_lepton_vsync_cb = NULL; static mp_obj_t fir_lepton_vsync_cb = NULL;
static void fir_lepton_extint_callback(omv_gpio_t pin, void *data) static void fir_lepton_extint_callback(void *data)
{ {
if (fir_lepton_vsync_cb) { if (fir_lepton_vsync_cb) {
mp_call_function_0(fir_lepton_vsync_cb); mp_call_function_0(fir_lepton_vsync_cb);

View File

@ -1220,7 +1220,7 @@ static mp_obj_t ltdc_dvi_get_display_id_data()
} }
#endif // OMV_DDC_PRESENT #endif // OMV_DDC_PRESENT
static void ltdc_dvi_extint_callback(omv_gpio_t pin, void *data) static void ltdc_dvi_extint_callback(void *data)
{ {
if (ltdc_dvi_user_cb) { if (ltdc_dvi_user_cb) {
mp_call_function_1(ltdc_dvi_user_cb, ltdc_dvi_get_display_connected()); mp_call_function_1(ltdc_dvi_user_cb, ltdc_dvi_get_display_connected());

View File

@ -524,7 +524,7 @@ mp_obj_t lcd_cec_receive_frame(uint n_args, const mp_obj_t *args, mp_map_t *kw_a
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Expected destination address!")); mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Expected destination address!"));
} }
static void lcd_cec_extint_callback(omv_gpio_t pin, void *data) static void lcd_cec_extint_callback(void *data)
{ {
if (lcd_cec_user_cb && lcd_cec_receive_frame_int(lcd_cec_dst_addr, false)) { if (lcd_cec_user_cb && lcd_cec_receive_frame_int(lcd_cec_dst_addr, false)) {
mp_call_function_0(lcd_cec_user_cb); mp_call_function_0(lcd_cec_user_cb);

View File

@ -132,7 +132,7 @@ mp_obj_t lcd_touch_update_touch_points()
mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to update the number of touch points!")); mp_raise_msg(&mp_type_OSError, MP_ERROR_TEXT("Failed to update the number of touch points!"));
} }
static void lcd_touch_extint_callback(omv_gpio_t pin, void *data) static void lcd_touch_extint_callback(void *data)
{ {
if (lcd_touch_user_cb) { if (lcd_touch_user_cb) {
mp_call_function_1(lcd_touch_user_cb, lcd_touch_update_touch_points()); mp_call_function_1(lcd_touch_user_cb, lcd_touch_update_touch_points());

View File

@ -19,34 +19,25 @@
#include "omv_boardconfig.h" #include "omv_boardconfig.h"
#include "omv_gpio.h" #include "omv_gpio.h"
typedef struct _omv_exti_descr { static omv_gpio_irq_descr_t gpio_irq_descr_table[16] = {{0}};
bool enabled;
uint32_t gpio;
uint32_t irqn;
omv_gpio_t pin;
void *data;
omv_gpio_callback_t callback;
} omv_exti_descr_t;
static omv_exti_descr_t exti_descr_table[16] = {{0}};
// Returns the port number configured in EXTI_CR for this line. // Returns the port number configured in EXTI_CR for this line.
static uint32_t omv_exti_get_gpio(uint32_t line) static uint32_t omv_gpio_irq_get_gpio(uint32_t line)
{ {
return (SYSCFG->EXTICR[line >> 2] >> (4 * (line & 3))) & 0x0F; return (SYSCFG->EXTICR[line >> 2] >> (4 * (line & 3))) & 0x0F;
} }
// Returns pin number. // Returns pin number.
static uint32_t omv_exti_get_line(omv_gpio_t pin) static uint32_t omv_gpio_irq_get_line(omv_gpio_t pin)
{ {
return 31 - __CLZ(pin->pin); return 31 - __CLZ(pin->pin);
} }
// Returns the IRQ number of a an EXTI line. // Returns the IRQ number of a an EXTI line.
static uint32_t omv_exti_get_irqn(omv_gpio_t pin) static uint32_t omv_gpio_irq_get_irqn(omv_gpio_t pin)
{ {
uint32_t exti_irqn = 0; uint32_t exti_irqn = 0;
uint32_t exti_line = omv_exti_get_line(pin); uint32_t exti_line = omv_gpio_irq_get_line(pin);
switch (exti_line) { switch (exti_line) {
case 0: case 0:
@ -76,32 +67,32 @@ static uint32_t omv_exti_get_irqn(omv_gpio_t pin)
return exti_irqn; return exti_irqn;
} }
static inline bool omv_exti_enabled(omv_exti_descr_t *exti_descr, uint32_t line) static inline bool omv_gpio_irq_enabled(omv_gpio_irq_descr_t *gpio_irq_descr, uint32_t line)
{ {
return (exti_descr->enabled && return (gpio_irq_descr->enabled &&
exti_descr->callback && gpio_irq_descr->callback &&
exti_descr->gpio == omv_exti_get_gpio(line)); gpio_irq_descr->gpio == omv_gpio_irq_get_gpio(line));
} }
void omv_exti_handler(uint32_t line) void omv_gpio_irq_handler(uint32_t line)
{ {
if (line < 5) { if (line < 5) {
// EXTI lines 0 to 4 have single IRQs. // EXTI lines 0 to 4 have single IRQs.
omv_exti_descr_t *exti_descr = &exti_descr_table[line]; omv_gpio_irq_descr_t *gpio_irq_descr = &gpio_irq_descr_table[line];
if (omv_exti_enabled(exti_descr, line)) { if (omv_gpio_irq_enabled(gpio_irq_descr, line)) {
__HAL_GPIO_EXTI_CLEAR_FLAG(1 << line); __HAL_GPIO_EXTI_CLEAR_FLAG(1 << line);
exti_descr->callback(exti_descr->pin, exti_descr->data); gpio_irq_descr->callback(gpio_irq_descr->data);
} }
} else { } else {
size_t line_max = (line == 5) ? 10 : 16; size_t line_max = (line == 5) ? 10 : 16;
// EXTI lines 5 to 9 and 10 to 15 are multiplexed. // EXTI lines 5 to 9 and 10 to 15 are multiplexed.
for (size_t i = line; i < line_max; i++) { for (size_t i = line; i < line_max; i++) {
omv_exti_descr_t *exti_descr = &exti_descr_table[i]; omv_gpio_irq_descr_t *gpio_irq_descr = &gpio_irq_descr_table[i];
if (__HAL_GPIO_EXTI_GET_FLAG(1 << i) if (__HAL_GPIO_EXTI_GET_FLAG(1 << i)
&& omv_exti_enabled(exti_descr, i)) { && omv_gpio_irq_enabled(gpio_irq_descr, i)) {
__HAL_GPIO_EXTI_CLEAR_FLAG(1 << i); __HAL_GPIO_EXTI_CLEAR_FLAG(1 << i);
exti_descr->callback(exti_descr->pin, exti_descr->data); gpio_irq_descr->callback(gpio_irq_descr->data);
} }
} }
} }
@ -109,7 +100,7 @@ void omv_exti_handler(uint32_t line)
void omv_gpio_init0(void) void omv_gpio_init0(void)
{ {
memset(exti_descr_table, 0, sizeof(exti_descr_table)); memset(gpio_irq_descr_table, 0, sizeof(gpio_irq_descr_table));
} }
void omv_gpio_config(omv_gpio_t pin, uint32_t mode, uint32_t pull, uint32_t speed, uint32_t af) void omv_gpio_config(omv_gpio_t pin, uint32_t mode, uint32_t pull, uint32_t speed, uint32_t af)
@ -141,23 +132,22 @@ void omv_gpio_write(omv_gpio_t pin, bool value)
void omv_gpio_irq_register(omv_gpio_t pin, omv_gpio_callback_t callback, void *data) void omv_gpio_irq_register(omv_gpio_t pin, omv_gpio_callback_t callback, void *data)
{ {
omv_exti_descr_t *exti_descr = NULL; omv_gpio_irq_descr_t *gpio_irq_descr = NULL;
uint32_t exti_line = omv_exti_get_line(pin); uint32_t exti_line = omv_gpio_irq_get_line(pin);
if (exti_line != 0) { if (exti_line != 0) {
exti_descr = &exti_descr_table[exti_line]; gpio_irq_descr = &gpio_irq_descr_table[exti_line];
exti_descr->enabled = true; gpio_irq_descr->enabled = true;
exti_descr->data = data; gpio_irq_descr->data = data;
exti_descr->gpio = omv_exti_get_gpio(exti_line); gpio_irq_descr->gpio = omv_gpio_irq_get_gpio(exti_line);
exti_descr->pin = pin; gpio_irq_descr->callback = callback;
exti_descr->callback = callback;
} }
} }
void omv_gpio_irq_enable(omv_gpio_t pin, bool enable) void omv_gpio_irq_enable(omv_gpio_t pin, bool enable)
{ {
uint32_t exti_line = omv_exti_get_line(pin); uint32_t exti_line = omv_gpio_irq_get_line(pin);
uint32_t exti_irqn = omv_exti_get_irqn(pin); uint32_t exti_irqn = omv_gpio_irq_get_irqn(pin);
exti_descr_table[exti_line].enabled = enable; gpio_irq_descr_table[exti_line].enabled = enable;
if (!enable) { if (!enable) {
HAL_NVIC_DisableIRQ(exti_irqn); HAL_NVIC_DisableIRQ(exti_irqn);
} else { } else {

View File

@ -45,6 +45,11 @@ typedef struct {
typedef const stm32_gpio_t *omv_gpio_t; typedef const stm32_gpio_t *omv_gpio_t;
#define OMV_GPIO_IRQ_DESCR_PORT_BITS \
struct { \
uint32_t gpio; \
};
// Dummy AF for pins defined as I/O // Dummy AF for pins defined as I/O
#define GPIO_NONE_GPIO (0) #define GPIO_NONE_GPIO (0)

View File

@ -339,7 +339,7 @@ int sensor_shutdown(int enable)
return ret; return ret;
} }
static void sensor_vsync_callback(omv_gpio_t pin, void *data) static void sensor_vsync_callback(void *data)
{ {
if (sensor.vsync_callback != NULL) { if (sensor.vsync_callback != NULL) {
sensor.vsync_callback(omv_gpio_read(DCMI_VSYNC_PIN)); sensor.vsync_callback(omv_gpio_read(DCMI_VSYNC_PIN));