Skip to main content
Graduate
January 27, 2025
Solved

loopback with UART Tx pin configured as AF_OD and Rx pin as GPIO_Input

  • January 27, 2025
  • 5 replies
  • 4520 views

I'm trying uart loopback and checking if I'm receiving the transmitted data on the receive buffer, I'm using nucleo-u575zi board , uart2 I'm using , baudrate is 57600 , the tx pin & rx pin are configured as shown below

 

 GPIO_InitStruct.Pin = GPIO_PIN_2;
 GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 GPIO_InitStruct.Pin = GPIO_PIN_3;
 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
 GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

 

  I'm using receive in interrupt mode and in ISR function I'm trying to receive byte by byte, And also, before going to receive callback it goes error callback function where the error-code is 4 and then it goes rxcallback where byte by byte reception happens, but buffer value is zero.
If the tx & rx modes AF_PP it works fine where in buffer I can see the data in buffer Whatever I'm transmitting but in the above-mentioned mode, receive buffer nothing is coming.
I have attached the main.c , msp.c and it.c files below, kindly ignore the commented lines I was trying to work on something else too.

    This topic has been closed for replies.
    Best answer by gbm

    I wrote it already: configure TX as OD AF with pullup enabled. Configure RX as AF with pullup enabled. Do NOT set RX as input - it's not STM32F1 series. For any MCU of any STM32 series other than F1, the peripheral input pin MUST BE CONFIGURED as AF, not as input (input == GPIO input). Also, unlike in F1, the pullups are configured independently from other pin characteristics.

    I am not sure if internal pullups are enough for 57600; I guess not. They should be ok for up to 9600 maybe. Above that use external pullup resistor of 1.5..4.7k.

    5 replies

    Technical Moderator
    January 27, 2025

    Hello @Meghana ,

    I'm editing your post to comply with the ST Community guidelines. In next time, please use </> button for your code.
    Please review our recommendation on this link on how to post a thread in this community:
    https://community.st.com/t5/community-guidelines/how-to-write-your-question-to-maximize-your-chances-to-find-a/ta-p/575228

    MeghanaAuthor
    Graduate
    January 27, 2025

    Thank you for correcting me from now on I'll adhere to the ST Community guidelines.

    Technical Moderator
    January 27, 2025

    Hi @Meghana ,

    The error code indicates a framing error, which might be caused by incorrect baud rate or UART settings.

    You can refer to the UART examples available in the STM32CubeU5 firmware package for your Nucleo-U575 board:

    STM32CubeU5/Projects/NUCLEO-U575ZI-Q/Examples at main · STMicroelectronics/STM32CubeU5 · GitHub

    MeghanaAuthor
    Graduate
    January 27, 2025

    Hi @Imen.D,

    I have explored the examples which u have sent. Thank you for the response and resources. But I'm trying to figure out the working of Tx & Rx in different modes which are open drain mode and input mode respectively, when using the AF_PP mode I'm getting data correctly but not in open drain mode. I need help to figure out the open-drain mode. 
    In loop back I don't think baud rate might be an issue for frame error, other uart settings are there in the main.c file which I've attached.

    Thanks, 
    Meghana

    gbmAnswer
    Graduate
    January 27, 2025

    I wrote it already: configure TX as OD AF with pullup enabled. Configure RX as AF with pullup enabled. Do NOT set RX as input - it's not STM32F1 series. For any MCU of any STM32 series other than F1, the peripheral input pin MUST BE CONFIGURED as AF, not as input (input == GPIO input). Also, unlike in F1, the pullups are configured independently from other pin characteristics.

    I am not sure if internal pullups are enough for 57600; I guess not. They should be ok for up to 9600 maybe. Above that use external pullup resistor of 1.5..4.7k.

    Super User
    January 27, 2025

    Is this setting generated by Cube - or you playing around yourself ?

     

    +

    it should be like this:

     /**UART7 GPIO Configuration
     PE7 ------> UART7_RX
     PE8 ------> UART7_TX
     */
     GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
     GPIO_InitStruct.Alternate = GPIO_AF7_UART7;
     HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
    MeghanaAuthor
    Graduate
    January 27, 2025

    Hi 

    Thank you for the response. The code is generated as you mentioned only but for my testing purpose, I need it in the mentioned configuration where Tx pin is open-drain and Rx pin is input mode. 
    The loopback works fine for the default configuration but when I change it to mentioned configurations and do receive in interrupt mode, it calls error callback function where it shows error code as 4 which indicates frame error after clearing that flag then it goes rxcallback function. 

    I attached an external pullup resistor of 10kohms to the Tx line as it is in open drain mode.

    Kindly, check the files I have attached.


    Super User
    January 27, 2025

    Hi,

    see in rm U5xx :

    port registers :

    AScha3_0-1737968529755.png

    For uart rx/tx you need AF setting. But you cannot choose more than ONE mode for a pin.

    You haveto  set it to AF , uart working then.

    ...and try, to read the input state from input register - should be still connected, if this pic is correct:

    AScha3_1-1737968728950.png

     

    Just try... (i never tried and have no U5...) .If there is an input mux , not shown in pic, then its not possible.

    Graduate
    January 27, 2025

    It cannot work this way - the pin configuration is incorrect. First, it's not F1 series - Rx must be configured as AF, not as GPIO input. Then, it MUST be pulled up. Additionally, you may enable pullup on TX to make it slightly stronger.

    MeghanaAuthor
    Graduate
    January 27, 2025

    Hi 

    Thank you for the response. So, to be specific you are saying that using u5 series board I cannot do this but why? Transmission works fine, but why doesn't receive work? Also should I enable internal pullup for Tx and Rx pin configurations?

    GPIO_InitStruct.Pull = GPIO_PULLUP;

     

    Super User
    January 27, 2025

    @Meghana wrote:

    Transmission works fine


    How have you verified that?

    Any open-drain (or open-collector) output will always require a pullup to work - it's basic electronics.

    An open-drain output acts as just a switch to ground: it can pull down, but it can never drive high - hence a pullup is always essential.

    Internal pullups have a fairly high resistance - around 40k ? - so are not going to be suitable for high-speed comms.

    This post shows the effect of pullup value on the communication:

    AndrewNeil_3-1737969789848.png

    So use an oscilloscope to check what's happening in your case ...

    Super User
    January 27, 2025

    In your code:

    void send_dcdi_command(uint8_t* data, uint8_t size){
    	//HAL_UART_Transmit_IT(&huart2, data, 3);
    
    //	 HAL_UART_AbortReceive(&huart2);
    //	 HAL_UART_Receive_IT(&huart2, buffer, 1);
    	//__HAL_UART_CLEAR_FEFLAG(&huart2);
    	 //enable uart receive in interrupt mode
    	HAL_UART_Transmit(&huart2, data, 3,20);
    	HAL_UART_Receive_IT(&huart2, buffer, 1);

    HAL_UART_Transmit does not return until the transmission is finished;

    You only call HAL_UART_Receive_IT after that - when the transmission is finished and gone!

    AndrewNeil_0-1737972908109.png

     

    MeghanaAuthor
    Graduate
    January 27, 2025

    Sorry, just to understand more clearly so, u meant when transmission is happening only receiving also is happening at same time but I'm calling receive function after transmission so that is the reason no data is coming in receive buffer, is it?

     

    Super User
    January 27, 2025

    @Meghana wrote:

     u meant when transmission is happening only receiving also is happening at same time 


    Not in the way you've coded it.

    Again, HAL_UART_Transmit does not return until the transmission is finished.

     


    @Meghana wrote:

    I'm calling receive function after transmission so that is the reason no data is coming in receive buffer, is it? 


    Probably; or, at least, the reason you're not getting an interrupt.

    Try this instead:

     

    // Prepare to receive data
    HAL_UART_Receive_IT(&huart2, buffer, 1);
    
    // Transmit some data
    HAL_UART_Transmit(&huart2, data, 3,20);

     

    There seems to be a lot of superfluous stuff in the code you posted.

    I would strongly suggest that you start with a simple project which just does this - nothing else.

    You can add the extras after you have the basics working.