diff --git a/cpu/stm32/include/periph_cpu.h b/cpu/stm32/include/periph_cpu.h index ef6572f1808b4..119813d23a17a 100644 --- a/cpu/stm32/include/periph_cpu.h +++ b/cpu/stm32/include/periph_cpu.h @@ -839,6 +839,20 @@ void periph_clk_dis(bus_t bus, uint32_t mask); */ void gpio_init_af(gpio_t pin, gpio_af_t af); +/** + * @brief Same as @ref gpio_init, but will set the pin as early as possible + * during initialization + * + * @param pin Pin to initialize + * @param mode Mode to initialize with + * + * @retval 0 Success + * + * This function is useful to initialize a pin almost flicker free, + * e.g. for UART + */ +int gpio_init_set(gpio_t pin, gpio_mode_t mode); + /** * @brief Configure the given pin to be used as ADC input * diff --git a/cpu/stm32/periph/gpio_all.c b/cpu/stm32/periph/gpio_all.c index ef9a6bb09ae2f..3edd787d4707f 100644 --- a/cpu/stm32/periph/gpio_all.c +++ b/cpu/stm32/periph/gpio_all.c @@ -83,7 +83,7 @@ static inline int _pin_num(gpio_t pin) return (pin & 0x0f); } -int gpio_init(gpio_t pin, gpio_mode_t mode) +static int _gpio_init(gpio_t pin, gpio_mode_t mode, int set_on_init) { GPIO_TypeDef *port = _port(pin); int pin_num = _pin_num(pin); @@ -107,6 +107,10 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) periph_clk_en(AHB1, (RCC_AHB1ENR_GPIOAEN << _port_num(pin))); #endif + if (set_on_init) { + gpio_set(pin); + } + /* set mode */ port->MODER &= ~(0x3 << (2 * pin_num)); port->MODER |= ((mode & 0x3) << (2 * pin_num)); @@ -122,6 +126,16 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) return 0; } +int gpio_init(gpio_t pin, gpio_mode_t mode) +{ + return _gpio_init(pin, mode, 0); +} + +int gpio_init_set(gpio_t pin, gpio_mode_t mode) +{ + return _gpio_init(pin, mode, 1); +} + void gpio_init_af(gpio_t pin, gpio_af_t af) { GPIO_TypeDef *port = _port(pin); diff --git a/cpu/stm32/periph/gpio_f1.c b/cpu/stm32/periph/gpio_f1.c index 938c75ea01b0d..758043f0928eb 100644 --- a/cpu/stm32/periph/gpio_f1.c +++ b/cpu/stm32/periph/gpio_f1.c @@ -74,8 +74,7 @@ static inline int _pin_num(gpio_t pin) return (pin & 0x0f); } - -int gpio_init(gpio_t pin, gpio_mode_t mode) +static int _gpio_init(gpio_t pin, gpio_mode_t mode, int set_on_init) { GPIO_TypeDef *port = _port(pin); int pin_num = _pin_num(pin); @@ -88,6 +87,10 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) /* enable the clock for the selected port */ periph_clk_en(APB2, (RCC_APB2ENR_IOPAEN << _port_num(pin))); + if (set_on_init) { + gpio_set(pin); + } + /* set pin mode */ *(uint32_t *)(&port->CRL + (pin_num >> 3)) &= ~(0xf << ((pin_num & 0x7) * 4)); *(uint32_t *)(&port->CRL + (pin_num >> 3)) |= ((mode & MODE_MASK) << ((pin_num & 0x7) * 4)); @@ -101,6 +104,16 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) return 0; /* all OK */ } +int gpio_init(gpio_t pin, gpio_mode_t mode) +{ + return _gpio_init(pin, mode, 0); +} + +int gpio_init_set(gpio_t pin, gpio_mode_t mode) +{ + return _gpio_init(pin, mode, 1); +} + void gpio_init_af(gpio_t pin, gpio_af_t af) { int pin_num = _pin_num(pin); diff --git a/cpu/stm32/periph/uart.c b/cpu/stm32/periph/uart.c index 5cba9470ec9fe..348cea10c7998 100644 --- a/cpu/stm32/periph/uart.c +++ b/cpu/stm32/periph/uart.c @@ -116,10 +116,8 @@ static inline void uart_init_cts_pin(uart_t uart) static inline void uart_init_pins(uart_t uart, uart_rx_cb_t rx_cb) { - /* configure TX pin */ - gpio_init(uart_config[uart].tx_pin, GPIO_OUT); - /* set TX pin high to avoid garbage during further initialization */ - gpio_set(uart_config[uart].tx_pin); + /* configure TX pin and directly set it, so ideally no garbage is send */ + gpio_init_set(uart_config[uart].tx_pin, GPIO_OUT); #ifdef CPU_FAM_STM32F1 gpio_init_af(uart_config[uart].tx_pin, GPIO_AF_OUT_PP); #else