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/LAUNCHXL2-570LC43: MIBSPI with DMA problem

Part Number: LAUNCHXL2-570LC43

Tool/software: Code Composer Studio

I used HALCoGen to generate software code to communicate 2 LAUNCHXL2-570LC43 MCUs through MIBSPI3, the 2 MCUs transfer and receive an array of 128 word(16-bits), then I configured DMA to write and read data from MIBSPI TX/RX RAM.

At 1MHz, and 2MHz  MIBSPI frequency the received data are fine, but at higher MIBSPI frequencies starts from 3MHz!! the received data become corrupted (the elements values are correct but their indices in the array is wrong) each new 128  word received are out of index from the previous reception and so on.

here is the DMA configuration and main function:

#include    "SPI_Start.h"
#include    "HL_sys_dma.h"

#define D_SIZE 128

#pragma SET_DATA_SECTION(".sharedRAM")
uint16 TXDATA[D_SIZE];         /* transmit buffer in sys ram */
uint16 RXDATA[D_SIZE]= {0};    /* receive  buffer in sys ram */
#pragma SET_DATA_SECTION()

#define D_SIZE 128
void mibspiDmaConfig(mibspiBASE_t *mibspi,uint32 channel, uint32 txchannel, uint32 rxchannel)
{
    uint32 bufid  = D_SIZE - 1;
    uint32 icount = 0;

    /* 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);

}

g_dmaCTRL g_dmaCTRLPKT1, g_dmaCTRLPKT2;    /* dma control packet configuration stack */

void     main(void)
{

        uint8_t i;
        for (i=0; i<D_SIZE; i++)
        {
            TXDATA[i]= i;
        }

        SPI_Init();

        /* - configuring dma control packets   */

        g_dmaCTRLPKT1.SADD      = (uint32)TXDATA;    /* source address             */
        g_dmaCTRLPKT1.DADD      = (uint32)&(mibspiRAM3->tx[0].data);    /* destination  address       */
        g_dmaCTRLPKT1.CHCTRL    = 0;                 /* channel control            */
        g_dmaCTRLPKT1.FRCNT     = 1;                 /* frame count                */
        g_dmaCTRLPKT1.ELCNT     = D_SIZE;            /* element count              */
        g_dmaCTRLPKT1.ELDOFFSET = 4;                 /* element destination offset */
        g_dmaCTRLPKT1.ELSOFFSET = 0;                 /* element destination offset */
        g_dmaCTRLPKT1.FRDOFFSET = 0;                 /* frame destination offset   */
        g_dmaCTRLPKT1.FRSOFFSET = 0;                 /* frame destination offset   */
        g_dmaCTRLPKT1.PORTASGN  = PORTA_READ_PORTB_WRITE;
        g_dmaCTRLPKT1.RDSIZE    = ACCESS_16_BIT;     /* read size                  */
        g_dmaCTRLPKT1.WRSIZE    = ACCESS_16_BIT;     /* write size                 */
        g_dmaCTRLPKT1.TTYPE     = FRAME_TRANSFER ;   /* transfer type              */
        g_dmaCTRLPKT1.ADDMODERD = ADDR_INC1;         /* address mode read          */
        g_dmaCTRLPKT1.ADDMODEWR = ADDR_OFFSET;       /* address mode write         */
        g_dmaCTRLPKT1.AUTOINIT  = AUTOINIT_ON;       /* autoinit                   */

        g_dmaCTRLPKT2.SADD      = (uint32)&(mibspiRAM3->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     = D_SIZE;             /* element count              */
        g_dmaCTRLPKT2.ELDOFFSET = 0;                 /* 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     = FRAME_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_dmaCTRLPKT1);
        dmaSetCtrlPacket(DMA_CH1,g_dmaCTRLPKT2);

        /* - setting the dma channel to trigger on h/w request */
        dmaSetChEnable(DMA_CH0, DMA_HW);
        dmaSetChEnable(DMA_CH1, DMA_HW);

        dmaReqAssign(DMA_CH0, DMA_REQ4); //DMA request line 4 -- TX (last col, Table 6-41)
        dmaReqAssign(DMA_CH1, DMA_REQ5); //DMA request line 5 -- RX (last col, Table 6-41)

        /* - configuring the mibspi dma , channel 2, MibSPI TX Line -2 , MibSPI RX Line - 3 */
        /* MibSPI TX Line and MibSPI RX Line are in the parentheses following MibSPI1 */
        /* MibSPI3 transfer group 0*/

        dmaEnable();

        if(SPI_Module[SPI3].MasterSlave!=SLAVE)
        {
            // Master puts CS to low
            mibspiREG3->PC3&= ~(0x00000002U);
        }
        mibspiTransfer(mibspiREG3, 0);

        while       (1)
        {

                    if((mibspiREG3->DMACTRL[0]& 0x8000)!=0x8000)
                    {
                        if(SPI_Module[SPI3].MasterSlave!=SLAVE)
                        {
                            // Master puts CS to high
                            mibspiREG3->PC3|= (0x00000002U);
                        }

                        mibspiDmaConfig(mibspiREG3,0,2,3);

                        if(SPI_Module[SPI3].MasterSlave!=SLAVE)
                        {
                            // Master puts CS to low
                            mibspiREG3->PC3&= ~(0x00000002U);
                        }
                        mibspiTransfer(mibspiREG3, 0);
                    }

        } // End of while loop
} // End of main()

  • Hello Amr,

    The wires between 2 launchpads may pick up noise and affect the transmission. Can you try MibSPI1 and MibSPI3 on the same board?

  • Hello QJ,

    I don't think that the problem is due to wires(wires length is 11cm), I tried the same communication using TG0 set data and get data functions without DMA intervention and everything worked fine.

    3MHz is not high frequency compared to 20 MHz to cause such a problem.

    Thanks and Regards,

    Amr

  • Hello Amr,

    Please double check if the DMACTRL is set correctly (highlighted in yellow):

    Can you please check MIBSPI#136 in LC4357 Errata? I am not sure if the issue is related to this bug.

  • Hello QJ,

    I doubled check if the DMACTRL is set correctly, and its correct.

    Can you please check MIBSPI#136 in LC4357 Errata? I am not sure if the issue is related to this bug.

    -It's not related to this bug.

    I added a break point in master code at this line "mibspiTransfer(mibspiREG3, 0);" and hit the run button each time, all array elements was correct! then I added a large delay before this line (in ms) and removed the break point; the code worked fine and all array elements was correct.

    Now, I don't know why the delay fixed the problem?, and I want to remove it.

    Thanks and Regards,

    Amr

  • Hello Amr,

        /* setting transmit and receive channels */
        mibspi->DMACTRL[channel] |= (((rxchannel<<4)|txchannel) << 16);
    RXDMA_MAP is at bit {23:20]. It doesn't make sense to program rxchannel to other bit field (4th bit in your code). DMA setting for transmit is OK.
    The condition for MibSPI #136:

    Condition This erratum is only valid when:
    1. A MibSPI instance that does not support the extended buffer feature is used.
    2. The number of buffers intended by the application for Transfer Group 0 (TG0) is 128 or 0x80.
    3. The last buffer number in a transfer group is set to 128 by setting the first buffer of the next transfer group (PSTART) to "0x00". (Note that PSTART-1 of next transfer group becomes last buffer number for the current transfer group)