UART Interrupt not triggering when receiving board is powered on before master board starts transmitting
Hello,
I have 2 boards connected via UART (baud rate of 115200). The first board is a custom board with an STM32F479 chip using the Standard Peripheral Drivers and mostly custom firmware(for sake of coherence I'm going to call this the master board). This board packages and sends data over UART to my second board. Shown below is how I package and send data from this board:
void dummy_tlm()
{
srand(300);
uint8_t data[480];
uint8_t data_with_opcode[483] = {1,2,3};
while(1)
{
// Generate dummy telemetry
for(int i = 0; i < 5; i++)
{ // These are just arrays of doubles and ints defined elsewhere, filling with random data
position[i] = (double)rand()/(double)(RAND_MAX/360);
velocity[i] = (double)rand()/(double)(RAND_MAX/80);
current[i] = (double)rand()/(double)(RAND_MAX/10);
temp_a[i] = (double)rand()/(double)(RAND_MAX/100);
temp_b[i] = (double)rand()/(double)(RAND_MAX/100);
status[i] = (int8_t)(rand() % 2);
limits[i] = (int8_t)(rand() % 2);
}
package_tlm(&data); // This function packages all telemetry into a data buffer of size 480
memcpy(data_with_opcode + 3, data, 480); // appends data to the end of buffer starting with {1,2,3}
for(int i = 0; i < 483; i++)
{
USART_SendData(LCD_UART, data_with_opcode[i]);
while(!USART_GetFlagStatus(LCD_UART, USART_FLAG_TC));
}
vTaskDelay(1000);
}
}This code does basically what I want, sending out my data buffer of size 483 over uart every second or so.
The second board is an STM32F746-Discovery board, running a TouchGFX application and mostly autogenerated HAL driver functions (calling this one the slave board). This board's job is to receive data over UART and display it on the screen, which it does just fine when it receives data properly. Here is the code I use to receive the UART transmission, largely based on the approach in this video ( https://www.youtube.com/watch?v=bCppZf8FKYg&t=1408s :(
#include "main.h"
#include "UartPollingRoutines.h"
#include "string.h"
#include "cmsis_os.h"
extern UART_HandleTypeDef huart6;
extern osSemaphoreId BinarySemUartRxHandle;
uint8_t uartMsgBuf[483];
uint8_t msgRdyFlag = 0;
void PollingInit()
{
// enable interrupt
HAL_UART_Receive_IT(&huart6, uartMsgBuf, 483);
}
void PollingRoutine()
{
if(__HAL_UART_GET_FLAG(&huart6, UART_FLAG_ORE))
__HAL_UART_CLEAR_OREFLAG(&huart6);
if(msgRdyFlag)
{
xSemaphoreGive(BinarySemUartRxHandle);
msgRdyFlag = 0;
}
}
// IRQ for HAL_UART_Receive_IT
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// Check for the 1,2,3 at the start of the data buffer, make sure we're not catching it mid-stream
if(uartMsgBuf[0] == 1 && uartMsgBuf[1] == 2 && uartMsgBuf[2] == 3)
msgRdyFlag = 1;
// Re-enable the interrupt
HAL_UART_Receive_IT(&huart6, uartMsgBuf, 483);
}PollingInit() is called once from main, and PollingRoutine() is called continuously from a task in main. The semaphore releases to trigger a series of events in Model::tick on the TouchGFX side of things.
When the master board is running and transmitting over UART prior to the slave board being powered on, the slave board gets the interrupt just fine. However, if the slave board is already on before the master board is powered and starts transmitting, we never enter HAL_UART_RxCpltCallback and the information is not received. I discovered from debugging the slave board that the UART handle has an error code of 8, which indicates that UART_FLAG_ORE (overrun error) is set, but checking and clearing it in the PollingRoutine() has not fixed the problem.
Is there some other specific flag I need to check/set/reset? Still somewhat new to using UART communication, so any and all feedback is appreciated!
