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.

TMS320F28335: DMA usage

Genius 12760 points
Part Number: TMS320F28335

The objective I have, is to transfer packets of 8 ADC values by the DMA to a cyclical buffer e.g. of length 1024. The data transfer to the cyclical buffer should be able to stop at any place of whole 8 ADC values and be rerouted to a second Buffer to be filled cyclically.

I tried using BURST_SIZE  of 8 (16bit values) and TRANSFER_SIZE of 128 Bursts (8*128=1024). When I want to switch the buffer I changed the SRC_BEG_ADDR_SHADOW and the SRC_ADDR_SHADOW. And since these get read only when the TRANSFER_COUNT is zero I wrote “zero” to the TRANSFER_COUNT. Unfortunately I noticed that the value I wrote to TRANSFER_COUNT was ignored, though stated as R/W value in documentation. So the DMA always continued writing until the end of the buffer before switching. Which is not as desired.

Do you have some advice how this can be done?

Regards,
Bernd

  • Hi Bernd,

    looking at the DMA state diagram, writing 0 to TRANSFER_COUNT should work.
    Have you used the EALLOW instruction before writing to the TRANSFER_COUNT register?
    All DMA register writes are EALLOW protected.

    Regards,
    Andy

  • Bernd,

    In addition to what Andy said,  You could just keep the Shadow address(I think you meant DST_ADDR_SHADOW vs SRC) pre-loaded waiting for either all the transfers to complete or the SW to manually set TRANSFER_COUNT=0; assuming the next buffer address would always be known ahead of time(usually there are just 2, but that might not be the case here, not sure).

    This is an interesting case, usually we have a ping/pong buffer that just fills each time with the total number of words, and this lets the DMA ISR/autoload to most of the work.  It looks like form above there may be some reason to stop it pre-maturely, but as you said on a 8 word boundary.  I'm not sure we've tried this before, but it looks like it should work based on the documentation.

    Lastly, just thinking out loud a bit, maybe we want to check both the transfer_count value before writing a 0; if it is at "1" I would just let it complete the full transfer, vs trying to end the transfer 1 burst early.  I'm not completely sure what would happen if DMA tried to decrement "0" if you somehow wrote to it after the 0 check happened but before it decremented the counter.  Just a thought.

    Best,
    Matthew

  • Hi Matthew,

    to write to the TRANSFER_COUNT register I used the EALLOW  Instruction. I just tested it again and the value I write to the TRANSFER_COUNT  gets ignored and the TRANSFER_COUNT  continues to decrement as usual.

    I also noticed that the TRANSFER_COUNT  in Chanel 1 starts counting at one less than TRANSFER_SIZE and has two Burst long the value zero so the total number of Bursts is indeed TRANSFER_SIZE but Chanel2 does count the right was. This makes it complicated though to find out where the most recently written samples are.

    As a workaround since I did not manage to change the TRANSFER_COUNT I used two DMA channels so each channel has its own fixed buffer and when I stop the first one so I can process the data, I start the second one instead and vice versa.

    It seems the approach I chose is not so common. I am trying to build a data capture similar to an osciloscope. I want to record a fixed number of samples when a trigger is found and I also want to keep a certain amount of pretrigger samples.

    When this Event got recorded I want the data to be available until it get processed. The data capture though should continue on a second buffer without interruption.

    Do you have some examples of such applications?

    Best regard,

    Joseph

  • Joseph,

    Thanks for the background on what you are trying to do.  I need to spend some time to see if there is an elegant solution. 

    I should have tried this myself before replying back in the affirmative; I suspect there is an error in the TRM that the _count registers are not writable.  This is going to get loaded by the DMA with the transfer_size -1 at the start of the DMA process, I don't think we envisioned needing to allow CPU writes.

    Let me see what I can come up with and will get back to you.

    Best,
    Matthew

  • Joseph,

    I tried to halt the DMA to see if in that state Transfer Count could be overwritten, but that does not allow writes either.  I think your current option will be the best way to proceed moving forward.

    Best,

    Matthew