cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_UART_Transmit with Single Wire Half Duplex?

Using CubeIDE v1.13.0, installed this week.

On STM32F0Discovery (STM32F051):

  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  HAL_UART_Transmit( &huart1, "Hello, UART1 world!\r\n", 21, 10000 );
	  HAL_GPIO_TogglePin( LD3_GPIO_Port, LD3_Pin );
	  HAL_Delay( 500 );

	  HAL_UART_Transmit( &huart2, "Hello, UART2 world!\r\n", 21, 10000 );
	  HAL_GPIO_TogglePin( LD4_GPIO_Port, LD4_Pin );
	  HAL_Delay( 500 );

    /* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */

The first HAL_UART_Transmit is to UART1, configured as full-duplex.
This works fine - the full string is transmitted each time:

AndrewNeil_0-1691052174456.png

The second HAL_UART_Transmit is to UART2, configured as Single Wire Half Duplex.
This does not quite work - only the 1st two characters are ever transmitted:

AndrewNeil_1-1691052247089.png

If I single-step the transmit loop in the HAL_UART_Transmit for UART2, it does transmit the entire string.

So what's going on here? Is there some gotcha! with Single Wire Half Duplex?

(Screenshots are from YAT; same results when using TeraTerm)

 

1 ACCEPTED SOLUTION

Accepted Solutions

"Datasheet says that happens in hardware"

Well, sort of ...

What the datasheet is talking about is just the input/output setting of the hardware pin.

The user code does have to manage the enabling & disabling of the UART peripheral's transmitter & receiver.

The problem is that the generated initialisation function leaves both the transmitter and the  receiver enabled!

This is what causes HAL_UART_Transmit to fail.

Two options to fix:

  1. Add a HAL_HalfDuplex_EnableTransmitter call (which does disable the receiver) before HAL_UART_Transmit;

  2. Add an LL_USART_DisableDirectionRx call before HAL_UART_Transmit.

View solution in original post

6 REPLIES 6

I reconfigured the IOC to 'Async' instead of Single Wire Half Duplex & re-generated.

No other changes to code.

Now UART2 is also fine:

AndrewNeil_0-1691058338771.png

So there definitely is something wrong with HAL_UART_Transmit in Single Wire Half Duplex.

LCE
Principal

Then go through that function and find what's happening when the half-duplex select bit is set.

Anyway, you could still manage the half-duplex by yourself, always turn off the transmitter after each transmission.

LCE
Principal

... okay, in my H7 uart HAL functions there's not much about half-duplex management, mostly that it is an extra init function, not much else.

And nothing in the HAL_UART_Transmit function.

"Then go through that function and find what's happening when the half-duplex select bit is set"

Yes - doing that...

Not seen anything in Ref Manual yet that suggests the operation should be any different at all.

AndrewNeil_0-1691061513408.png

 

"you could still manage the half-duplex by yourself, always turn off the transmitter after each transmission"

Datasheet says that happens in hardware.

"Datasheet says that happens in hardware"

Well, sort of ...

What the datasheet is talking about is just the input/output setting of the hardware pin.

The user code does have to manage the enabling & disabling of the UART peripheral's transmitter & receiver.

The problem is that the generated initialisation function leaves both the transmitter and the  receiver enabled!

This is what causes HAL_UART_Transmit to fail.

Two options to fix:

  1. Add a HAL_HalfDuplex_EnableTransmitter call (which does disable the receiver) before HAL_UART_Transmit;

  2. Add an LL_USART_DisableDirectionRx call before HAL_UART_Transmit.
Imen.D
ST Employee

Hello,

An internal ticket (ID 160120) is submitted in order to work on this issue.
(PS: ID 160120 is only for reference, not available outside of ST)

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen