Skip to main content
Explorer
February 12, 2025
Question

Change uart settings and pinout runtime

  • February 12, 2025
  • 2 replies
  • 876 views

Hi!

I'm working with a STM32C071 and I would like to change uart1 pinout and settings runtime: I've defined USART1 (in the .ioc file) as PB2 (RX) and PC14 (TX). After boot, I would like to change the USART1 pinout as PB6 (TX) and PB7 (RX). So I've written the following:

void UART_Reconfigure(UART_HandleTypeDef *huart2change,
 GPIO_TypeDef *newTXPort, uint16_t newTXPin,
 GPIO_TypeDef *newRXPort, uint16_t newRXPin,
 GPIO_TypeDef *oldTXPort, uint16_t oldTXPin,
 GPIO_TypeDef *oldRXPort, uint16_t oldRXPin) {

 // 1. Abilita il clock per i vecchi GPIO se necessario (PRIMA di deinizializzarli)
 if (oldTXPort == GPIOA || oldRXPort == GPIOA) {
 __HAL_RCC_GPIOA_CLK_ENABLE();
 }
 if (oldTXPort == GPIOB || oldRXPort == GPIOB) {
 __HAL_RCC_GPIOB_CLK_ENABLE();
 }
 if (oldTXPort == GPIOC || oldRXPort == GPIOC) {
 __HAL_RCC_GPIOC_CLK_ENABLE();
 }

 // 2. Disabilita la UART prima di cambiare i pin
 HAL_UART_DeInit(huart2change);

 // 3. Deinizializza i vecchi pin
 HAL_GPIO_DeInit(oldTXPort, oldTXPin);
 HAL_GPIO_DeInit(oldRXPort, oldRXPin);

 // 4. Abilita il clock per i nuovi GPIO
 if (newTXPort == GPIOA || newRXPort == GPIOA) {
 __HAL_RCC_GPIOA_CLK_ENABLE();
 }
 if (newTXPort == GPIOB || newRXPort == GPIOB) {
 __HAL_RCC_GPIOB_CLK_ENABLE();
 }
 if (newTXPort == GPIOC || newRXPort == GPIOC) {
 __HAL_RCC_GPIOC_CLK_ENABLE();
 }

 // 5. Configura i nuovi pin
 GPIO_InitTypeDef GPIO_InitStruct = {0};

 // Configura TX
 GPIO_InitStruct.Pin = newTXPin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF0_USART1; // USART1 su PB6 (Verifica per altri pin!)
 HAL_GPIO_Init(newTXPort, &GPIO_InitStruct);

 // Configura RX
 GPIO_InitStruct.Pin = newRXPin;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // RX in modalità AF_PP
 GPIO_InitStruct.Pull = GPIO_PULLUP; // Pull-up abilitato
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
 GPIO_InitStruct.Alternate = GPIO_AF0_USART1; // USART1 su PB7 (Verifica per altri pin!)
 HAL_GPIO_Init(newRXPort, &GPIO_InitStruct);

 // 6. Reinizializza la UART
 huart2change->Instance = USART1;
 huart2change->Init.BaudRate = 115200;
 huart2change->Init.WordLength = UART_WORDLENGTH_8B;
 huart2change->Init.StopBits = UART_STOPBITS_1;
 huart2change->Init.Parity = UART_PARITY_NONE;
 huart2change->Init.Mode = UART_MODE_TX_RX;
 huart2change->Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart2change->Init.OverSampling = UART_OVERSAMPLING_16;
 huart2change->Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
 huart2change->Init.ClockPrescaler = UART_PRESCALER_DIV1;
 huart2change->AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;

 if (HAL_UART_Init(huart2change) != HAL_OK) {
 // Gestione errore
 Error_Handler();
 }
 if (HAL_UARTEx_SetTxFifoThreshold(huart2change, UART_TXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_SetRxFifoThreshold(huart2change, UART_RXFIFO_THRESHOLD_1_8) != HAL_OK)
 {
 Error_Handler();
 }
 if (HAL_UARTEx_DisableFifoMode(huart2change) != HAL_OK)
 {
 Error_Handler();
 }
}

I only have to launch:

UART_Reconfigure(&huart1, GPIOB, GPIO_PIN_6, GPIOB, GPIO_PIN_7, GPIOC, GPIO_PIN_14, GPIOB, GPIO_PIN_2);

But it doesn't work.

What am I missing?

Thanks

    This topic has been closed for replies.

    2 replies

    Graduate II
    February 12, 2025

    You will engage much more users if you comment your code in english, is good practice in general.

    >>But it doesn't work.

    How is it not working, is HAL_UART_Init returning an error? Have you tried using those PB6  PB7 pins from the beginning in case is not working?

     

     

     

    Edit: how about looking at 

     

    HAL_UART_MspInit

     

    Maybe you need to enable UART CLK before declaring those new pins?

     

     /* UART1 clock enable */
     __HAL_RCC_UART1_CLK_ENABLE();
    
     // 4. Abilita il clock per i nuovi GPIO
     if (newTXPort == GPIOA || newRXPort == GPIOA) {
     __HAL_RCC_GPIOA_CLK_ENABLE();
     }
     if (newTXPort == GPIOB || newRXPort == GPIOB) {
     __HAL_RCC_GPIOB_CLK_ENABLE();
     }
     if (newTXPort == GPIOC || newRXPort == GPIOC) {
     __HAL_RCC_GPIOC_CLK_ENABLE();
     }

     

     

    BRonc.1Author
    Explorer
    February 13, 2025

    Hi Xavier,

    thanks for your reply. I have no output on serial. Now i've noticed that maybe there is a conflict in pinout definition: if I set uart1 as PB6 and PB7 directly in the .ioc config, I can see that USART1 definition has a warning:

     

    immagine.png

    I will try to solve this

     

     

     

    Super User
    February 13, 2025

    yellow is only a warning (hint) that not all options for Hardware Flow Control will be available, because some will conflict with other settings.

    Debug-step through your code and compare the actual register settings with the expected ones.

    hth

    KnarfB

     

    BRonc.1Author
    Explorer
    February 17, 2025

    Hi all,

    I've solved. I was missing a setting in the build environment. Thanks to all!

    Explorer
    February 17, 2025

    This internal peripheral routing is usually very straightforward.
    You can have both sets of UART Tx / Rx pins configured and working at the same time, if that makes sense for your application.

    Never tried it on a C0xx, though.