Skip to main content
ICohe.1
Associate III
May 30, 2020
Question

huart2 died on reception and needs repower

  • May 30, 2020
  • 11 replies
  • 1793 views

F4 board (Master) with huart1 & huart2 identically configured, talking to 2 identical boards(Slaves) with the same program. huart1 works perfectly, huart2 dies after receiving from slave.

Sequence:

Master sends 6 chars ( 9600) using HAL_UART_Transmit_IT() and slave answer with 20 chars repeatedly. Works fine when tested with huart1(on PB6,PB7).

Connecting the same slave to huart2(on PA2,PA3) instead, Master sends, slave received, slave answer with 20 chars, then Master try to send again but nothing coming out on the wire.

HAL_UART_Transmit_IT() still generate a call to HAL_UART_TxCpltCallback() but nothing is out.

The only way to get this single transaction again is to repower the Master.

The program do not even try to receive. No call to any IRQ or polling reception function. If I disconnect the Master's RX wire, it can transmit again (but useless without the slaves answer) .

Settings are identical for both huarts and done with QubeIDE.

Here is the simple program I use

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart){
	__NOP();
}
 
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart){
	__NOP();
}
 
 
 
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart){
	__NOP();
}
 
UART_HandleTypeDef *uartUsed;
 
int main(void)
{
 HAL_Init();
 
 SystemClock_Config();
 
 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_I2C1_Init();
 MX_USART1_UART_Init();
 MX_RTC_Init();
 MX_USART2_UART_Init();
 MX_USART6_UART_Init();
 MX_TIM1_Init();
 
 uartUsed=&huart2;
 
 while (1)
 {
		 HAL_Delay(1000);
		 HAL_UART_Transmit_IT(uartUsed,txBuffCmd,6); 
 }
 
static void MX_USART1_UART_Init(void)
{
 
 /* USER CODE BEGIN USART1_Init 0 */
 
 /* USER CODE END USART1_Init 0 */
 
 /* USER CODE BEGIN USART1_Init 1 */
 
 /* USER CODE END USART1_Init 1 */
 huart1.Instance = USART1;
 huart1.Init.BaudRate = 9600;
 huart1.Init.WordLength = UART_WORDLENGTH_8B;
 huart1.Init.StopBits = UART_STOPBITS_1;
 huart1.Init.Parity = UART_PARITY_NONE;
 huart1.Init.Mode = UART_MODE_TX_RX;
 huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart1.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_UART_Init(&huart1) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART1_Init 2 */
 
 /* USER CODE END USART1_Init 2 */
 
}
 
/**
 * @brief USART2 Initialization Function
 * @param None
 * @retval None
 */
static void MX_USART2_UART_Init(void)
{
 
 /* USER CODE BEGIN USART2_Init 0 */
 
 /* USER CODE END USART2_Init 0 */
 
 /* USER CODE BEGIN USART2_Init 1 */
 
 /* USER CODE END USART2_Init 1 */
 huart2.Instance = USART2;
 huart2.Init.BaudRate = 9600;
 huart2.Init.WordLength = UART_WORDLENGTH_8B;
 huart2.Init.StopBits = UART_STOPBITS_1;
 huart2.Init.Parity = UART_PARITY_NONE;
 huart2.Init.Mode = UART_MODE_TX_RX;
 huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
 huart2.Init.OverSampling = UART_OVERSAMPLING_16;
 if (HAL_UART_Init(&huart2) != HAL_OK)
 {
 Error_Handler();
 }
 /* USER CODE BEGIN USART2_Init 2 */
 
 /* USER CODE END USART2_Init 2 */
 
}

This topic has been closed for replies.

11 replies

waclawek.jan
Super User
May 30, 2020

> F4 board

What board is it? Is it a Nucleo or Disco? Isn't PA2/PA3 connected to something else on the board, e.g. STLink's VCP pins?

JW

ICohe.1
ICohe.1Author
Associate III
May 30, 2020

it is a custom board. PA2/PA3 on Master are connected to PA10/PA9 on slave (F042) through 2X100R resistors. and a 30 cm flat cable

PIN ---- 100R----Cable-----100R----PIN

waclawek.jan
Super User
May 30, 2020

I don't use Cube/HAL, but you always can read out the USART (and maybe relevant GPIO) registers and check/compare to working case.

JW

ICohe.1
ICohe.1Author
Associate III
May 30, 2020

Right. I could not see any different in the uart registers. It is not the same as there is no diff. Wondering if it is electric latch up. Because the only way to get it send again is turning it off and on again. Is there any constructural different between uart1 and uart2 ?

Piranha
Principal III
May 30, 2020

> Wondering if it is electric latch up. Because the only way to get it send again is turning it off and on again.

Stop wondering and write normal register based code at least for a test. Basic USART implementation takes only a few lines of code! There is a 99% chance that you'll see that the hardware works and the problem is caused by HAL/Cube non-working bloatware.

waclawek.jan
Super User
May 30, 2020

I don't think there are differences in hardware. There's one minor, i.e. that USART1 is on APB2 whereas USART2 is on APB1 (you did not tell us which F4 exactly do you use, but most if not all of them have this); but I don't see any possible mechanism where this would make any significant difference.

You've observed the Tx line using oscilloscope, I presume, and you've have verified that the code went through the instructions which actually write to USART data register.

If you use interrupts, I presume you've checked they stay enabled both in USART and NVIC.

If you can't see anything obvious in the UART and GPIO registers (which you might've posted for us to check), I'd say the problem may quite well be in Cube/HAL. You can try to debug Cube/HAL, observing its variables and states; or you can get rid of it and rewrite your code with direct register access.

JW

ICohe.1
ICohe.1Author
Associate III
May 30, 2020

It is an STM32F401RET6. Didn't use scope but USB-Serial adapter connected to the Rx/Tx lines of the cable and terminal software on the PC.

When cable is connected to uart1 , I can see Master to slave transmission. then slave to master transmission and again -never stop.

When changing the code to use uart2 (I also moved the cable to the uart2 connector) I can see: Master to slave, then slave to master and then eveything stopps.

Master still execute HAL_UART_Transmit_IT(uartUsed,txBuffCmd,6); and even the HAL_UART_TxCpltCallback() is being called but the terminal dose not show anything.

Except of course the first transmission. The salve also report when receiving from master on another slave's uart.

I assume (might be wrong) that my setup is valid because for the first it works with uart1 and secondly, with uart2 I can detect the first Master transmission.

Somehow the slave transmission upset the output stage of the uart in a none recoverable fashion, As you can see in the program snippet above, apart from the configuration the software consist of selecting the uart in line 32 and then a while loop with a delay line and a HAL_UART_Transmit_IT.

I will first check again the hardware and then a low level uart programming as both of you sugested.

ICohe.1
ICohe.1Author
Associate III
May 31, 2020

I want to inform you and others that might be reading this thread. I had a hardware issue. After fixing it everything works perfect. Yes with HAL functions, which in my case simplify fixed data length communication. The hardware issue was another mcu (TM32F070F6P6) on the master board hooked up to the same 4 communication lines. The other mcu was never programmed so in theory should not be an issue because all I/Os are inputs on powerup. Since I am not going to use this mcu, just removing it solved the problem.

Piranha
Principal III
May 31, 2020

So the second MCU's pin capacitance changed some minor timing and the HAL bugware failed. It's not a hardware, but a software issue. Change the power supply, temperature, put it in a box or add another unrelated code and it will fail again... Because it's broken!

> fixed data length communication

There is no such a thing with USART. USART is a stream (not message) based protocol. If you threat it like message based, your software will inevitably fail some day. You can implement messaging protocol over USART yourself and it's not so hard. Use some header, checksum and/or timing to separate frames.

As for USART driver code, this is pretty good guide:

https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

waclawek.jan
Super User
May 31, 2020

One of the common problems in debugging is not listening to others' questions:

>> Isn't PA2/PA3 connected to something else on the board

I understand why that is: you've already discarded that question beforehand by judging that it's irrelevant (and my question was also blurred by the fact that I was talking about Nucleo there).

This is why talking to the teddybear (explaining the problem to ruber duck, your wife/girlfriend, the cleaning lady, etc.) *is* a valid debugging method: by explaining the problem to an outsider, you question yourself (or if you talk to a person, potentially he/she questions maybe in an unqualified way) the thought paths you've already taken, and potentially "unlock" other paths.

> in theory should not be an issue because all I/Os are inputs on powerup

That's the generalized vision, but obviously, they don't all remain so. See AN2606.

JW