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.

TMS570LS2134 DMA Port Assignment Registers

Hi there,

I'm having difficulty to understand when to assign a given DMA channel to Port B. The description of the PAR0 and PAR1 register state that only 0x4 (or 0x5 or 0x6 or 0x7 because of the no care bits) can be set (to use Port B) for a given DMA channel, so for my DMA channels from 0 to 7, and 15, I set PAR0=0x77777777 and PAR1=0x00000007, but DMA channel 15 no longer works!

Under this no-working condition, I've observed DMAGCTRL.BUS_BUSY=1, reading its description refer me to some AHB thing that I don't fully understand (bus contention/collision or something).

If I set PAR0=0x77770000, channel 15 is working again and BUS_BUSY is 0.

What is the logic and is there any limitation as on how many channels can use Port B? Port A is apparently unavailable for this MCU.

Can anyone shed some light please?

Thanks!

  • Hi Chuck,

    I have forwarded your question to one of our DMA experts. They should get back with you shortly.

  • Hi Chuck, 

      I will need to run some test and also look at the RTL design before answering your question. I will get back to you tomorrow. I'm surprised that if you don't set channel15 to portB and the transfer will still complete for that channel. Can you also tell me for arbitration scheme you choose? Is it fixed or round robin? In your non working scenario if you change the arbitration scheme do you see different result.? The BUSY flag is saying that the slave module from which the DMA is reading from or writing to is not yet replying a response. Can you also tell when channel15 is not complete are you seeing any errors in the ESM. What are the various DMA interrupt flags showing for channel15?

  • Hi Charles,

    I'm sorry if my description was not clear ... The DMA channel 15 is always set to 0x7 for Port B using PAR1 register, this was not changed throughout my tests. What I've changed were channels 4, 5, 6 and 7 using PAR0 register. Each channel location is mapped in a somewhat "reversed" order with according to the TRM 499n. :-)

    Channel 15 is configured to received DMA request line #13 from RTI event #1, to trigger transfer of 2 MB of Flash ROM to the CRC module for CRC compression in semi-automatic mode, with 64-bit transfers. At the end of the compression, I should receive a Compression Completed interrupt so I can check the computed CRC against the pre-stored CRC for error. This has always worked until I changed PAR0=0x77770000 to PAR0=0x77777777. DMA channels 4, 5, 6 and 7 are new to the design and my guess was that every DMA should use Port B.

    Thanks for helping!

    Chuck.

  • Hi Chuck,

      Thanks. Now I'm clear on your problem. What  transfers are you making with channel 4,5,6,7? Are you transferring a lot of data with these new channels? Are you in fixed arbitration scheme? How often do you generate RTI trigger to channel 15? For channel 15 are you dividing the 2MB into multiple frames using frame trigger?   Is channel 15 partially transferred or completely un-transferred? the reason I'm asking these questions is because I want know if it is possible that the RTI trigger comes too quickly before DMA can service channel15. If you are in fixed priority and you add several new channels then the DMA will service these higher priority channels first. In the meantime you may have generated more than one RTI trigger to channel15. DMA at most can buffer two triggers per channel. If you have more than that then the new triggers will be lost.

  • Sorry Charles, edited in red.

    Hi Charles,

    MCU is clocked by the PLL at 120 MHz, while the VCLK bus is 60 MHz.

    Channel 15 is triggered only once every 60 seconds. The first trig happens 100ms after power-up. So I don't think that it is too frequent even though the buffer to be transferred is quite large. It is set to transfer some 8192 frames of 32 elements of 64 bits each. Channel 15 is not starting at all (with help of the debugger in breakpoint mode), while the RTI has indicated that the proper event #1 DMA has been generated.

    Channels 0 and 1 continue to work fine with both setups. Channel 2 is called the quickest every 0.5 ms to transfer 256 words of 16 bits from memory to memory. Upon BTC (block transfer completed), channel 3 (you didn't ask for this one) is triggered every 0.5 ms to transfer 64 words of 32-bit to MibSPI5 TXRAM locations [0..63], while channel 4 is also triggered every 0.5 ms to transfer the subsequent 64 words of 32-bit to MibSPI5 TXRAM locations [64..127]. The MibSPI5 is configured in slave mode but the SPI master is not yet connected (no SCLK), so channels 5 and 6 should not be triggered to read MibSPI5 RXRAM locations [0..63] and [64..127], respectively. Channel 7 also shouldn't be triggered since it is used only when channel 6 has completed its 128 words receiving (BTC), but should never happen for the same reason.

    I didn't change the default priority scheme of the DMA module, so lower channels numbers have higher priorities. Channel 15 has the lowest priority.

    Hope that my configuration is now clearer!

  • HI Chuck,

      Can you please send me a screenshot of all the DMA registers? I want to know how you setup the new channels. Also I'd like to know if channel 15 is pending in the PEND register. Are there any errors getting generated? Can you please check if any errors in the ESM module? I wonder if channel 15 is somehow disabled. Also by any chance the control packet for channel 15 was ever changed after channel 15 has already become pending. Changing the control packet after the channel is pending will disable the channel.

     One experiment I'd like you to try is to move channel 15 to high priority queue by setting bit15 of the CHPRIOS register. This will separate channel 15 into a different queue (high queue) from the rest of the channels. You can keep everything else the same. I want to know if this will change anything.

      Since the introduction of new channels 4,5,6,7 causes channel 15 not to transfer, we may need to understand the setup of these new channels. Channel 3 and 4 are periodically triggered every 0.5ms for MIBSPI5 TXRAM transfer. Even MIBSPI5 does not receive any data in its RXRAM (as you indicated that the SPI master is not yet conneted) to subsequently trigger channel 5 and 6, the channel 3 and 4 triggers will still happen periodically. Is this how you set it up? The problem I see is that the TXRAM for MIBSPI5 is getting over-written every 0.5ms but the RXRAM may not have received any data as long as the external SPI master is not transmitting.

  • Charles,

    Your description in your last paragraph is correct on my case with the actual setup, channels 3 and 4 are triggered every 500 us without any effect on channels 5 and 6, as yet.

    I think that my statement on setting PAR0=0x77770000 to make channel 15 works is perhaps wrong, as I can't reproduce what I saw yesterday, I apology. Channel 15 is not working even when I change PAR0 in the debugger window now. I'm trying to see what has happened since yesterday.

    Please find snapshot of DMA and ESM registers below. No ESM error has been detected since breakpoint inside ESM_HIGH and ESM_LOW ISRs are not encountered. I didn't enable all ESM detections though ...

  • Hi Charles,

    If I put within the IAR debugger PAR0=0x00000000 while PAR1=0x00000007, channel 15 starts to work again, every 60 seconds.

    Any clue?

    Thanks!

  • Charles,

    With try and error, I've discovered that the no go for channel 15 is caused by channel 3, so as soon as I set the DMAPAR0=0x77707777, the PEND for channel 15 is cleared and get serviced.

    Below is the initialization code for channel 3, which is configured to respond to MibSPI5 DMA source 0 or SW triggered by written DMASWCHENAS=0x00000008.

    Do you see any problem?

        // ------------------------------------------------------------------------
        // configure DMA channel 3 for MibSPI5 device request source 0 or SW trigger when DMASWCHENAS set to 0x00000008
        // transfer application TXRAM buffer to MibSPI5 TXRAM (part 1)
        // ------------------------------------------------------------------------

        DMACP3ISADDR    = CPULINK.GetTxBufCpuBase();    // point to application TXRAM buffer start address
        DMACP3IDADDR    = (u32) &MIBSPI5_TXBUF_BASE;    // point to MibSPI5 TG0 TXRAM start address

        DMACP3ITCOUNT   = 0x00020040;           // frame transfer=2, element transfer=64
        DMACP3CHCTRL    = 0x0000A00A;           // RD/WR size: 32 bits, transfer type is one frame
                                                // RD/WR mode: post increment
                                                // auto-initiation disabled

        DMACP3EIOFF     = 0x00000000;           // element index address offset
        DMACP3FIOFF     = 0x00000040;           // frame index address offset

    Thanks!

  • Well sorry Charles,

    It might be just luck! I used the IAR debugger to change the value of DMAPAR0, and I might see that changing Port B usage for channels 2, 3 OR 4 can unlock channel 15, but not always with the same channel, but one of them surely does the trick. It let me believe that it just random and depend on where the DMA is ...

    So I set the DMAPAR0=0x77000777 in my code and upload again, and it works every time, so the problem must be one of the channels 2, 3 and 4 ...

    Where should I look next?

    Thanks.

  • Hello Chuck,

      Quickly glance through your screenshot. Here is my observation:

      1. You map DMA request 31 to both channel 3 and 5. DMA request line 31 is an OR of requests from MIBSPI1, MIBSPI3, SCI and MIBSPI5. Is this your intended mapping? Is this possible that you are using MIBSPI3 and causes the MIBSPI3 DMA request to trigger onto channels 3 and 5 which are for MIBSPI5.

      2. You map DMA request 30 to both channel 4 and 6. DMA request line 30 is an OR of requests from MIBsPI1, MIBSPI3, SCI and MIBSPI5. Same question as above.

      3. I see that channels 0,1,2,3,4,13,15 are pending. This means that DMA requests for these channels have arrived.

      4. I see that for channel 3 and 4 that you enable both the hardware enable (HWCHENA) and software enable (SWCHENA). Is this intended to provide software trigger and hardware trigger onto these two channels? You said that channel 3 and 4 are triggered every 0.5ms. Are you using the CPU to generate a software triggers to these two channels every 0.5ms? If so, why are you enabling HWCHENA for these two channels? If there is a DMA request from MIBSPI3 then it can also trigger channel 3 and 4.

      5. Looking at the Working control packet I see some activities on channels 2,3,4,5,6. Since these happen every 0.5ms they may have taken up DMA's bandwidth meaning that DMA is unable to service channel 15 when higher priority channels keep coming in. One experiment to try to is to increase the time from 0.5ms to some longer time. Or the other experiment I suggested before to move channel 15 to the high priority queue.

  • Charles,

    Please see my answers and clarifications below:

    Channel 2 is generated every 0.5 ms by SW. Upon DMA BTC of channel 2, channels 3 and 4 are triggered by SW within ISR to transfer ONLY the first 64 words into each MibSPI5 segment, [0..63] and [64..127]. Since no master SPI is connected, the cycle ends there and the next DMA is from channel 2 again, and overwrite data in MibSPI TXRAM. In the real implementation, channels 3 and 4 would be triggered again by HW (DMA requests 30 and 31) once MibSPI5 RXRAM locations 63 and 127 are written, to transfer the next 64 words on each channel.

    1. This is my intended mapping. Only DMA request from MibSPI5[0] (i.e. source line 0) was enabled, all other are disabled.
    2. Same as above.
    3. Yes. But since the pending bits are set, I believe that the DMA is simply not working at all under this condition. BUS_BUSY was set so the whole DMA was halted. Why???
    4. MibSPI3 could not trigger channels 3 and 4. See my clarifications and answer to point (1) above.
    5. I'll try lowering down the frequency and see.

    Thanks!

  • Charles,

    Newest findings: I've commented out the SW activation of CH2, CH3 and CH4, but let along DMAPAR=0x77777777. Guess what, channel 15 not working either. BUS_BUSY remains set!

    As soon as put DMAPAR0=0x77000777, channel 15 is serviced.

    So it doesn't work even when no more DMA is generated from CH2, CH3 and CH4 ... now I'm totally lost!

    Please help!

  • Hi Chuck,

      When you comment out the SW activation on CH2,3,4 do you still see the PEND register active for these three channels?  What do the various interrupt flags indicate for these three channels when you said you disable them.

  • As soon as I set DMAPAR0=0x77777777 in the debugger, BUS_BUSY change to 1.

    Not sure why PEND13=1 the whole time but it is not enabled for HW triggering. Below are the DMA channels used in my application:

    Request Device

    Device Request Source

    DMA Request Line

    DMA Channel

    MIBSPI1

    0

    REQ[1]

    CH00

    MIBSPI3

    0

    REQ[15]

    CH01

    SW

    CH02

    MIBSPI5/ SW

    0/

    SW

    REQ[31]/

    CH03

    MIBSPI5/ SW

    1/

    SW

    REQ[30]/

    CH04

    MIBSPI5

    0

    REQ[31]

    CH05

    MIBSPI5

    1

    REQ[30]

    CH06

    SW

    CH07

    RTI

    Event1

    REQ[13]

    CH15

    Here is the initialization code:

    // ------------------------------------------------------------------------
        // global configuration for all used DMA channels
        // ------------------------------------------------------------------------

        DMAGCTRL        = 0x00000000;           // disable all DMA functions
        DMAHWCHENAS     = 0x0000807B;           // enable channels 0, 1, 3, 4, 5, 6 and 15 for HW

        DMADREQASI0_bit.CH0ASI  = 1;            // channel  0: request line #1  from MibSPI1 source 0
        DMADREQASI0_bit.CH1ASI  = 15;           // channel  1: request line #15 from MibSPI3 source 0
        DMADREQASI0_bit.CH3ASI  = 31;           // channel  3: request line #31 from MibSPI5 source 0
        DMADREQASI1_bit.CH4ASI  = 30;           // channel  4: request line #30 from MibSPI5 source 1
        DMADREQASI1_bit.CH5ASI  = 31;           // channel  5: request line #31 from MibSPI5 source 0
        DMADREQASI1_bit.CH6ASI  = 30;           // channel  6: request line #30 from MibSPI5 source 1
        DMADREQASI3_bit.CH15ASI = 13;           // channel 15: request line #13 from RTI event1

        DMAPAR0         = 0x77777777;           // channels 0, 1, 2, 3, 4, 5, 6, 7: use DMA Port B
        DMAPAR1         = 0x00000007;           // channel 15: use DMA Port B
        DMAPCR          = 0x0000000A;           // enable parity check

    Anything that you can see problematic?

  • Hi Charles,

    Like I said, as soon as I set DMAPAR0=0x77777777 in the debugger, BUS_BUSY change to 1, on the very [ENTER] of this register change. I don't even have to continue [GO] execution then break it again.

    It must be something here that affect the DMA module ...

    What do you think?

  • More precisely, I've stepped through the code, I've noticed that after DMA and MibSPI5 initialization, no problem even with DMAPAR0=0x77777777, BUS_BUSY remain at 0.

    BUS_BUSY get set only after executing this line of code:

        DMASWCHENAS = 0x00000004;       // trigger DMA CH2 to duplicate working copy message

    Snapshot before execution of the above line:

    After execution of the above line:

    Registers changed are in red.

  • Hello Chuck,

      I will try to see if I can create a testcase to mimic your setup and see if I can reproduce the same. In the meantime, can you try to disable the HWCHENA for channel 2 so that only SWCHENA is enabled for this channel and let me know what happen.

  • Charles,

    I've cleared all DMAHWCHENANAS=0x00000000 and stepped with the same manner, same result for BUS_BUSY=1 as soon as DMASWCHENAS=0x00000004 was executed.

    Thanks.

  • Hi Chuck,

      Looking at the control packet for channel 2 again I see that you have the AIM bit set. Since you first use the s/w trigger to start channel 2, this means that even after channel 2 block is complete it will automatically retrigger itself. As channel 2 has higher priority than channel 15 it can starve channel 15 from gettnig service. Take out the AIM bit and let me know it it makes a difference.

  • Hi Chuck,

      Our posts cross each other. Please look at my last reply to disable AIM bit. With the AIM bit set and s/w trigger, it will continue the block transfer non-stopped. Please give a try and let me know if it makes a difference.

  • Kudo Charles,

    Yes it seems that AIM is the culprit!

    Does this mean that SW triggered should never use AIM=1?

    If so how about those hybrid DMA, first use SW trigger to initiate the first frame, then wait for HW trigger to continue the rest? This is the case for my DMA channels 3 and 4, as you can see.

    Thanks for your great support.

  • Hi Chuck,

      I'm glad we identifiy the culprit. Don't get me wrong. This is not a bug but as an intended feature. You can mix the hardware trigger and s/w trigger like you do today. It will not be a problem. The s/w trigger will kickoff the first block transfer and the subsequent block transfers will be triggered by your hardware request coming from MIBSPI5. But make sure the AIM bit is disabled or otherwise, the DMA will not wait for the hardware trigger but rather keep continuing as soon as a block is complete. Please let me know if you have other questions.

     

     

  • Charles,

    I'm just wondering under what circumstance should we use AIM=1? Since it auto-retriggers after each run, it will take all the DMA bandwidth, isn't it?

    Only higher priority DMA can interrupt those SW triggered DMA with AIM=1. Am I correct?

    Thanks!

  • Hi Chuck,

      You are right. There are three ways to interrupt this s/w triggered channel with AIM=1.

      1. Higher priority channels in the same queue.

       2. You setup up two different priority queue. This was what I sgugested you to do earlier by assigning ch15 to high priority queue. DMA will service high priority queue first before servicing low priority queue. By default, all channels are assigned to low priority queue.

       3. You setup round-robin arbitration scheme which is what I also suggested earlier for your to try. With R-R, every channel gets a chance for a transfer. With fixed priority, channel 2 is forever higher priority than channel 15. Since channel 2 is re-triggered, channel 15 is not getting serviced.

  • Charles,

    I'm having other issues ... what could prevent from setting the DMAHWCHENAS register?

    In my initialization code, I set this register to 0x0000807B to include the enabling of DMA CH0 and CH1, it works fine during maybe a couple of times, then BTC from these channels stops from generating, I break it out then I've observed that DMAHWCHENAS becames 0x00008078, which means DMA CH0 and CH1 are disabled. I have ONLY one single place in my code to set this to 0x0000807B.

    As a consequence, DMAPEND for CH0 and CH1 are set but not been serviced. If I forced to change HWCHENA0 and HWCHENA1 to 1, their respective PEND bit get clear but HWCHENA0 and HWCHENA1 will reset to 0 immediately, then the next thing is the program pointer reached the "Undefined_Handler" at 0xf2a4.

    Where should I start looking?

    Thanks again for your continuous support.

  • Hi Chuck,

      The HWCHENA is automatically cleared at the end of a block transfer. Think about you want to transfer a block of data using a hardware request from a peripheral, i.e. the MIBSPI. Once the block transfer is complete, the CPU may want to process these data but the MIBSPI may continue to generate the hardware DMA request as soon as it receives another serial data. The way to prevent this is to disable the DMA channel and let the user decide when the next block of data can take place by re-enabling the channel. MIBSPI may not be the best example because I think it can be setup for oneshot DMA request generation. But for other peripherals not as smart in this regard like NHET or RTI where the request is generated periodically you might want to stop new data from coming in so you can process the existing transferred data first.

  • Thanks Charles,

    I'm not sure understand it.

    The intend purpose in my setup is that the RTI generates periodically a request to start an ISR, within which a MIBSPI transfer group (TG) is triggered to send words to MIBSPI TXRAM, at the end of its to call the DMA for copy MIBSPI RXRAM data to local buffer. After DMA has finished its transfer, the BTC interrupt is generated.

    It works once and I can see the HWCHENA was cleared after one block, which is fine according to your explanation. However, any attempt to re-enable the associated HWCHENA, such as just before or after trigger a new TG transfer, leads to "Undefined_Handler" and halts.

    If I don't re-enable HWCHENA, it works only once but at least all the rest are still working (not halted).

    Where should I re-enable the HWCHENA then?

    Thanks!

  • Hi Chuck,

      At the moment I can not relate the action of writing HWCHENA and underfined instruction decoded by the CPU. CPU must have executed an undefined instruction to take the undefined trap. Can you examine the instruction that causes the undefined? Are you somehow running code from RAM and the RAM content was corrupted by the DMA transfer?

  • Hi Charles,

    No, the code is not running from the RAM. I have to check for boundary issues in order to isolate the problem.

    Good weekend!

  • Charles,

    If a given block transfer is divided into many frames, and the first frame is to be triggered by SW, then subsequent transfers by HW until completion, I should set AIM=1 because the SW will not auto-initiated the DMA channel again since it has transferred only one frame (not one block).

    At the end of the last frame initiated by HW, the first frame can only be triggered again by SW later in the code, given that no other HW triggers will arise.

    Is my understanding correct?

    Thanks!

  • Hi Chuck,

      I don't think AIM=1 will work if the trigger type is frame trigger. I think if you are dividing the block into multiple frames, you can use the s/w to start the first frame and use the h/w request to trigger the subsequent frames without using the AIM. Can you try this?

  • Hi Charles,

    If AIM=0, the corresponding HWENAS bit will be cleared at the end of 1 block transfer, either by SW trigger or HW trigger. To put the HWENAS bit back, from what I know I have to put the DMAGCTRL register in the reset state before turning the bit on again, which is unlikely the best way to do it given there might be other DMAs in operation.

    That must be other way to achieve this. Can you point me to it?

    Thanks.

  • Hi Chuck,

      There is no need to globally diable DMA in order to enable the HWCHENA bits. HWCHENA is a enable bit for the channel. Hardware requests which might have been generated will be captured even if the HWCHENA is disabled. This will show up the channel is pending. Soon as the channel is enabled, the channel will be serviced according to the configured priority. Please give a try.

  • Thanks Charles,

    That makes sense, I'll try that once I get the hardware on hands. I'm current using the TI TMS570 HDK.

    A question regarding the MibSPI operation, if you think that I should start a new thread, please let me know. Thanks in advance.

    Let say I have a 256-words BUFFER[0..255] that I want to transmitted by MibSPI using DMA. Since the MibSPI TXRAM size if only 128 words, I have to set it up as follow:

    1. Configure MibSPI TG0 range to be from TXRAM[0..127]
    2. Configure and start DMA CH3 to write first frame BUFFER[0..63] to TXRAM[0..63]
    3. Configure and start DMA CH4 to write first frame BUFFER[64..127] to TXRAM[64..127]
    4. Start MibSPI TG0 transfers
    5. When BUFID reaches RXRAM[63], trigger again CH3 to write second frame BUFFER[128..191] to TXRAM[0..63]
    6. When BUFID reaches RXRAM[127], trigger again CH4 to write second frame BUFFER[192..255] to TXRAM[64..127]
    7. To signal the end of the 256-words block transfer, generate DMA Block Transfer Completion (BTC) interrupt when BUFID is reaching the second time RXRAM[127].

    Therefore for both DMA CH3 and CH4, they each have 2 frames of 64 words each and naturally I use post-increment addressing mode for both channels.

    For the source pointer that is pointing to the application BUFFER[], I setup a source address frame index offset of 64, so after the first frame, it will jump to element BUFFER[128] for CH3 and element BUFFER[192] for CH4, no problem here.

    What I cannot understand is what will happen to both post-increment write pointers pointing MibSPI TXRAM[] after the first frame on each channel was transferred. I must be wrong but I see the following, on the second frame:

    • DMA CH3 write pointer will start at TXRAM[64] thus overwriting the region reserved for DMA CH4.
    • DMA CH4 write pointer will start at TXRAM[127]+1 thus overwriting the region the is outside of the MibSPI TXRAM.

    Is my DMA scheme having a problem? How this is supposed to work?

    Thanks for your continuous support.

  • Hi Chuck,

      I think your source address frame index offset may be a problem. What is the size of the source pointer? Is it 8 bit or 16-bit? I will think the buffer array is of type uint16, right? I think the element index should be 2 and the frame index should be 128. What do you use?

  • Hi Charles,

    The element size of the source/destination pointer is 32-bit, both RD/WR, since the MibSPI TXRAM is of 32 bits large.

    The buffer array is also of 32 bits large, matching the MibSPI TXRAM size.

    Because of 32-bit size buffer and destination, element index is therefore 0 and frame index is only 64.

    Do you still see a problem in my scheme?

    Thanks.

  • Hi Chuck,

      The DMA UserGuide has the below statement in section "Element/Frame Index Pointer".

    The DMA controller does not adjust the element/frame index number according to the element size. An index of 2 means increment the address by 2 and not by 16 when the element size is 64 bits.

      So element size of 0 will transfer data from BUFFER[0] and fill the entire first 64 words of the TXRAM. Is this what you are seeing?

      If your BUFFER array  is of 32bit then CH3/4 element index should be 4 and frame index should be 512. The starting source address for CH3 is &BUFFER[0] and the starting source address for CH4 is &BUFFER[64].

  • Thank you Charles,

    Hmmm, I think that you point me to something that I might have missed...

    Not having my setup at this time, but in my memory with another working DMA configuration, I think that it does fill the entire 64 words of the TXRAM when the TG is triggered, however with all source/destination element/frame address indexes offsets of 0. So my feeling is that the DMA controller does not require me to setup the those offset registers if copying same size of data from source to destination.

    On another hand, for example, if the source/destination element size are both 32-bit large but source/destination addressing mode is only 16 bits (let say because the other 16-bit will not change), then source and destination element address index offsets would have to be set to 2 bytes, offset that is to be added after each element transfer. Same for the frame address index offsets. Please correct me if I'm wrong.

    This being said and with your explanation in mind, I think that your last statement should have both source/destination element indexes set to 0 (no effect since both are 32-bit large), and only source frame index set to 64 x 32-bit (or 4-byte) = 256 (applied after first frame transfer).

    In layman's terms, after CH3 has copied BUFFER[0..63] to TXRAM[0..63], add 256 bytes to the sources index so on next frame transfer, it would take BUFFER[128..191] to TXRAM[0..63]. As for CH4, it will do the same by copying BUFFER[64..127] to TXRAM[64..127] on the first frame, then BUFFER[192..255] to TXRAM[64..127].

    If I still stand correct, then I have to setup for DMA CH3 and CH4 with 2 frames of 64 words each for the complete block of 256 source elements. My question really is what is the MibSPI TG mechanism to allow the destination pointers to return to &TXRAM[0] and &TXRAM[64] at the beginning of the second frame, from the last write to TXRAM[63] and TXRAM[127] respectively?

  • Hi Chuck,

      when you are in indexing address mode, the user must provide the correct oofset address. DMA does not adjust the address by taking into account the size of the transfer. With your example where the element size is 32bit, you need to give the element index of 4, not 2. If you give the index of 2 but the transfer size of 32bit, it becomes an unaligned access. There are some examples in the DMA userguide. Please take a look. You'r understanding of using 256 as the frame index is actually correct.

      For your next question about returning the destination pointer back to &TXRAM[0] I think you will need to use chaining feature. The way it is setup right now, once CH3 finishes the first frame, the destination pointer is pointing to TXRAM[63]. DMA will not reset the destination pointer to TXRAM[0] again. With chaining this is how it will work. Setup CH3 with only one frame of 64 elements. Chain CH3 to a new channel, say CH5. In CH5 you will setup also 64 elements and one frame But the starting address will point to BUFFER[128] and destination starting address points to &TXRAM[0]. 

  • Hi Charles,

    I really appreciate your prompt support, as this truly helps me advancing in my debugging process. :)

    I'm pretty sure that if both source and destination buffers and transfer size are 32-bit, it is not required to specify element index, otherwise it would be redundant as the DMA controller knows already the transfer size. My previous example uses an element index of 2 is for the case of a buffer size of 32 bits but transfer size of 16 bits.

    To your response of my destination pointer reset to [0] question, after I ran into problem, I've exactly considered your suggested scheme but use BUFID DMA trigger instead of DMA chaining, because chaining would overwrite previous data that haven't yet been transmitted.

    However, I would expect that there is another way to do this without using additional DMAs, given that we have only 15 channels, they will be used up very quickly with a larger block to transfer. In fact, given that the MibSPI TXRAM is only 128 words large, if using 2 DMAs to fill the whole TXRAM (64 words each), then I would only be able to transfer up to 128 words x 15/2 = 960 words, while the TRM states that we can go all the way to 65535 elements by using LARGE_COUNT and DMAxCOUNT register. So that must be a mean to use one single DMA for such purpose.

    I really need your help. Can you please look into it while I'm also working at my end?

    Very best regards!

  • Well Charles,

    After reading in the TRM that both source/destination address index offset registers are XXXXX or not specified after RESET, I'm not so sure about my understanding now. It seems that they must be set under any condition.

    If you were right on element index interpretation, if SOURCE BUFFER ELEMENT SIZE is 32 bits, transfer size is 8-bit, what its index should be? Also 4?

    Please confirm!

  • Hi Chuck,

      What is the end result of the transfer that you expect? If the BUFFER array is of 32bit type and the transfer size is 8 bit then 3 bytes of each buffer word will not be transferred if you use index of 4. If you use index of 1 then all 4 bytes of each 32-bit buffer word will be transferred.

  • Morning Charles,

    I understand now. Index offsets are NOT used in post-increment modes. I earlier have mixed up between DMA post-increment mode and index mode. You were correct all along and sorry about that.

    My concern is now on how to streamline a block of 2 DMA frames writes to the same destination address range, without using additional DMAs (please see my previous posts). I have found the following in the TRM for the DMAxCOUNT register, and will be study it. If you have any additional tips on what I want to achieve, please advise!

    Thanks!

    Note: Usage Tip for Block Transfer Using a Single DMA Request. It is possible to use the multi-buffer RAM to transfer chunks of data to/from an external SPI. A DMA Controller can be used to handle the data in bursts. Suppose a chunk of 64 bytes of data needs to be transferred and a single DMA request needs to be generated at the end of transferring the 64 bytes. This can be easily achieved by configuring a TG register for the 64 buffer locations and using the DMAxCTRL/DMAxCOUNT registers to configure the last buffer (64th) of the TG as the BUFID and enable RXDMA (NOBRK = 0). At the end of the transfer of the 64th buffer, a DMA request will be generated on the selected DMA request channel. The DMA controller can do a burst read of all 64 bytes from RXRAM and/or then do a burst write to all 64 bytes to the TXRAM for the next chunk.

  • Chuck Wong said:
    My concern is now on how to streamline a block of 2 DMA frames writes to the same destination address range, without using additional DMAs (please see my previous posts).

    I think that I can answer my own question: the DMA WRITE mode should be set to INDEXED (0x3) and the destination address index offset should be set to 0, so no adding is performed to the original destination address after one frame transfer.

  • Hi Chuck,

      That will actually work. I keep thinking about either using chaining mode for which takes up additional DMA channel or thinking in the direction of using only one DMA frame with AIM=1. However, you will be writing the same 64 words source to the  MiBSPI TG the next DMA request unless you change source address in the CP while in ISR. Your idea solves the problem. Thanks.