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.

Configuring MIBSPI2 to use DMA on the RM57

Other Parts Discussed in Thread: HALCOGEN

I am trying to enable using DMA with multi-buffer for SPI2 on the RM57.

I started by using "example_mibspiDMA.c" found in the HALCoGen examples at C:\ti\Hercules\HALCoGen\v04.05.01\examples\RM57Lx

I configured HALCoGen as directed in the example. I then verified that for MIBSPI1 the DMA transfer was working as expected (the RXDATA buffer contains the correct data at the end of the DMA transfer).

I then used HALCoGen to configure MIBSPI2 using the same steps that I used for MIBSPI1. I then search and replace all occurrences of "mibspiREG1"  with "mibspiREG2" in the example source code. I also changed the occurrences of "mibspiRAM1" to "mibspiRAM2".

I tried tired to run my modified sample and it didn't work. Nothing was transferred to the RXDATA array.

I then found table 5-37 in the RM57 data sheet (this was not in the TRM). From the table it looks like I should be using DMA request 2 and 3 instead of 1 and 2.

I changed the line of code where I set up the MIBSPI  DMA configuration:

mibspiDmaConfig(mibspiREG2,0,2,3);

I also tried changing the DMA control packets to use DMA_CH2 and 3:

/* - setting dma control packets */

dmaSetCtrlPacket(DMA_CH2,g_dmaCTRLPKT2);

dmaSetCtrlPacket(DMA_CH3,g_dmaCTRLPKT1);

/* - setting the dma channel to trigger on h/w request */

dmaSetChEnable(DMA_CH2, DMA_HW);

dmaSetChEnable(DMA_CH3, DMA_HW);

I tried several other permutations, but nothing is ever transferred to the RXDATA array. Is there something else I should be configuring?

  • Tony,

    Problem may be

    mibspiDmaConfig(mibspiREG2,0,2,3);

    If you look at Table 5-37 again, DMA requests  MIBSPI2[2] and MIBSPI2[3] map to the DMA's DMAREQ[4] and DMAREQ[5].

  • Tony,

    Try the following:

    I changed the line of code where I set up the MIBSPI  DMA configuration:

    mibspiDmaConfig(mibspiREG2,0,0,1);

    I also tried changing the DMA control packets to use DMA_CH2 and 3:

    /* - setting dma control packets */

    dmaSetCtrlPacket(DMA_CH2,g_dmaCTRLPKT2);

    dmaSetCtrlPacket(DMA_CH3,g_dmaCTRLPKT1);

    /* - setting the dma channel to trigger on h/w request */

    dmaSetChEnable(DMA_CH2, DMA_HW);

    dmaSetChEnable(DMA_CH3, DMA_HW);

    Here is the detail of the different arguments for mibspiDmaConfig(mibspiREG2,0,0,1);

    mibspiREG2 : Base address of MIBSPI2 Control Register.
    0 : MIBSPI DMA CONTROL 0
    0 : RXDMA_MAP0 (see following table)
    1 : TXDMA_MAP1 (see following table)

    Please have a try and let me know.

  • I now have the example app working with MIBSPI2. The comments Jean-Marc have are correct. Those changes were necessary.
     
    One bug I encountered after making the changes Jean-Marc recommended was that the "charlen" field was set differently between SPI1 and SPI2. When I made the charlen for SPI2 match the charlen for SPI1, and had the changed mentioned above, the modified app started to work for MIBSPI2.

  • When verifying I found one more issue that you need to be aware of. Make sure that the TGCTRL register has 128 and not 127.

        /** - initialize transfer groups */

        mibspiREG2->TGCTRL[0U] = (uint32)((uint32)1U << 30U)  /* oneshot */

                               | (uint32)((uint32)0U << 29U)  /* pcurrent reset */

                               | (uint32)((uint32)TRG_ALWAYS << 20U)  /* trigger event */

                               | (uint32)((uint32)TRG_DISABLED << 16U)  /* trigger source */

                               | (uint32)((uint32)0U << 8U);  /* start buffer */

     

        mibspiREG2->TGCTRL[1U] = (uint32)((uint32)1U << 30U)  /* oneshot */

                               | (uint32)((uint32)0U << 29U)  /* pcurrent reset */

                               | (uint32)((uint32)TRG_ALWAYS << 20U)  /* trigger event */

                               | (uint32)((uint32)TRG_DISABLED << 16U)  /* trigger source */

                               | (uint32)((uint32)128U << 8U);  /* start buffer */

  • Thank You Tony!

    The other point I want to add to this thread for anyone following is that we decided that mode 4 is not the right mode to use for a block transfer where you don't tolerate dropping data.

    Mode 4 as the example shows is for an external sensor. The sensor would be periodically read by the MibSPI and this may involve sending a fixed command string ... so it wouldn't be necessary or desirable to force the CPU or DMA to keep writing this same string to MibSPI RAM before every transfer. And you also wouldn't always want the CPU or DMA to have to read every sensor reading *out* of the MibSPI RAM - you just want the MibSPI to read from the sensor frequently so that when the CPU does decide it needs the sensor value - a 'fresh' value is readily available in MibSPI RAM.

    That's what mode 4 is good for - it performs the transfer regardless of the status of RXEMPTY / TXFULL.

    For a long transfer to a block device like an SDCARD - with DMA involved - you want a full handshake between the MibSPI buffer status flags (RXEMPTY/TXFULL) and the MibSPI serial engine. Don't want it to start a transfer before the buffer has been serviced.

    For this use case buffer mode 7 is appropriate.

    EDIT: 

     tickets filed-   SDOCM00119524 for the wrong buffer mode in the example.

                            SDOCM00119525 for the wrong buffer size for TG 0.