FuriHal: various GPIO improvements (#3260)

* FuriHal: add alternative gpio pulls that covers special cases, extra checks and crash on inalid parameters.
* FuriHal: optimize pwr_XX selection in gpio_init
* FuriHal: cleanup gpio param validation crash routine
This commit is contained in:
あく 2023-12-12 14:39:14 +00:00 committed by GitHub
parent 7b85e04462
commit e2e3663524
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -3,14 +3,21 @@
#include <furi_hal_version.h> #include <furi_hal_version.h>
#include <furi_hal_resources.h> #include <furi_hal_resources.h>
#include <stm32wbxx_ll_comp.h> #include <stm32wbxx_ll_comp.h>
#include <stm32wbxx_ll_pwr.h>
#define GET_SYSCFG_EXTI_PORT(gpio) \ static uint32_t furi_hal_gpio_invalid_argument_crash() {
(((gpio) == (GPIOA)) ? LL_SYSCFG_EXTI_PORTA : \ furi_crash("Invalid argument");
((gpio) == (GPIOB)) ? LL_SYSCFG_EXTI_PORTB : \ return 0;
((gpio) == (GPIOC)) ? LL_SYSCFG_EXTI_PORTC : \ }
((gpio) == (GPIOD)) ? LL_SYSCFG_EXTI_PORTD : \
((gpio) == (GPIOE)) ? LL_SYSCFG_EXTI_PORTE : \ #define GPIO_PORT_MAP(port, prefix) \
LL_SYSCFG_EXTI_PORTH) (((port) == (GPIOA)) ? prefix##A : \
((port) == (GPIOB)) ? prefix##B : \
((port) == (GPIOC)) ? prefix##C : \
((port) == (GPIOD)) ? prefix##D : \
((port) == (GPIOE)) ? prefix##E : \
((port) == (GPIOH)) ? prefix##H : \
furi_hal_gpio_invalid_argument_crash())
#define GPIO_PIN_MAP(pin, prefix) \ #define GPIO_PIN_MAP(pin, prefix) \
(((pin) == (LL_GPIO_PIN_0)) ? prefix##0 : \ (((pin) == (LL_GPIO_PIN_0)) ? prefix##0 : \
@ -28,11 +35,16 @@
((pin) == (LL_GPIO_PIN_12)) ? prefix##12 : \ ((pin) == (LL_GPIO_PIN_12)) ? prefix##12 : \
((pin) == (LL_GPIO_PIN_13)) ? prefix##13 : \ ((pin) == (LL_GPIO_PIN_13)) ? prefix##13 : \
((pin) == (LL_GPIO_PIN_14)) ? prefix##14 : \ ((pin) == (LL_GPIO_PIN_14)) ? prefix##14 : \
prefix##15) ((pin) == (LL_GPIO_PIN_15)) ? prefix##15 : \
furi_hal_gpio_invalid_argument_crash())
#define GET_SYSCFG_EXTI_PORT(port) GPIO_PORT_MAP(port, LL_SYSCFG_EXTI_PORT)
#define GET_SYSCFG_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_SYSCFG_EXTI_LINE) #define GET_SYSCFG_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_SYSCFG_EXTI_LINE)
#define GET_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_EXTI_LINE_) #define GET_EXTI_LINE(pin) GPIO_PIN_MAP(pin, LL_EXTI_LINE_)
#define GET_PWR_PORT(port) GPIO_PORT_MAP(port, LL_PWR_GPIO_)
#define GET_PWR_PIN(pin) GPIO_PIN_MAP(pin, LL_PWR_GPIO_BIT_)
static volatile GpioInterrupt gpio_interrupt[GPIO_NUMBER]; static volatile GpioInterrupt gpio_interrupt[GPIO_NUMBER];
static uint8_t furi_hal_gpio_get_pin_num(const GpioPin* gpio) { static uint8_t furi_hal_gpio_get_pin_num(const GpioPin* gpio) {
@ -65,9 +77,11 @@ void furi_hal_gpio_init_ex(
const GpioPull pull, const GpioPull pull,
const GpioSpeed speed, const GpioSpeed speed,
const GpioAltFn alt_fn) { const GpioAltFn alt_fn) {
uint32_t sys_exti_port = GET_SYSCFG_EXTI_PORT(gpio->port); const uint32_t sys_exti_port = GET_SYSCFG_EXTI_PORT(gpio->port);
uint32_t sys_exti_line = GET_SYSCFG_EXTI_LINE(gpio->pin); const uint32_t sys_exti_line = GET_SYSCFG_EXTI_LINE(gpio->pin);
uint32_t exti_line = GET_EXTI_LINE(gpio->pin); const uint32_t exti_line = GET_EXTI_LINE(gpio->pin);
const uint32_t pwr_port = GET_PWR_PORT(gpio->port);
const uint32_t pwr_pin = GET_PWR_PIN(gpio->pin);
// Configure gpio with interrupts disabled // Configure gpio with interrupts disabled
FURI_CRITICAL_ENTER(); FURI_CRITICAL_ENTER();
@ -92,13 +106,21 @@ void furi_hal_gpio_init_ex(
switch(pull) { switch(pull) {
case GpioPullNo: case GpioPullNo:
LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_NO); LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_NO);
LL_PWR_DisableGPIOPullUp(pwr_port, pwr_pin);
LL_PWR_DisableGPIOPullDown(pwr_port, pwr_pin);
break; break;
case GpioPullUp: case GpioPullUp:
LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_UP); LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_UP);
LL_PWR_DisableGPIOPullDown(pwr_port, pwr_pin);
LL_PWR_EnableGPIOPullUp(pwr_port, pwr_pin);
break; break;
case GpioPullDown: case GpioPullDown:
LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_DOWN); LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_DOWN);
LL_PWR_DisableGPIOPullUp(pwr_port, pwr_pin);
LL_PWR_EnableGPIOPullDown(pwr_port, pwr_pin);
break; break;
default:
furi_crash("Incorrect GpioPull");
} }
// Set gpio mode // Set gpio mode
@ -166,7 +188,7 @@ void furi_hal_gpio_init_ex(
LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ANALOG); LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ANALOG);
break; break;
default: default:
break; furi_crash("Incorrect GpioMode");
} }
} }
FURI_CRITICAL_EXIT(); FURI_CRITICAL_EXIT();