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.

MibSPI Large Count with TG

Other Parts Discussed in Thread: HALCOGEN

Hi there,

I've succeeded in setting up a MibSPI using TG and DMA to transfer up to 128 x 16-bit words and understood well the mechanism, I believe.

When my TX size is within 128 words, the MibSPI sequencer transmits data in the TXRAM and save RX words in RXRAM, so all I have to do is to start the sequencer and once the last word is RX (defined by BUFID), the DMA kicks in and copy all RX data to my application RAM.

Now I'm trying to understand how to setup using this same SPI transmission scheme but with a larger buffer but could find information for my understanding. I understand that I have to set the LARGE COUNT bit in the DMACNTLEN register, then set the ICOUNT field of the ICOUNT register to the size of my buffer to be transmitted, up to 64K. Below are some of my questions and hope that someone can shed some light.

What registers to configure to instruct the MibSPI sequencer to take data from the application RAM (larger than 128 words, let say, 1024 words)?

How the mechanism works to transfer each chunk of data to the TXRAM?

Where can I configure the RX buffer written to trigger the DMA at the end of transfer (it was BUFID when <= 128 words)?

Thank you very much for any help.

  • Chuck Wong said:
    I've succeeded in setting up a MibSPI using TG and DMA to transfer up to 128 x 16-bit words and understood well the mechanism, I believe.

    Super!

    Chuck Wong said:
    What registers to configure to instruct the MibSPI sequencer to take data from the application RAM (larger than 128 words, let say, 1024 words)?

     

    The MibSPI sequencer can only read words from the MibSPI MultiBuffer RAM.  It's not able to read the main memory of the CPU.  What it can do is make a DMA request.  The DMA will then have to be configured to copy data from the main RAM of the CPU into the multibuffer RAM.

    Chuck Wong said:
    How the mechanism works to transfer each chunk of data to the TXRAM?

    The DMA request is tied to a particular buffer - see the BUFIDx register.  So what you might do is when you get halfway through your transmit buffers, you would kick off a DMA request to one DMA channel that moves data from CPU RAM into the first 64 MibSPI buffers.  You would be tieing this DMA channel to buffer 63.   Then you would also do the same at the last buffer but tie it to a different channel that moves the 2nd half of the data into the 2nd half of the buffers.  This way you can keep a sort of ping-pong scheme going.

    Chuck Wong said:
    Where can I configure the RX buffer written to trigger the DMA at the end of transfer (it was BUFID when <= 128 words)?

    It's in that DMAxCTRL register set.  (There are multiple of these) and you can configure a different DMA channel for the RX and transmit buffers.

  • Hi Anthony,

    POST EDITED.

    Thanks for the prompt help. Please let me know whether my understanding is correct with the following configuration. Many thanks!

    Considering a 512-word buffer residing in the CPU application TXRAM to be transferred using MibSPI:

    Parameter

    TX DMA 1

    TX DMA 2

    TX DMA3

    MibSPI DMACNTLEN.LARGE_COUNT=1

     

     

     

    MibSPI DMAxCOUNT.ICOUNT

    256

    256

    512

    MibSPI BUFID (To Trigger DMA)

    63

    127

    Chained by DMA 2

    DMA Initial SRC Address

    CPU TXRAM[0]

    CPU TXRAM[64]

    MibSPI RXRAM[0]

    DMA Initial Destination Address

    MibSPI TXRAM[0]

    MibSPI TXRAM[64]

    CPU RXRAM[0]

     DMA Frame Count

    4

    4

    4

    DMA Element Count

    64

    64

    128

    DMA Frame Index Offset

    64

    64

    0

    DMA Hardware Trigger Initiates

    1 Frame Transfer

    1 Frame Transfer

    1 Frame Transfer


    DMA 3 is set up and be chained by DMA 2 to copy 128 RX words each time, from MibSPI RXRAM to CPU application RXRAM, for a total of 512 words.

  • Hi Chuck,

    the above table is a good start but I think there are some things I would change.

    I started adapting the mibSPI DMA example that comes with HalCoGen but didn't finish; and I'll be out of the office for the next 4 business day so I'll go ahead and post what I've got in case it's useful.

    5125.MibSPI_DMA_LargeBlock_RM48.zip

    I would avoid the DMA chaining for starters.  Instead the DMACTRL register in the MibSPI can trigger 2 channels of the DMA - one for receive and one for transmit.  This would I think be the most flexibile / reliable way I think rather than chaining.

    In my twist on the basic HalCoGen example I haven't turned on the receive path so you would need to do this.

    And I shortened up the transfer to 4 16-bit words, but its' transferred using 2 DMA frames of 2 words each.  This just makes it simple to capture what is going on on an Oscilloscope and still have enough resolution to see / count the bit clocks easily.   If you can get this to work the way you like it's trivial then to change it to support longer bursts.

    While I'm out there are other folks on the team monitoring the forum so post if you've got questions.

  • Hi Anthony,

    Thanks for the suggestions and will take all of them into account in my design.

    Regards!

  • Anthony F. Seely said:
    The DMA request is tied to a particular buffer - see the BUFIDx register.  So what you might do is when you get halfway through your transmit buffers, you would kick off a DMA request to one DMA channel that moves data from CPU RAM into the first 64 MibSPI buffers.  You would be tieing this DMA channel to buffer 63.   Then you would also do the same at the last buffer but tie it to a different channel that moves the 2nd half of the data into the 2nd half of the buffers.  This way you can keep a sort of ping-pong scheme going.

    Hi Anthony,

    While I understand how this mechanism works, I didn't catch the following in the case of a large buffer. Let's follow the above quoted example for a 256-word data array TX_BUFFER[256] to output to the SPI device, then store the RX data into RX_BUFFER[256] in the MCU application RAM. I would configure:

    • MibSPI TG0 to cover all locations [0..127]
    • DMA CH3 to 2 frames transfer of 64 elements each, by taking TX_BUFFER[0..63] as TX frame 1 and TX_BUFFER[128..191] as TX frame 2, and write those frames to locations TXRAM[0..63]
    • DMA CH4 to 2 frames transfer of 64 elements each, by taking TX_BUFFER[64..127] as TX frame 1 and TX_BUFFER[192..255] as TX frame 2, and write those frames to locations TXRAM[64..127]
    • DMA CH5 to read MibSPI RXRAM[0..63] and store both frames at RX_BUFFER[0..63] and RX_BUFFER[18..191] respectively.
    • DMA CH6 to read MibSPI RXRAM[64..127] and store both frames at RX_BUFFER[64.127] and RX_BUFFER[192..255] respectively.
    • I would then tie MibSPI DMA0CTRL to BUFID=63 (to initiate DMA CH3 and CH5), and DMA1CTRL to BUFID=127 (to initiate DMA CH4 and CH6) to create a Ping-Pong scheme.
    • I then manually launch DMA CH3 and CH4 using SW to fill the MibSPI TXRAM [0..127], then trigger the MibSPI TG0 to start the TX.

    Here is what I don't understand: in the case of DMA CH3, although I might use the source frame address index offset to control the source DMA pointer after the first frame been transferred (jump from array location 63 to 128), since the destination DMA pointer is now pointing at location 64, how could I reset the destination pointer to TXRAM[0] as it is intended?

    Same question for DMA CH4 for reverting back to TXRAM[64]. Also the same for DMA CH5 and CH6 for on the RXRAM.

    Thanks!

  • Chuck Wong said:
    Here is what I don't understand: in the case of DMA CH3, although I might use the source frame address index offset to control the source DMA pointer after the first frame been transferred (jump from array location 63 to 128), since the destination DMA pointer is now pointing at location 64, how could I reset the destination pointer to TXRAM[0] as it is intended?

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