TM4C1233H6PM Tiva processor
Custom Board using a combination battery & usb for power.
System clock is 80MHz on external oscillator.
TI-RTOS version tirtos_tivac_2_01_00_03.
The project I am working on uses UART 1 connected to an external bluetooth module. The UART is configured for 8, none and 1 and at a baud of 1382400.
During setup the uart interface is used in its standard blocking mode and data frames are received and sent normally. After initialization the uart is put into callback mode. This is done to free up the task that called UART_read to enable it to handle other events and or messages instead of waiting forever or timing out waiting for data to arrive.
My understanding of the callback mode is you can call UART_read in that mode to allow the calling task to perform other actions and not be forced to wait for data to arrive before proceeding further. So, when data does arrive on the UART the callback is called and it should then be treated like any other ISR (or this case Hwi) and notify the interested parties (aka Event driven process).
The problem occurs when frames larger then 16 bytes arrives. The FIFO overflows and the remaining of the frame is lost.
The protocol we are using sends the frame length in the third byte of the frame and the protocol has beginning and terminating bytes so we know when the frame starts, how long and where it ends.
Below is the code that is being used:
uint32_t uiRemainder_frame_rcv_len = 0; void vIneedMD_radio_read_cb(UART_Handle sHandle, void *buf, int count) { // tRadio_request tParams; ERROR_CODE eEC = ER_FAIL; tRadio_message tRadio_msg; int i = 0; int iBuff_Index = 0; uint32_t uiRcv = 0; uint8_t * c = (uint8_t * )buf; if(count == 3) { if(c[0] == INEEDMD_CMND_SOF) { //Protocol frame // eRadio_Message_Params_Init(&tRadio_msg); uiRemainder_frame_rcv_len = c[2] - 3; tRadio_msg.uiFrame_len = c[2]; memcpy(tRadio_msg.uiBuff, c, c[2]); tRadio_msg.eMessage = RADIO_MSG_RCV_PROTOCOL_FRAME; Mailbox_post(tTIRTOS_Radio_mailbox, &tRadio_msg, BIOS_NO_WAIT); } return; } else if(count == uiRemainder_frame_rcv_len) { tRadio_msg.uiFrame_len = count; uiRemainder_frame_rcv_len = 0; memcpy(tRadio_msg.uiBuff, c, count); tRadio_msg.eMessage = RADIO_MSG_FINISH_RCV_PROTOCOL_FRAME; Mailbox_post(tTIRTOS_Radio_mailbox, &tRadio_msg, BIOS_NO_WAIT); } else { return; } } void vRadio_task(UArg a0, UArg a1) { ERROR_CODE eEC = ER_FAIL; eRadio_connection_state eConn_State; tRadio_message tRadio_Message; uint16_t uiRcvd_str_len = 0; int i = 0; uint8_t cRcv_frame[128]; eIneedMD_radio_setup(); eRadio_Message_Params_Init(&tRadio_Message); UART_read(sRadio_UART_handle, cRcv_frame, 3); while(1) { if(Mailbox_pend(tTIRTOS_Radio_mailbox, &tRadio_Message, BIOS_WAIT_FOREVER) == true) { switch(tRadio_Message.eMessage) { case RADIO_MSG_RCV_PROTOCOL_FRAME://RADIO_REQUEST_RECEIVE_PROTOCOL_FRAME: UART_read(sRadio_UART_handle, &cRcv_frame[3], (tRadio_Message.uiFrame_len - 3)); break; case RADIO_MSG_FINISH_RCV_PROTOCOL_FRAME: if((cRcv_frame[0] == PROTOCOL_SOF) & \ (cRcv_frame[tRadio_msg.uiFrame_len + 3] == PROTOCOL_EOF)) { //do something } //begin another uart read to for the next frame UART_read(sRadio_UART_handle, cRcv_frame, 3); break; default: break; } } } }
You will have to excuse me if the snippit has some errors in it, I tried to abstract the parts of the code that were not relevant to this issue and may have miss typed a variable name or function.
In any case the code works as expected with small frames (ie < 16 bytes) but once the frames are "large" the uart callback function never gets called for the remainder of the frame therefore the event is never completed. According to the UART1 registers the UART overrun flag is set and data was lost.
Is there something I am missing in my code when it comes to using uart callback mode?
I am trying to avoid polling the uart (IE doing a uart read and if no data was received do a read again, NOT the rtos uart polling function)because that defeats the purpose of the event driven process. This also can cause lag in the system while the task that called uart_read() can't respond to messages while waiting for the uart to timeout.
Thanks in advance.