2024-06-03 08:22 AM
I’m experiencing an issue while developing firmware on a STM32L431CCU6 connected to:
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();
}
Solved! Go to Solution.
2024-06-04 02:27 AM
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.
2024-06-03 08:40 AM - edited 2024-06-03 08:41 AM
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.
2024-06-03 12:09 PM
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
2024-06-04 02:00 AM
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
2024-06-04 02:09 AM
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
2024-06-04 02:27 AM
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.
2024-06-04 07:58 AM
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
}