cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 UART1 and UART3 conflicts

msingh08
Associate II

I’m experiencing an issue while developing firmware on a STM32L431CCU6 connected to:

 

  • Xbee module (XB3-24Z8CM-J) via UART1
  • RS485 driver (ST1480ABDR_ Via UART2

 

HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);

HAL_NVIC_SetPriority(USART3_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(USART3_IRQn);

 

The communication to the xbee works perfectly fine until the RS485 interface is polled at which point nothing is received via UART1 (no interrupt recorded), I’ve checked the interrupt priorities and UART1 has a higher priority.

Each interface works on its own but when attempting to use the interfaces together it seems to have a conflict somewhere. Would you have any suggestion/recommendations?

 

Appreciate any help and thanks in advance. 

 

 

if(huart == &huart1)
	{
		
		Receive_test2(Rx_byte);//stores received byte into an array
		Uart_Receive_raw(&huart1,0,1);//wait another byte
		TIM15_reset_count();//timer overflows if no further bytes received for 1ms
	}

	if(huart == &huart3)
	{
		rs485RxIsr();
		RS485_increment_Rx_byte();
	}

 

 

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
msingh08
Associate II

There wasn't anything wrong in the configurations, The problem was that somewhere in the code (still need to find where) the xbee reset pin is being pulled low by the RS485 code in the while1. 

View solution in original post

6 REPLIES 6

Don't have blocking code in interrupt handlers, or related callbacks.

Review NVIC documentation, you need to use groups, and preemption to interrupt an interrupt. This is different than priority level alone.

Really just to buffer, and leave immediately, you don't want to do a lot of processing with long or unpredictable run times.

UART1, UART2 and UART3 should all be able to operate independently of each other.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Karl Yamashita
Lead III

If you need a timeout, use HAL_UARTEx_ReceiveToIdle_DMA and HAL_UARTEx_RxEventCallback instead.

See this project in the link below that uses multiple UART and a queue buffer.  

https://github.com/karlyamashita/Nucleo-G431RB_Three_UART/wiki

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.

Hi DeLorean, 

HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4); was already configured in the IOC file but I have tried placing it before initializing the priority levels and that didn't have any effect. 

 

Do you have any other suggestions? 

 

Kind Regards

Manpreet Singh

Hi Karl, 

Thanks for your reply, I've noticed your example uses DMA and I was wondering if this is necessary? I was trying to keep the code as simple as possible and achieve the result. However if it is your experience that I cannot achieve the result with interrupts then I will certainly move to DMA, can you confirm please? 

Do you think it is not a good idea to reset a timer count in the UART1_ISR? 

 

Kind Regards

Manpreet Singh

msingh08
Associate II

There wasn't anything wrong in the configurations, The problem was that somewhere in the code (still need to find where) the xbee reset pin is being pulled low by the RS485 code in the while1. 

I did briefly test it without DMA and it worked, but i did not do any regression testing.

You can use HAL_UARTEx_ReceiveToIdle_IT in place of HAL_UARTEx_ReceiveToIdle_DMA. 

Skip the part of adding the DMA channels for the U(S)ARTn. 

 

The part i don't remember is if half callback is called or not? You'll have to test for that.

If half callback is not called, then this part of the code

void UART_DMA_EnableRxInterrupt(UART_DMA_QueueStruct *msg)
{
	msg->rx.HAL_Status = HAL_UARTEx_ReceiveToIdle_DMA(msg->huart, msg->rx.queue[msg->rx.ptr.index_IN].data, UART_DMA_CHAR_SIZE * 2);
}

Replace with 

void UART_DMA_EnableRxInterrupt(UART_DMA_QueueStruct *msg)
{
	msg->rx.HAL_Status = HAL_UARTEx_ReceiveToIdle_IT(msg->huart, msg->rx.queue[msg->rx.ptr.index_IN].data, UART_DMA_CHAR_SIZE); // * 2 removed
}

  

 

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.