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.

TM4C1294NCZAD: issue about I2C DMA FIFO burst

Part Number: TM4C1294NCZAD
Other Parts Discussed in Thread: TMP100

Dear team,

My customer uses I2C  FIFO  DMA . The following is the I2C setting:

I2CRxFIFOConfigSet(i2c_udma_setting[i].I2C_BASE, I2C_FIFO_CFG_RX_MASTER_DMA | I2C_FIFO_CFG_RX_TRIG_3);   设置 tiger 为3 bytes

I2CMasterBurstLengthSet(i2c_udma_setting[i].I2C_BASE, 3);  

uDMAChannelControlSet(ui32ChannelNum | UDMA_PRI_SELECT,
UDMA_SIZE_8 | UDMA_SRC_INC_NONE | UDMA_DST_INC_8 |
UDMA_ARB_4);                                                                                               
 

uDMAChannelTransferSet(ui32ChannelNum | UDMA_PRI_SELECT,
UDMA_MODE, (void *)(i2c_udma_setting[index].I2C_BASE + I2C_O_FIFODATA),
(void *)g_ui8I2CMasterRxDataA[index],
3);     

The following is the beginning of FIFO burst receive

    I2CMasterSlaveAddrSet(ui32Base, i2c_addr, true);
    I2CMasterControl(ui32Base, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START);

The following is the I2C interrupt

 ui32Mode = uDMAChannelModeGet(i2c_udma_setting[index].DMA_Channel | UDMA_PRI_SELECT);

   if (ui32Mode == UDMA_MODE_STOP)
   {
       ui32Mode = I2CMasterBurstCountGet(i2c_udma_setting[index].I2C_BASE);
      I2CMasterControl(i2c_udma_setting[index].I2C_BASE, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH);   
}

In 

 I2CMasterControl(i2c_udma_setting[index].I2C_BASE, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH);   

he sets hardware interrupt:

After executing I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START

I2CMasterControl(ui32Base, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START);

Look at the waveform with an oscilloscope, and you can see the normal I2C waveform that reads 3 bytes. At this time, it stops at the I2C interrupt (  I2CMasterControl(i2c_udma_setting[index].I2C_BASE, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH); )

Then single step, the customer sees another 3 bytes of data is read out, and there is an I2C STOP waveform.

According to the customer's understanding, there should be only one I2C STOP waveform and no more 3 bytes of data.

If the client sets the burst size to 4, there are 8 bytes of data to read. Set to 8 and there are 16 data to read.
It seems that the read data is twice the burst setting, this should be a problem.

Please help.

  • I am unable to see the issue with just the snippets of code you provided. Has your customer reviewed the application note: SPMA073? There is an  example project that is part of this note that does i2c FIFO uDMA. I have updated that project to use CCS v10.1, code generation tools version 20.2.3 and TivaWare 2.2.0.205 and included it here: /cfs-file/__key/communityserver-discussions-components-files/908/ektm4c129_5F00_i2c_5F00_master_5F00_udma_5F00_fifo.zip

  • Thanks for your reply.

    The code I posted is highly similar to the example you gave, and customers refer to the example.

    But the receiving method in the example is I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE, and the client's receiving start is

    I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START

    If possible, you can test the burst receive method, I think there will be  same problem as the customer, thank you!

  • Unfortunately I am not in the office and do not have access to the FRAM board on which that test was developed. I can try to create a test case using the DK-TM4C129X board and the TMP100, but it will likely be the end of the week before I have any results.

  • Thank you for your patience!

    Looking forward to your reply!

  • I was able to get this done a little sooner than I anticipated. I am using a DK-TM4C129X which connects by I2C6 to a TMP100 temp sensor. While doing a burst read from the temp sensor does not really make sense, it works well enough to show what the I2C is doing. I read 8 bytes using FIFO and uDMA. The first two bytes are the temperature, the next six bytes are 0xFF. When I use I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE, all 8 bytes are read in a burst and the bus is released at the end by the master not acknowledging the last byte (NACK) and sending a stop condition.

    When I use I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START, the result is the same however the burst read does not end after the 8 bytes.

    While this does not explain what is happening in your customer's code, it does show how to properly do a burst read using FIFO and uDMA. I have attached my project for reference.

    /cfs-file/__key/communityserver-discussions-components-files/908/dktm4c129_5F00_i2c6_5F00_master_5F00_udma_5F00_fifo.zip

  • Thank you for the detailed test!

    You check the I2CMasterIntStatusEx at the appropriate location in the interrupt service routine. When the status is I2C_MASTER_INT_RX_FIFO_REQ, call I2CMasterControl(I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH), you will see I2C STOP, and another burst of 8 bytes.

    uint32_t ui32I2CMasterInterruptStatus = I2CMasterIntStatusEx(i2c_udma_setting[8].I2C_BASE, true);
    if(ui32I2CMasterInterruptStatus & I2C_MASTER_INT_RX_FIFO_REQ)
    {
    I2CMasterControl(i2c_udma_setting[8].I2C_BASE, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH);

    Please test it.

    PS: What model is this oscilloscope?

    Besides, I found that if I don’t use I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH,just use I2C_MASTER_CMD_FIFO_BURST_RECEIVE_ERROR_STOP,you can also see the I2C stop, and it will not burst.

  • OK, I think I see the confusion. When using FIFO mode, each call to I2CMasterControl() can cause the reception or transmission of multiple bytes. Use of the uDMA extends the FIFO size. 

    Using I2C_MASTER_CMD_FIFO_SINGLE_RECEIVE will cause a start, address, then read as many bytes as are programmed in the uDMA, with a NACK on the last byte and a stop condition. This is the example I showed you and I think what you want to do.

    Using I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START will cause a start, address, then read as may bytes as are programmed in the uDMA acknowledging all bytes including the "last" one and not send a stop condition. (Shown in the second image of my previous post.)

    Using I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH will not generate a start or address, it will then read as may bytes as are programmed in the uDMA with a NACK on the last byte condition and a stop condition.

    So when you call I2CMasterControl() twice, once with I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START and then with I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH, you have run the uDMA twice. If that is not what you want, don't do that!

  • Susan Yang said:
    What model is this oscilloscope?

    Those images are from an Intronix LOGICPORT USB logic analyzer.

  • Thanks! It solved my problem!