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.

CCS/RM44L920: SPI TX/RX problem with DMA

Part Number: RM44L920
Other Parts Discussed in Thread: HALCOGEN

Tool/software: Code Composer Studio

Hi,

I need to read 4 ADC's sample data in sequence in period, which 4 ADC share the same SPI  but accessed by a demultiplexer triggered by CS. To read an ADC sample data,  It need to communicate with ADC following frame: 1 read command + 3 clock, which are 4 bytes, each byte in 8 bits.

Now I want to use DMA mode to readout ADC sample data. Here is my design:  connect DMA request[0] , which is SPI receive in standard mode request to DMA CHANAN 1, while DMA request[1] , which is SPI transit in standard mode request to DMA CHANNEL 0, and my control packets   are defined as following:

g_dmaCTRL dmaCtrl_tran = {

     ( uint32 ) &***[0],                 // initial source address

    ( uint32 ) &spiREG1->DAT1,                // initial destination address

     DMA_CH1,                                         // next ctrl packet to be trigger + 1

       4,                                                    // frame   count
       4,                                                   // element count
       0,                                                   // element destination offset
       4,                                                  // element source offset
       0,                                                 // frame destination offset
       16,                                              // frame source offset
      0x04,                                          // dma port
     ACCESS_32_BIT,                      // read element size
     ACCESS_32_BIT,                   // write element size
     1,                                             // trigger type - frame/block
     ADDR_OFFSET,                      // addresssing mode for source
     0,                                            // addresssing mode for destination
     0,                                          // auto-init mode
     NO_CHANNEL,                 //   uint32 COMBO;      // next ctrl packet trigger(Not used)
    };

 g_dmaCTRL  dmaCtrl_rec= {

     ( uint32 ) &spiREG1->BUF,                 // initial source address

     ( uint32 ) Spi1DmaRevData,             // initial destination address

     DMA_CH0,                                 // next ctrl packet to be trigger + 1

       4,                  // frame   count
       4,                  // element count
       4,               // element destination offset
       0,               // element source offset
       16,              // frame detination offset
       0,                // frame source offset
      0x04,                       // dma port
     ACCESS_32_BIT,          // read element size
     ACCESS_32_BIT,          // write element size
     1,                                     // trigger type - frame/block
     0,                                     // addresssing mode for source
     ADDR_OFFSET,              // addresssing mode for destination
     0,                                           // auto-init mode
     NO_CHANNEL,                 // next ctrl packet trigger(Not used)
    };

and my problem is it can't work.  From my OSC, I only capture 16 spi clock periodically which means 2 bytes, and CS0 only active at the first 8' clock but inactive at the following 8'clock, If it work, one CS will keep active for 32 spi clocks ( 4 bytes) as it work in SPI receiver interrupt mode.

I think there is something I am wrong, would you please tell me how to configure DMA packet or if you can provide me an example about SPI DMA in Rm44L920?

Best Regards,

  • Hello,
    There is an example for TMS570LS31x_21x under HALCoGen examples folder. You could use this example as reference. Description on this example is in HALCoGen help ( TMS570LS31x.chm )

    Best regards,
    Miro
  • Hi Miro,

    Thank you for your prompt response.

    I tried to understand how SPI and DMA work in standard SPI mode but not in Multi-buffer mode, and here is my understand please help to point out my problem as my code still didn't work.

    At first, as I want to readout ADC data by SPI peripheral per DMA,  both TX_DMA_REQ and RX_DMA_REQ are needed to be generated by hardware.

    Both these function are enabled by DMAREQEN (SPIINT0[16]) and SPIEN (SPIGCR1[24]) are set to 1.

    As it was a hardware request, DMA request should be HARDWARE request and performed by

    dmaSetChEnable(DMA_CH0, DMA_HW);

    dmaSetChEnable(DMA_CH1, DMA_HW);

    Second,  DMA channel configuration: DMAREQ[1] which is a SPI transmit request( TX_DMA_REQ) connect to DMA channel 0 as it has the highest priority, which is performed by  dmaReqAssign(DMA_CH0, 1);

    while DMAREQ[0] which is a SPI receive request( RX_DMA_REQ) connect to DMA channel 1, performed by dmaReqAssign(DMA_CH1, 0);

    Third, As expected,  a TX_DMA_REQ is generated at first and then followed by a RX_DMA_REQ.

    A TX_DMA_REQ always followed by a RX_DMA_REQ until all ADC data are readout.

    So element should be "1" and frame should be "4" for readout an ADC data as it need to send out a command and 3 spi clock for adc data transmit, and the trigger source is frame transfer triggered by DMA request.

    The process can be evaluated as :

    1)TXBUF empty

    2)----------->TX_DMA_REQ

    3)---------------------->TX Element Send

    4)---------------------->SPI Received data

    5)---------------------------------------->RX_DMA_REQ

    6)------------------------------------------------->RX Element copy data

    And Tx/RX DMA packets are defined as following:

                                                                       TX                                            RX
    initial source address                         ( uint32 ) &Command[0]         ( uint32 ) &spiREG1->BUF
    initial destination address                  ( uint32 ) &spiREG1->DAT1    ( uint32 ) Spi1DmaRevData
    next ctrl packet to be trigger + 1          DMA_CH1 + 1                       DMA_CH0 + 1
    frame   count                                       16                                          16
    element count                                     1                                             1
    element destination offset                   0                                             4
    element source offset                         4                                              0
    frame destination offset                      0                                              4
    frame source offset                            4                                               0
    dma port                                            4                                                4
    read element size                             ACCESS_32_BIT                   ACCESS_32_BIT
    write element size                            ACCESS_32_BIT                   ACCESS_32_BIT
    trigger type - frame/block                  0                                               0
    addresssing mode for source          ADDR_OFFSET                       ADDR_OFFSET
    addresssing mode for destination   ADDR_OFFSET                       ADDR_OFFSET
    auto-init mode                                   0                                                 0

    Thanks,

    Catherine

  • Hello,
    For DMA in multi-buffered mode source and destination addresses should be the multi-buffer RAM and not SPIDAT0 / SPIDAT1 or SPIBUF (Chapter 28.7.1 in TRM ).
    I am not aware how ADC you are using sends data after command is received (could you tell me what ADC are you using). How do you change ADC that you are communicating with (how do you manage CS)? Element and frame count should be set according to this. More about the meaning of frame and element could be found in chapter 16.2.2 of device TRM. Addressing modes could be: constant, post incremented and indexed (Chapter 12.2.3 of TRM). You choose modes for both source an destination to be indexed (ADDR_OFFSET) and in that way address will bi post-incremented by the value int the as defined in the Element Index Offset Register and the Frame Index Offset Register.


    Best regards,
    Miro
  • Hi Miro,

    Thank you for help.

    My code worked in multi-buffered mode now followed DMA example your provided.

    And I still have several questions here. There are two notes (1) SPI1, SPI3,SPI5 receive in standard SPI mode and (2) SPI1, SPI3,SPI5 transmit in standard SPI mode in TRM page 560. My question is if I need to launch a standard SPI bi-directional transition should I use a DMA request of SPI transmit in standard mode instead of SPI receive?  And what about if I want to launch two SPI bi-directional transition at the same time, for example, in SPI1 and SPI3? Can I use the same DMA request connect to different DMA channel as you know a DMA request can come from SPI1, SPI3,SPI5?

    Thanks,

    Catherine

  • Hello,
    These notes means that, for example, if you are using SPI1 in standard mode then for receiving data you should use DMAREQ[0] and for transmitting DMAREQ[1].
    SPI is synchronous serial interface. During each SPI clock cycle, a full-duplex data transmission occurs. If you want to use DMA for both receive and transmit you have to assign DMA request for receive to a channel and another DMA request for transmit to a different channel.

    Best regards,
    Miro