Part Number: LAUNCHXL-F28377S
Tool/software: Code Composer Studio
I'm a little stumped on how to do this more complex task, involving the CLA and a queue.
Some quick background: I have two main CLA tasks, the first (Task1) is triggered by the ADCB EOC (which itself is triggered by Timer0 at 100 kHz), and the second (Task2) is triggered by Timer0 itself (this was arrived at after much experimenting, and tweaking, as whenever I had Task2 running more often than the ADC task, the ADC task would never start - so I set them both up to use the same interval, only staggered). Task1 works perfectly, storing the ADC results in a simplistic ring buffer, and performing a simple calculation in the Task1 ISR. The second mostly works.
Task2 is used to toggle some GPIO pins for communicating with an external device. Because the total length of the codes are on the order of 100's of microseconds, instead of delaying, I use a simple case structure on each trigger to determine if it should: do nothing, turn on the code pins, turn on the strobe pin, turn off the strobe pin, turn off the code pins. This way each time the task is called, it completes nearly instantaneously, with the output codes being the proper length for the external device. The task works on one code per time, and once it is done, attempts to grab another from a queue. If none, it just continues passing right through.
Now, the tricky part. I have two requirements: 1) that I can add bytes to the end of the queue faster than the task will consume them (pretty easy in theory and practice) and 2) that I can add a byte to the front of the queue (not replacing the currently transmitting byte, just the front of the queue). The first ability is to send medium-short messages (2-20 characters). This second ability is necessary to send a single byte about any external interrupts that come in - as quickly as possible, and even in the middle of transmitting a message. I've set it up so that the Task sends exactly 1 byte per 500 microseconds (~300 "on" and ~200 "off). This way, if an interrupt message comes in, it will be guaranteed to be received less than 1 ms after occurring.
What is currently work is this: a function on the CPU that takes incoming bytes (one at a time) and adds them to a CPU2CLA buffer and increments a CPU2CLA length counter. Each time Task2 is run, it checks this queue and grabs one byte from the front of a CLAonly buffer, increases its own buffer length, and flags that a byte was consumed. When the Task2 CPU ISR is run, it will check if a byte was consumed, and remove the first-most byte from the CPU2CLA buffer. Currently this double buffer system doesn't have a flag for add to front, so it doesn't take care of the interrupt case.
What I tried previously was to have a Task3 which took one byte that was passed CPU2CLA and run it from the CPU with a Task3andWait. Although this method should in theory take care of both requirements, about half of the time a byte or two of a message would never get transmitted (a single byte always got sent).