Skip to main content
Associate II
January 27, 2025
Solved

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

  • January 27, 2025
  • 19 replies
  • 4743 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.

19 replies

ST 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

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
MeghanaAuthor
Associate II
January 27, 2025

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

ST 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

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
MeghanaAuthor
Associate II
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

gbm
gbmBest answer
Super User
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.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
AScha.3
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);
If you feel a post has answered your question, please click on " Best Answer ".
MeghanaAuthor
Associate II
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.


AScha.3
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.

If you feel a post has answered your question, please click on " Best Answer ".
gbm
Super User
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.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
MeghanaAuthor
Associate II
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;

 

Andrew Neil
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 ...

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Andrew Neil
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

 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
MeghanaAuthor
Associate II
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?

 

Andrew Neil
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.

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.