summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriabdalkader <i.abdalkader@gmail.com>2022-04-13 16:54:01 +0200
committerDamien George <damien@micropython.org>2022-04-20 15:31:14 +1000
commit71afed1a70d1b783d104d29878be3c44fae7cbcf (patch)
tree0da708e15b4d862c0eb4679eecbe3f1ac71364ea
parentb50fe9a6da13bc14cd3fcdba87d715f406d5c913 (diff)
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.
-rw-r--r--ports/stm32/mphalport.c7
1 files changed, 6 insertions, 1 deletions
diff --git a/ports/stm32/mphalport.c b/ports/stm32/mphalport.c
index 202538841..9961c3d99 100644
--- a/ports/stm32/mphalport.c
+++ b/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) {