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.

DMA transfer count



Hello,

I am using McBSP unit configured for SPI together with two DMA units to communicate between two F28335s. One DMA fills TX register (when empty) and the other empties RX register (when full). DMAs on SPI master are in non-continuous mode and are enabled periodically by the application. The slave's DMAs are running continuously. Size of DMA transfer equals number of 16-bit words I'm exchanging, one word in a burst.

I have a problem in understanding what is happening on the slave side. After one set of SPI transactions is over, i.e. after master's DMAs have finished their transfers, I am expecting the following situation on the slave:

  • McBSP TX buffer is empty after the last transaction
  • this condition triggers one burst of the "sending" DMA
  • the "sending" DMA's transfer count equals transfer size - 1
  • the "receiving" DMA has't been triggered yet and its' transfer count is zero

However, I observed that in the above situation the "sending" DMA's transfer count equals transfer size - 2. How is this possible?

Regards,

Josip

  • Josip,

    Is it possible that the slave McBSP TX Buffer is empty when you first enable it (before the master sends any data)? I'm not positive but this might trigger the slave "sending" DMA burst once prior to the master initiating the first set of the transfers. Then after the first set, when the slave "sending" DMA is triggered, it is the second time, not the first.

    Regards,
    Dave Foley

     

  • David,

    I think that is exactly what is happening, but it still doesn't explain the observed behavior. I think the sequence should look something like:

    1. Slave DMAs (sending and receiving) transfer sizes are initiated to N_size and they are both enabled.

    2. Slave McBSP TX register is empty, so a burst is triggered. Transfer count is initialized to transfer size (N_cnt = N_size).

    3. Sending DMA performs one burst filling the McBSP TX register. Transfer count is decremented (N_cnt = N_cnt - 1 = N_size - 1)

    4. Slave waits for master to start SPI transaction.

    5. On first SPI transaction slave receives one 16-bit word and sends what was already in TX buffer. Slave sending DMA burst is triggered and it once more fills TX buffer for next SPI transaction. N_cnt = N_cnt - 1 = N_size - 2.

    6. After the  (N_size - 1)-th SPI transaction, slave sending DMA transfer count should be N_cnt = 0.

    7. On N_size-th SPI transaction slave sends data prepared by the sending DMA in previous step and new transfer is initiated when TX buffer becomes empty. I.e. jump to step 2.

    So if my reasoning is good, after the 7-th step of such sequence the slave sending DMA's transfer count should be N_size-1 and the slave should be waiting for the master to start clocking on SPI for next N_size number of SPI transactions. 

    However, while slave is waiting for the master I observed that its' receiving DMA transfer count is zero (as expected, N_size bursts have been completed and DMA is waiting for first incoming 16-bit word of the next transfer), but the sending DMA transfer count is N_size-2 (instead of N_size-1)!

    It seams like the slave sending DMA performs two bursts at the end of transfer when TX register becomes empty (or after it is first enabled), and before master starts sending next (first) batch of data.

    I'm confused...

  • Josip,

    Keep in mind the TRANSFER_SIZE register is an N-1 register, meaning that if you wanted to perform 6 bursts in each transfer you would set the register value to 5. The TRANSFER_COUNT register is exact. If a 5 exists in this register then there are 5 bursts left in the transfer. Hopefully that has not been confusing you.

    Note that a interrupt should occur at step 6 (if enabled). You could try setting the HALT bit or setting a breakpoint in the ISR to see what state the DMA is in. The DMA can only HALT in certain locations (once you set the HALT bit or hit the emulation breakpoint, the DMA will continue to run until the next HALT spot in the state machine, assuming the FREE bit is configured to 0). See Figure 5 in the DMA User Guide (http://www.ti.com/lit/pdf/sprufb8) for the points in the state machine where the DMA will HALT. You can then look at the registers to debug what is going on.

    Regards,
    Dave Foley

     

  • Dave

    thank you for suggestions. I am aware of the N-1 nature of the TRANSFER_SIZE register. I am transferring 10 16-bit words so I set TRANSFER_SIZE to 9. After initialization, before any activity on McBSP SPI bus, TRANSFER_COUNT is for:

     - DMA1 (receives date) - 0 (which is expected)

     - DMA2 (sends data) - 7 (?!)

    After I trigger one 10-word SPI transaction on the master, TRANSFER_COUNTs on slave are same as above.

    I tried setting HALT bit on the slave's DMA2. Prior to taking DMA out of HALT, the register content is (master is not clocking SPI):

    MODE 0x0910
    CONTROL 0x0100
    BURST_SIZE 0x0001
    BURST_COUNT 0x0000
    SRC_BURST_STEP 0x0000
    DST_BURST_STEP 0x0000
    TRANSFER_SIZE 0x0009
    TRANSFER_COUNT 0x0000
    SRC_TRANSFER_STEP 0x0001
    DST_TRANSFER_STEP 0x0000
    SRC_WRAP_SIZE 0xFFFF
    SRC_WRAP_COUNT 0x0000
    SRC_WRAP_STEP 0x0000
    DST_WRAP_SIZE 0x0000
    DST_WRAP_COUNT 0x0000
    DST_WRAP_STEP 0x0000
    SRC_BEG_ADDR_SHDW 0x0000F068
    SRC_ADDR_SHDW 0x0000F068
    SRC_BEG_ADDR_ACTIVE 0x00000000
    SRC_ADDR_ACTIVE 0x00000000
    DST_BEG_ADDR_SHDW 0x00005043
    DST_ADDR_SHDW 0x00005043
    DST_BEG_ADDR_ACTIVE 0x00000000
    DST_ADDR_ACTIVE 0x00000000

    If I than write 0x0101 to CONTROL register and run and halt the processor, content of the registers is:

    MODE 0x0910
    CONTROL 0x2800
    BURST_SIZE 0x0001
    BURST_COUNT 0x0000
    SRC_BURST_STEP 0x0000
    DST_BURST_STEP 0x0000
    TRANSFER_SIZE 0x0009
    TRANSFER_COUNT 0x0007
    SRC_TRANSFER_STEP 0x0001
    DST_TRANSFER_STEP 0x0000
    SRC_WRAP_SIZE 0xFFFF
    SRC_WRAP_COUNT 0xFFFD
    SRC_WRAP_STEP 0x0000
    DST_WRAP_SIZE 0x0000
    DST_WRAP_COUNT 0x0000
    DST_WRAP_STEP 0x0000
    SRC_BEG_ADDR_SHDW 0x0000F068
    SRC_ADDR_SHDW 0x0000F068
    SRC_BEG_ADDR_ACTIVE 0x0000F068
    SRC_ADDR_ACTIVE 0x0000F06A
    DST_BEG_ADDR_SHDW 0x00005043
    DST_ADDR_SHDW 0x00005043
    DST_BEG_ADDR_ACTIVE 0x00005043
    DST_ADDR_ACTIVE 0x00005043

    It still seems to me that sending DMA performs two transfers in stead of one.

  • Josip,

    Just a speculation-

    Usually SPI module has a TX Buffer and a Shift register. So the first DMA transfer to the SPI_TX buffer goes down to the shift register, triggering a TX_BUF empty condition, which trigger another DMA transfer. That can explain why pending count shows 2 less to begin with.

    If you shift 10 known values from the slave, do they end up correctly on the master side?

    Joe

     

  • Joe,

    I think you nailed it! The DMA documentation [SPRUFB8] says that it is triggered by McBSP event "MXEVT". Such event is not mentioned in McBSP documentation [SPRUFB7B], but it says that transmit interrupt is generated "when the XRDY bit changes from 0 to 1" and also that "XRDY is set in response to a copy from DXR1 to XSR1". All this is consistent with behavior I observed in my application.

    Thank you for the insight!

    Josip

  • Hi all,

    another issue has arisen with the DMA+McBSP/SPI driver. Data somehow gets corrupted. We performed two experiments.

    One application sends six 32-bit values to the slave and loops them back to the master. At first, sent and received data is the same but after some time the data on master gets misaligned (data on the slave stays OK):

    sent

    received

    4201999A

    999A07C0

    449A4000

    40004201

    43E80000

    0000449A

    000003DB

    03DB440D

    00000504

    05040000

    000007C0

    07C00000

    In another experiment, eight 32-bit values are sent. First value is dummy data, second and eight values are constant (12345678h) and are looped back to the master. Just before drivers on both slave and master, DMA transfer counts of both sending and receiving DMAs are checked. At first, master receives the same values as sent on 2nd and 8th slot (12345678h), and DMA transfer count values are as follows:

    • master
      • DMA1 (sends): 0
      • DMA2 (receives): 0
      • slave
        • DMA1 (receives): 0
        • DMA2 (sends): 13

    All these values are as expected. After some time in operation, data gets misaligned and master receives 56781234h on 2nd slot and 56783750h on eight slot. On the slave, values on these two slots are as expected (12345678h). DMA transfer counts stay the same as they were while data was OK.

     

    Can anyone make any sense out of this?

     

    Regards,

    Josip