This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

TM4C123 ADC Burst Sampling - how to use uDMA



Afternoon All!

Hopefully someone will find this useful....

Whilst working on some code to try to capture a burst of ADC values (in this case 1024 conversions) I was getting confused by the datasheet and it sent me down an effective, but overly complex route.

The "issue" is that the maximum number of Sample Sequencer entries is 8 - so no matter what you do, once you have 8 samples you have to deal with them. Using an ISR would require 125,000 interrupts per second which is not ideal so the uDMA seemed like the obvious choice. The modes appeared to be thus : BASIC would do an ARB sized transfer so maximum 8 unless the request doesn't go away (but it will), AUTO would do the full transfer but might underflow the FIFO so no good, PING-PONG will do 8 at a time so still no better than BASIC (but might guarantee no FIFO overflow), MEM-SCATTER-GATHER would do the whole lot in one go and hence may underflow the FIFO and PER-SCATTER-GATHER would work but is quite wasteful - you use as many bytes of task table as you get samples (ADC values are 12 bit so you can move chunks of 16 bits) - you could overwrite the task list saving memory but then you need to re-build it every time.

I initially tried PER-SCATTER-GATHER and being sneaky to save memory, setting the Primary ARB size to 1 item of 32 bits to load a new control word - that wouldn't work since the destination address is not updated by the uDMA core so would just overwrite the same data. I tried an ARB size of 2 to move a new destination and control word in - that didn't work and I now think that maybe it can (the uDMA controller expected a 4 word primary transfer regardless of what ARB size and item count you set, so seems to hard-decrement the primary destination end address by 4 words for the primary destination start address - to shift only alternate destination and control word you need to bump up the primary destination end address to align primary destination end minus 4 words with the alternate destination address location). A full task list worked just fine but was wasteful... still, one interrupt for 1024 samples was definitely a move in the right direction!

Re-reading the datasheet, I noticed that the description of BASIC mode says that it will transfer only an ARB sized chunk if the request "goes away", so you shouldn't use it with software triggered DMA. It seemed to suggest that it will try to re-arbitrate if the request hasn't "gone away" so I wondered, would it do so if it "went away but then came back". It appears that YES, it will do that - the word "BASIC" doesn't seem to do that mode justice. When the uDMA drains the ADC FIFO the DMA request goes away, but when the FIFO is full again, it comes back. At that point, if the total number of items has not been transferred it will re-arbitrate and it will do another ARB sized chunk, ergo you can set up a bulk transfer by just putting in a bigger number of items. I do seem to be getting 1024 results.

One catch might be FIFO overflow - if it takes the uDMA more than 1 microsecond to gain control of the bus, and to read out the first entry from the FIFO, then the ADC could overflow the FIFO. The solution to this would be to set the IE bit on entry #3 and entry #7 and an ARB size of 4, so you are only ever draining half the FIFO, thus buying another 4 microseconds.

To start and stop sampling, enable and disable the sequencer. Do not switch an enabled sequencer from TRIGGER_PROCESSOR to TRIGGER_ALWAYS and back, it won't stop sampling properly if you do - you need to disable a sequencer to get out of ALWAYS mode on TM4C123. Of course you could trigger off something else, but whatever it is, it must not "go away" (so, maybe level-triggered GPIO) otherwise sampling will stop again.

Best regards,

Pat.