2023-11-22 06:16 AM
Hello all,
I'm using STM32 F103CBT6 MCU on a custom board where MAXRS485 is used. Rx and Tx of the Modbus chip is connected to USART1 on the MCU.
To receive and Transmit data I'm using UART in interrupt mode. The program also has 8 GPIO interrupts on multiple ports, tim3 interrupts every 10ms and tim1 is used for software debouncing which only works when an input occurs for 50ms.
Priorities are set as follows:
GPIO 0
UART 1
TIM1 2
TIM3 3
I'm facing following issue in UART functionality :
When UART receives MODBUS query every 5 seconds, after 7- 8 hours, the UART interrupt stops receiving new data. If breakpoint is set, it does not get triggered on the
HAL_UART_RxCpltCallback
and no data is received in the buffer. I have multiple boards kept on testing, this situation occurs on different boards everyday. UART starts working again after reseting the chip.
I've connected an LED on both Rx and Tx pin when the data is received on Modbus chip, an LED glows. That is how I know that the Modbus data is getting received in MAXRS485.
I'm attaching all the interrupt code below as well as UART Rx and Tx code.
Please help me find the root cause of this solution.
UART Rx 1 Image attached
UART Rx 2
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
data_in[DataPos] = rxBuff;
DataPos+=1;
uart_rx_count += 1;
TotalCharsReceived=DataPos;
HAL_UART_Receive_IT(&huart2, &rxBuff, 1);
}
UART Tx
void MBSendData(unsigned char count)
{
int temp_size = 0;
isr_flags=USART2->SR;
cr1_its=USART2->CR1;
cr3_its=USART2->CR3;
/* UART parity error interrupt occurred ----------------------------------*/
if (((isr_flags & USART_SR_PE) != RESET) && ((cr1_its & USART_CR1_PEIE) != RESET))
{
USART2->DR=HAL_UART_ERROR_PE;
data_in[count]=HAL_UART_ERROR_PE;
}
/* UART noise error interrupt occurred -----------------------------------*/
if (((isr_flags & USART_SR_NE) != RESET) && ((cr3_its & USART_CR3_EIE) != RESET))
{
USART2->DR=HAL_UART_ERROR_NE;
data_in[count]=HAL_UART_ERROR_NE;
}
/* UART frame error interrupt occurred -----------------------------------*/
if (((isr_flags & USART_SR_FE) != RESET) && ((cr3_its & USART_CR3_EIE) != RESET))
{
USART2->DR=HAL_UART_ERROR_FE;
data_in[count]=HAL_UART_ERROR_FE;
}
/* UART Over-Run interrupt occurred --------------------------------------*/
if (((isr_flags & USART_SR_ORE) != RESET) && (((cr1_its & USART_CR1_RXNEIE) != RESET) || ((cr3_its & USART_CR3_EIE) != RESET)))
{
USART2->DR=HAL_UART_ERROR_ORE;
data_in[count]=HAL_UART_ERROR_ORE;
}
for (unsigned char c=0; c<count;c++)
{
while( !( USART2->SR & (1<<7u) ) ) {}; //wait till transmit buffer is empty
temp_size++;
USART2->DR = data_in[c];
// ** 1.5 Character delay
delay_us(1200); //9600
}
//** 3.5 character delay
delay_us(4000); //9600
//** Clear Data in buffer
memset(data_in, 0, sizeof(data_in));
}
2023-11-22 06:38 AM
Debug a chip in the affected state and example the state of the UART handles.
Could be buffer overflow. You never show how DataPos gets reset, it only monotonically increases in your code.
Nothing stands out in the snippets of code you've provided. Do any UART errors occur?
2023-11-22 09:36 PM
Hello,
Thanks for replying.
@TDK wrote:Could be buffer overflow. You never show how DataPos gets reset, it only monotonically increases in your code.
No, the buffer does not overflow. DataPos is reset when the buffer length is > 6 and then it is processed. Sorry to not mention it in the snippets.
if(CharCount>=6u)
{
CharCount=0;
DataPos=0;
failed_tx_count = 0;
//process data buffer
}
Also, no UART errors occur. GPIO and timer works during that time.
@TDK wrote:Debug a chip in the affected state and example the state of the UART handles.
I'm having the same issue in a chip right now. I debug the board using ST-Link and in debugging mode. If I connect the debugger right now, the chip will reset and it will start working. (I am unaware of a way that lets you debug without restarting the chip I will search for it).
Can you tell me if the UART interrupt is correctly handled?
Thanks again.
2023-11-23 03:27 AM - edited 2023-11-23 03:28 AM
I managed to start debugging mode without restarting the chip (Thanks to you! @TDK ). I've added a breakpoint inside UART callback function HAL_UART_RxCpltCallback but it does not get triggered. And I can see the timer and input variables constantly changing in the Live Expressions tab.
Everything on UART side seems not responding. I'm unsure.