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.

LAUNCHXL2-570LC43: TMS 570 MIBSPI slave with DMA

Part Number: LAUNCHXL2-570LC43

Hey TI team,

For our application we are running MIBSPI5 as slave with MIBSPI CLK ~12.5 Mhz. We are getting a 13*16 bit transfers ever ~20.836 microseconds. Since we don't want to run a get data at this rate we are trying to use the DMA module to facilitate the transfer of this data to an initialized buffer. For this we have a couple of questions 

  1. Can we use DMA for moving this 208 bit information for every spi transfer into an array that may have memory allocated for 2500 of these buffers which would allow us to read every 50ms.
  2. After the above mentioned read an we reset the dma base pointer back to start writing to the base address of the array.
  3. How would we setup the interrupt request of dma to trigger on every spi transfer complete ?

Thanks ! 

  • Can we use DMA for moving this 208 bit information for every spi transfer into an array that may have memory allocated for 2500 of these buffers which would allow us to read every 50ms.

    Yes, DMA request is generated after the transfer from the BUFIDx buffer is finished. You can assign 13 buffers for one TG.

    After the above mentioned read an we reset the dma base pointer back to start writing to the base address of the array.

    Yes, you can.

    How would we setup the interrupt request of dma to trigger on every spi transfer complete ?

    The DMA supports several interrupt: BTC, FTC, HBC, and LFS

    Please refer to DMA Interrupt section  of device TRM

  • Hey QJ, thanks for the response.
    I have a follow up question for this and I see the data being reported is not the same as when MIBSPI is individually run. I have tried the following 2 scenarios.

    Scenario 1 - 

    Only running mibspi5 without dma and sending 48ksamples of data per second and am able to see the correct data when trying to get the mibspi data i.e. (0x0102,0x0304,0x0506 .. repeated 3 more times)

    recv unsigned short[12] [0x0102,0x0304,0x0506,0x0102,0x0304...] (Hex) 0x08000FD0
    [0] unsigned short 0x0102 (Hex) 0x08000FD0
    [1] unsigned short 0x0304 (Hex) 0x08000FD2
    [2] unsigned short 0x0506 (Hex) 0x08000FD4
    [3] unsigned short 0x0102 (Hex) 0x08000FD6
    [4] unsigned short 0x0304 (Hex) 0x08000FD8
    [5] unsigned short 0x0506 (Hex) 0x08000FDA
    [6] unsigned short 0x0102 (Hex) 0x08000FDC
    [7] unsigned short 0x0304 (Hex) 0x08000FDE
    [8] unsigned short 0x0506 (Hex) 0x08000FE0
    [9] unsigned short 0x0102 (Hex) 0x08000FE2
    [10] unsigned short 0x0304 (Hex) 0x08000FE4
    [11] unsigned short 0x0506 (Hex) 0x08000FE6

    Scenario 2 - 

    Running mibspi5 with dma and the following settings - 

    #pragma SET_DATA_SECTION(".sharedRAM")
    uint16 RXDATA[160]= {0};    /* receive  buffer in sys ram */
    #pragma SET_DATA_SECTION()
    
    int main(void)
    {
           mibspiInit();
           mibspiREG5->TGCTRL[0] |= 0x80000000;
           
           g_dmaCTRLPKT2.SADD      = (uint32)&(mibspiRAM5->rx[0].data);    /* source address             */
           g_dmaCTRLPKT2.DADD      = (uint32)&RXDATA;    /* destination  address       */
           g_dmaCTRLPKT2.CHCTRL    = 0;                 /* channel control            */
           g_dmaCTRLPKT2.FRCNT     = 1;                 /* frame count                */
           g_dmaCTRLPKT2.ELCNT     = 12;                 /* element count              */
           g_dmaCTRLPKT2.ELDOFFSET = 0;                 /* element destination offset */
           g_dmaCTRLPKT2.ELSOFFSET = 2;                 /* element destination offset */
           g_dmaCTRLPKT2.FRDOFFSET = 0;                 /* frame destination offset   */
           g_dmaCTRLPKT2.FRSOFFSET = 2;                 /* frame destination offset   */
           g_dmaCTRLPKT2.PORTASGN  = PORTB_READ_PORTA_WRITE;
           g_dmaCTRLPKT2.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
           g_dmaCTRLPKT2.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
           g_dmaCTRLPKT2.TTYPE     = BLOCK_TRANSFER ;   /* transfer type              */
           g_dmaCTRLPKT2.ADDMODERD = ADDR_OFFSET;         /* address mode read          */
           g_dmaCTRLPKT2.ADDMODEWR = ADDR_INC1;       /* address mode write         */
           g_dmaCTRLPKT2.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */
    
           /* upto 32 control packets are supported. */
    
           /* - setting dma control packets */
           dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT2);
    //       dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT1);
           dmaReqAssign(DMA_CH0, DMA_REQ31);
           /* - setting the dma channel to trigger on h/w request */
           dmaSetChEnable(DMA_CH0, DMA_SW);
    //       dmaSetChEnable(DMA_CH1, DMA_SW);
    
           /* - configuring the mibspi dma , channel 0 , tx line -0 , rxline -1     */
           /* - refer to the device data sheet dma request source for mibspi tx/rx  */
           mibspiDmaConfig(mibspiREG5,0,0,1);
    
           dmaEnable();
           
           while(1){}
        return 0;
        }
    // ------------------------------------------
        void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel)
    {
        uint32 bufid  = 0;
        uint32 icount = 12;
    
        /* setting transmit and receive channels */
        mibspi->DMACTRL[channel] |= (((rxchannel<<4)|txchannel) << 16);
    
        /* enabling transmit and receive dma */
        mibspi->DMACTRL[channel] |=  0x80008000;
    
        /* setting Initial Count of DMA transfers and the buffer utilized for DMA transfer */
        mibspi->DMACTRL[channel] |=  (icount << 8) |(bufid<<24);
    
    }
    // ------------------------------------------

    and I see the flags being copied and as well as some values being corrupted. 

    [0] unsigned short 0x0102 (Hex) 0x0807F000
    [1] unsigned short 0x803E (Hex) 0x0807F002
    [2] unsigned short 0x0304 (Hex) 0x0807F004
    [3] unsigned short 0x803E (Hex) 0x0807F006
    [4] unsigned short 0x0081 (Hex) 0x0807F008
    [5] unsigned short 0x803E (Hex) 0x0807F00A
    [6] unsigned short 0x0102 (Hex) 0x0807F00C
    [7] unsigned short 0x803E (Hex) 0x0807F00E
    [8] unsigned short 0x0283 (Hex) 0x0807F010
    [9] unsigned short 0x803E (Hex) 0x0807F012
    [10] unsigned short 0x0081 (Hex) 0x0807F014
    [11] unsigned short 0x803E (Hex) 0x0807F016

    For both cases I am receiving 12 16 bit values as input and with dma , I am trying to copy them over to a different buffer which can hold a certain number of these samples considering the above is a single sample. Any help in this regard would be appreciated. Thanks !

  • Hey, TI team,

    Wanted to check in again to see if there is something that I am missing in the above case. Thanks !

  • Does the TG0 have 12 buffers in your configuration?

    Why is the element source offset 0x2? I think it should be 0x4.

    and

    Why is the frame source offset 0x2? If the TG0 size is 12, the offset should be 0x0. If TG0 size is 24, the offset is 12*4

  • So yes, the MIBSPI is configured with charlen of 16 with 12 buffers in TG0,
    Each sample of data being transferred over MIBSPI has (12 * 16-bit) values.

    I have updated the element source offset and frame source offset as mentioned, and I still get corrupted data.
    [0] unsigned short 0x0102 (Hex) 0x08001500
    [1] unsigned short 0x0304 (Hex) 0x08001502
    [2] unsigned short 0x0506 (Hex) 0x08001504
    [3] unsigned short 0x0182 (Hex) 0x08001506
    [4] unsigned short 0x0283 (Hex) 0x08001508
    [5] unsigned short 0x0081 (Hex) 0x0800150A
    [6] unsigned short 0x0182 (Hex) 0x0800150C
    [7] unsigned short 0x0040 (Hex) 0x0800150E
    [8] unsigned short 0x00C1 (Hex) 0x08001510
    [9] unsigned short 0x0141 (Hex) 0x08001512
    [10] unsigned short 0x0102 (Hex) 0x08001514
    [11] unsigned short 0x0283 (Hex) 0x08001516

    The updated config is as follows - 

    int main(void)
     {   _enable_IRQ();
    
    /* USER CODE BEGIN (3) */
    //    mibspiInit();
    //    //mibspiPmodeSet(mibspiREG5, PMODE_2_DATALINE, DATA_FORMAT0);
        uint16_t tx[8] = {1,2,3,4,5,6,7,8};
    
        /* - creating a data chunk in system ram to start with ... */
           loadDataPattern(D_SIZE,&TXDATA[0]);
    
           /* - initializing mibspi - enabling tg 0 , length 127 (halcogen file)*/
           mibspiInit();
           mibspiREG5->TGCTRL[0] |= 0x80000000;
    
    //       /* - enabling loopback ( this is to emulate data transfer without external wires */
    //       mibspiEnableInternalLoopback(mibspiREG1);
    //       mibspiEnableLoopback(mibspiREG1, Digital_Lbk);
    //
    //       /* - configuring dma control packets   */
    
           g_dmaCTRLPKT2.SADD      = (uint32)&(mibspiRAM5->rx[0].data);    /* source address             */
           g_dmaCTRLPKT2.DADD      = (uint32)&RXDATA;    /* destination  address       */
           g_dmaCTRLPKT2.CHCTRL    = 0;                 /* channel control            */
           g_dmaCTRLPKT2.FRCNT     = 1;                 /* frame count                */
           g_dmaCTRLPKT2.ELCNT     = 12;                 /* element count              */
           g_dmaCTRLPKT2.ELDOFFSET = 2;                 /* element destination offset */
           g_dmaCTRLPKT2.ELSOFFSET = 4;                 /* element destination offset */
           g_dmaCTRLPKT2.FRDOFFSET = 0;                 /* frame destination offset   */
           g_dmaCTRLPKT2.FRSOFFSET = 0;                 /* frame destination offset   */
           g_dmaCTRLPKT2.PORTASGN  = PORTB_READ_PORTA_WRITE;
           g_dmaCTRLPKT2.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
           g_dmaCTRLPKT2.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
           g_dmaCTRLPKT2.TTYPE     = BLOCK_TRANSFER ;   /* transfer type              */
           g_dmaCTRLPKT2.ADDMODERD = ADDR_OFFSET;         /* address mode read          */
           g_dmaCTRLPKT2.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
           g_dmaCTRLPKT2.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */
    
           /* upto 32 control packets are supported. */
    
           /* - setting dma control packets */
           dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT2);
    //       dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT1);
           dmaReqAssign(DMA_CH0, DMA_REQ31);
           /* - setting the dma channel to trigger on h/w request */
           dmaSetChEnable(DMA_CH0, DMA_SW);
    //       dmaSetChEnable(DMA_CH1, DMA_SW);
           dmaEnableInterrupt(DMA_CH0, BTC, DMA_INTA);
    
           /* - configuring the mibspi dma , channel 0 , tx line -0 , rxline -1     */
           /* - refer to the device data sheet dma request source for mibspi tx/rx  */
           mibspiDmaConfig(mibspiREG5,0,0,1);
    
           dmaEnable();
    
    //       /* - start the mibspi transfer tg 0 */
    //       mibspiTransfer(mibspiREG1,0 );
    
        while(1){
    //    tx[0]++;
    //    tx[1]++;
    //    tx[2]++;
    //    if(tx[0]>100){ tx[0]=0;tx[1]=0;tx[2]=0;}
    //    mibspiSetData(mibspiREG1,0,tx);
    //    mibspiTransfer(mibspiREG1,0);
    //
    //    while(!mibspiIsTransferComplete(mibspiREG1,0));
    //
    //    mibspiGetData(mibspiREG5, 0 , &recv[0]);
    
        }
    /* USER CODE END */
      return 0;
    }
    
    
    /* USER CODE BEGIN (4) */
    void mibspiEnableInternalLoopback(mibspiBASE_t *mibspi )
    {
        /* enabling internal loopback */
        mibspi->GCR1 |= 1U << 16U;
    }
    
    void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel)
    {
        uint32 bufid  = 0;
        uint32 icount = 12;
    
        /* setting transmit and receive channels */
        mibspi->DMACTRL[channel] |= (((rxchannel<<4)|txchannel) << 16);
    
        /* enabling transmit and receive dma */
        mibspi->DMACTRL[channel] |=  0x8000C000;
    
        /* setting Initial Count of DMA transfers and the buffer utilized for DMA transfer */
        mibspi->DMACTRL[channel] |=  (icount << 8) |(bufid<<24);
    
    }
    
    void loadDataPattern(uint32 psize, uint16* pptr)
    {
        int i;
        for(i=0;i<psize;i++)
        {
            TXDATA[i] = i;
        }
     }
    
    void dmaGroupANotification(dmaInterrupt_t inttype, uint32 channel) {
        memcpy(&recv,&RXDATA,sizeof(recv));
    }

  • Hi,

    Please change the DMA trigger type to DMA_HW:

           dmaSetChEnable(DMA_CH0, DMA_HW);

    Since you use the DMA request 31, and DMA is for MibSPI5 RX:

           mibspiDmaConfig(mibspiREG5,0,0,1);

    should be changed to:

           mibspiDmaConfig(mibspiREG5,0,0,0);