Browse Source

stm32/mphalport: Fix I/O glitches when switching GPIO mode to alt-func.

To avoid any I/O glitches in mp_hal_pin_config, make sure a valid alternate
function is set in AFR first before switching the pin mode.  When switching
from AF to INPUT or OUTPUT, the AF in AFR will remain valid up until the
pin mode is switched.
pull/8563/head
iabdalkader 3 years ago
committed by Damien George
parent
commit
71afed1a70
  1. 7
      ports/stm32/mphalport.c

7
ports/stm32/mphalport.c

@ -114,6 +114,12 @@ void mp_hal_pin_config(mp_hal_pin_obj_t pin_obj, uint32_t mode, uint32_t pull, u
GPIO_TypeDef *gpio = pin_obj->gpio;
uint32_t pin = pin_obj->pin;
mp_hal_gpio_clock_enable(gpio);
if (mode == MP_HAL_PIN_MODE_ALT || mode == MP_HAL_PIN_MODE_ALT_OPEN_DRAIN) {
// To avoid any I/O glitches, make sure a valid alternate function is set in
// AFR first before switching the pin mode. When switching from AF to INPUT or
// OUTPUT, the AF in AFR will remain valid up until the pin mode is switched.
gpio->AFR[pin >> 3] = (gpio->AFR[pin >> 3] & ~(15 << (4 * (pin & 7)))) | (alt << (4 * (pin & 7)));
}
gpio->MODER = (gpio->MODER & ~(3 << (2 * pin))) | ((mode & 3) << (2 * pin));
#if defined(GPIO_ASCR_ASC0)
// The L4 has a special analog switch to connect the GPIO to the ADC
@ -124,7 +130,6 @@ void mp_hal_pin_config(mp_hal_pin_obj_t pin_obj, uint32_t mode, uint32_t pull, u
#endif
gpio->OSPEEDR = (gpio->OSPEEDR & ~(3 << (2 * pin))) | (2 << (2 * pin)); // full speed
gpio->PUPDR = (gpio->PUPDR & ~(3 << (2 * pin))) | (pull << (2 * pin));
gpio->AFR[pin >> 3] = (gpio->AFR[pin >> 3] & ~(15 << (4 * (pin & 7)))) | (alt << (4 * (pin & 7)));
}
bool mp_hal_pin_config_alt(mp_hal_pin_obj_t pin, uint32_t mode, uint32_t pull, uint8_t fn, uint8_t unit) {

Loading…
Cancel
Save