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.

TMS570LC4357: How to use DMA for I2C transmit and receive?

Part Number: TMS570LC4357

Do you have any example code to use DMA for I2C transfer and receive?

  • Using DMA for I2C data transfers is similar to using DMA for SPI or SCI transfers. 

    A transmit event is generated after a START condition in master transmitter mode. The DMA receives data and transmits data based on receive event and transmit event. The read and write events have the same timing as I2CRRDY (I2CRINT) and I2CXRDY (I2CXINT), respectively.

    I don't have example for I2C with DMA.

  • uint8 TX_PACK[bsize]={'H','E','R','C','U','L','E','S','M','I','C','R','O','-','T','I'};
    uint8 RX_PACK[bsize]={0};

    #define I2C1_TX_ADDR ((uint32_t)(&(i2cREG1->DXR)))
    #define I2C1_RX_ADDR ((uint32_t)(&(i2cREG1->DRR)))
    // enable CPU response to interrupt request
    _enable_IRQ();
    /* i2c initialization */
    i2cInit();

    /* Configure address of Slave to talk to */
    i2cSetSlaveAdd(i2cREG1, slv_add);
    i2cSetDirection(i2cREG1, I2C_TRANSMITTER);


    /* set i2c own address */
    i2cSetOwnAdd(i2cREG1,own_add);

    /* enable internal loopback */
    i2cEnableLoopback(i2cREG1);

    dmaReqAssign(DMA_CH0, DMA_REQ10);
    dmaReqAssign(DMA_CH1, DMA_REQ11);

    dmaSetChEnable(DMA_CH0, DMA_HW);
    dmaSetChEnable(DMA_CH1, DMA_HW);

    dmaEnableInterrupt(DMA_CH0, BTC, DMA_INTA);
    dmaEnableInterrupt(DMA_CH1, BTC, DMA_INTA);

    vDmaConfigCtrlTxPacket((uint32_t)(&TX_PACK[0]), I2C1_TX_ADDR, 16);
    vDmaConfigCtrlRxPacket(I2C1_RX_ADDR, (uint32_t)(&RX_PACK[0]), 16);
    /* - setting dma control packets for transmit */
    dmaSetCtrlPacket(DMA_CH0, g_dmaCTRLPKT1);
    dmaSetCtrlPacket(DMA_CH1, g_dmaCTRLPKT);

    dmaEnable();

    i2cREG1->DMACR |= 0x3;

    i2cSetStop(i2cREG1);

    /* transmit Start Condition */
    i2cSetStart(i2cREG1);

    1. I see both DMA interrupt notifications but RX_PACK DMA is all 0

  • Please change the following code:

    #define I2C1_TX_ADDR ((uint32_t)(&(i2cREG1->DXR)))
    #define I2C1_RX_ADDR ((uint32_t)(&(i2cREG1->DRR)))

    To:

    #define I2C1_TX_ADDR ((uint32_t)(&(i2cREG1->DXR)) + 3)
    #define I2C1_RX_ADDR ((uint32_t)(&(i2cREG1->DRR)) + 3)

  • This works, Thank you. Can you please explain why 3?

  • TMS570LC43x is a big endian device. The most significant byte of the data is placed at the byte with the lowest address. The rest of the data is placed in order in the next three bytes in memory. 

    I2CDXR[7:0] and I2CDRR[7:0] are placed at the byte with the highest address.

    Memory address              I2CDXR              I2CDRR

    --------------------------------------------------------------------

    0x20                                 - -                        - -   

    0x21                                 - -                        - -

    0x22                                 DXR[15:8]           DRR[15:8]

    0x23                                 DXR[7:0]             DRR[7:0]