I am developing on the TM4C123FH6PM using CCS V5.5 and TI-RTOS 1.21.
My project is to utilize all 8 UARTs with external RS-485 interfaces. The nature of the communication RX messages is that the length of any given message is variable. I need to detect the end of a message frame to initiate action on the message. I thought that I could use one of the MCU timers in one-shot mode and re-trigger the timer on each byte received. However, there are not enough timers in the MCU to allow one to be associated with each port.
I think that using the CLOCK module and creating a one-shot timer for each port. In order for this to work, I must be able to "re-trigger" this module on each byte received and set the timeout value longer the one-character time (BAUD rate dependent).
I was in the process of implementing this strategy when I read this from the CDOC:
Void Clock_setTimeout(Clock_Handle handle, UInt32 timeout);
ARGUMENTS
handle — handle of a previously-created Clock instance object
timeout — initial timeout in Clock ticks
CONSTRAINTS
Cannot change the initial timeout of instance that has been started. <<<=====
I think this means that I can't do what I had planned:
A. Create the one-shot in the GUI.
B. Start it on my first RX'd character
C. Stop on the next character
D. Reset the timeout period.
E. Start the timer again - hoping that it runs again from 0 to timeout value.
Using this method once the timer finally expires the function called will execute when the message frame is ready for processing.
Transmitting is not so difficult as I know when the last byte is sent and I can trigger the one-shot to allow the UART to clock out the byte with a sufficient amount of extra dead time before changing the RTS line to put the RS485 converter back into RX mode.
My main question is: Can I stop, then reset the timeout period, and then restart a CLOCK module repeatedly in the manner described above?
PLAN B: In a CLOCK module timer, read a Global that keeps track of the number of bytes received - incremented by the RX call back function. In this timer module I would look at this byte counter and detect when it is NOT zero and NOT incrementing after several cycles of the timer. My concerns here are can I lock out the RX callback routine from modifying the byte counter while I am checking the counter in the timer isr. Using global INT disable would work however, it slows down system response and steals time from the scheduler. Advantages of this solution - responsive to message end and only one timer can check ALL UART channels.
PLAN C: Use a high priority task to check the byte counters which are pushed via message queues. I have no experience in using message queues. I am concerned that if I put a queue each time a character arrives, will the task run at a sufficient frequency to service and empty the queue or will an overrun occur?
I want to use a method that minimizes memory footprint and system resources. My BAUD rates range from 4800 to 115,200. It is not acceptable to set a one-shot timer for the longest possible time delay based on the buffer length and slowest BAUD rate as this would artificially delay system response time.
I would appreciate any architectural and code example ideas offered.
Thank you.