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.

LAUNCHXL-F28379D: I2C with interrupts - works with 400 kHz, but doesn't with 100 kHz.

Part Number: LAUNCHXL-F28379D
Other Parts Discussed in Thread: PCF8574

Hello everyone,

I wrote my own library to handle i2c based on your eeprom example which uses interrupts and API for 79D. This is code in main loop:

while(1)
    {
        counter++;
        uint16_t data[] = {0x0F, 0x1F, 0x2F, 0x3F, 0x4F};
I2C_lib_MasterWriteRead(&I2cMaster, SLAVE_ADDRESS, data, 5, 0); while (I2cMaster.status != I2CM_STATUS_READY); I2C_lib_MasterWriteRead(&I2cMaster, SLAVE_ADDRESS, data, 0, 5); while (I2cMaster.status != I2CM_STATUS_READY); I2C_lib_MasterWriteRead(&I2cMaster, EEPROM_ADDRESS, data, 2, 1); while (I2cMaster.status != I2CM_STATUS_READY); }

This code works perfectly when I2C is running on 400 kHz. But when I set I2C speed on 100 kHz it freezes on while loop after one transaction. It's working on 100 kHz when I put some delay between WriteRead functions, like:


for(i = 0; i < 100000); i++)
        counter++

But as I said, it's working on 400 kHz. I can see SDA line on my scope and on my logic analyzer. When running on 400 kHz everything is ok like start, ack and stop conditions.

I have no idea why it doesn't work on 100 kHz. I am using API which TI provided and I am using interrupts so single bits shouldn't bother me I suppose...

I appreciate any help.

BR,
Dawid.

PS:  my code is in an attachment.

pcf8574.zip

  • Hello,

    So you're saying it's getting stuck waiting for status to go to I2CM_STATUS_READY? Is the status supposed to be getting set in an ISR? Have you tried placing a breakpoint in the ISR to make sure it's getting there okay?

    Whitney
  • Also, make sure you're using the volatile keyword on your I2cMaster object. I don't know what optimization level you're using, but if you have the optimizer turned on, there's a chance status isn't getting reread as it sits in that loop.

    Whitney
  • Hello Whitney,

    I tried with volatile keyword on I2cMaster object but warning appeared:

    Description Resource Path Location Type
    #169-D argument of type "volatile I2C_Master_t *" is incompatible with parameter of type "I2C_Master_t *" main.c /pcf8574 line 35 C/C++ Problem

    Answering your previous questions:

    1) So you're saying it's getting stuck waiting for status to go to I2CM_STATUS_READY? - YES

    2) Is the status supposed to be getting set in an ISR? - YES

    3) Have you tried placing a breakpoint in the ISR to make sure it's getting there okay? - NO, to be honest, I don't know where I should pay my attention doing this.

    About optimization:

    I think it's turned off.

  • I declared my struct as: typedef volatile struct I2C_Master. Still it hangs, but I realised that something strange is happening. Take a look at the picture:

    Look at the readData table. readData is declared as unsigned char so it should be 8 bit value. But debugger shows 0x8A0B. How it is possible?

  • Hello,

    Since you have the optimizer off, the volatile isn't going to make a difference. It's something to look out of if you do turn the optimizer on later.

    On the C28, 16 bits is the smallest number of bits that can be separately addressed, so our chars and bytes are 16 bits. It is still possible to access data 8 bits at a time using the __byte() and __mov_byte() intrinsics though. You can read up on this a bit more in our compiler user's guide in the "TMS320C28x C/C++ Language Implementation" > "Data Types" chapter.

    www.ti.com/.../getliterature.tsp

    Whitney
  • Ok, I understand. 

    In the meantime I solved my problem. All I had to do was adding a loop in which I check stop condition status. Correct procedure looks like this:

    while(I2C_getStopConditionStatus(I2CA_BASE)) counter++;

    I2C_lib_MasterWriteRead(&I2cMaster, SLAVE_ADDRESS, data, 0, 5); while (I2cMaster.status != I2CM_STATUS_READY);

    Thank you very much for your help and important information. I very appreciate it.

    BR,

    Dawid.