summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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) {