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.

TMS320F28034: I2C EEPROM Random Read issue

Part Number: TMS320F28034

I'm working with I2C of TMS320F28034 to read and write data in a EEPROM AT24C08C.

I'm facing problem with ramdon read operation.

case 1)

following the sequence -> Write to Word Adress -> read from the same Word Adress -> reg (I2CDRR) is loaded with the right data. However the variable quadbyte            

is not loaded with the right data. I need to call the read function   Uint16 Reade2Prom(Uint16 e2promaddress) twice in order to get quadbyte = I2caRegs.I2CDRR;

is it right to check the flag      while(!I2caRegs.I2CSTR.bit.SCD); before quadbyte = I2caRegs.I2CDRR;?

case 2)

when the reas function Uint16 Reade2Prom(Uint16 e2promaddress) is called  to read a different  Word Adress it doesn't work I2CDRR is not updated.

There is something wrong in my code below?

Could someone help me with some example to perform these operations correctly?

for(;;)  //infinite loop

{           

if (FlagTestI2CREAD == 1)

{

 quadbyteTEST = Reade2Prom(e2promaddress);

 FlagTestI2CREAD = 0 ;

}

 

if (FlagTestI2CWRITE == 1)

{

 Write2Prom(e2promaddress,EEdata);

 FlagTestI2CWRITE = 0;

}

}

  

void I2CInit(void)

{

    I2caRegs.I2CMDR.bit.IRS = 0;

    I2caRegs.I2CPSC.all = 5; //

    I2caRegs.I2CCLKH = 21; //

    I2caRegs.I2CCLKL = 69; //

    I2caRegs.I2CIER.all     = 0x0000;   //

    I2caRegs.I2CFFTX.all    = 0x6040;

    I2caRegs.I2CFFRX.all    = 0x2040; //

    I2caRegs.I2CMDR.all     = 0x0020;

}

Uint16 Reade2Prom(Uint16 e2promaddress)

{

        Uint16 addresslow;

      Uint16 addresshigh;

 

       addresslow                = e2promaddress & 0x00FF;

       addresshigh               = (e2promaddress>>8) & 0x00FF;

       I2caRegs.I2CSAR     = EEPROM_ADDR;//0x0050;

 

       I2caRegs.I2CCNT           = 0x0002;

       I2caRegs.I2CDXR           = addresshigh;

       I2caRegs.I2CDXR           = addresslow;

       I2caRegs.I2CMDR.all = 0x2620; // Transmitter mode - master mode // START     

       while(!I2caRegs.I2CSTR.bit.ARDY);

 

       I2caRegs.I2CCNT           = 0x0001;

       I2caRegs.I2CMDR.all = 0x2C20; // Receiver mode - master mode // START -     

       while(!I2caRegs.I2CSTR.bit.SCD);

       quadbyte                = I2caRegs.I2CDRR;

       return(quadbyte);

 }

 

 

void Write2Prom(Uint16 e2promaddress, Uint16 EEdata)

{

       Uint16 addresslow;

       Uint16 addresshigh;

       addresslow                =  e2promaddress&0x00FF;

       addresshigh               = (e2promaddress>>8)&0x00FF;

       I2caRegs.I2CSAR     = EEPROM_ADDR;//0x0050;

       I2caRegs.I2CCNT           = 3    ;

       I2caRegs.I2CDXR           = addresshigh;

       I2caRegs.I2CDXR           = addresslow;

       I2caRegs.I2CDXR           = EEdata;

       I2caRegs.I2CMDR.all = 0x2E20; // Transmitter mode - master mode // START

       while(!I2caRegs.I2CSTR.bit.SCD);

       I2caRegs.I2CSTR.bit.SCD   = 1;

}

 

  • It would be better to wait for the RRDY bit to go high. Don't forget to manually clear it after you read the data.

    Is quadbyte a global variable? If so, make sure it's declared volatile, especially if you have compiler optimizations turned on.
  • Dear Adam, thanks for the support!

    1 - I made quadbyte a volatile global variable, but it  didn't solve the problem.

    2 -  I made addresshigh and addresslow a volatile global variable in order to debug.    

    I made some changes in the code to work without fifo, checking the flags RRDY and XRDY, see new code below.

    Please see the tests performed trying to solve the issue, but still without a solution.

    void I2CInit(void)

    {

       I2caRegs.I2CMDR.bit.IRS = 0;

       I2caRegs.I2CPSC.all = 5; //

       I2caRegs.I2CCLKH = 30;//

       I2caRegs.I2CCLKL = 60;//

       I2caRegs.I2CIER.all     = 0x0000;   // Disable all interrupts

       I2caRegs.I2CFFTX.all    = 0;//

       I2caRegs.I2CFFRX.all    = 0;//

       I2caRegs.I2CMDR.all     = 0x0020;

    }

    void Write2Prom(Uint16 e2promaddress, Uint16 EEdata)

    {

    addresshigh      = (e2promaddress & 0x0300) >> 8;

    addresslow = (e2promaddress & 0x00FF);

    I2caRegs.I2CSAR = EEPROM_ADDR;//0x0050;

    I2caRegs.I2CCNT = 3 ;

    I2caRegs.I2CDXR = addresshigh;

    I2caRegs.I2CMDR.all = 0x2E20; // Transmitter mode - master mode // START - slave address - n data bytes (I2CCNT) - STOP  //

       while(I2caRegs.I2CSTR.bit.XRDY == 0);

       I2caRegs.I2CDXR     = addresslow;

       while(I2caRegs.I2CSTR.bit.XRDY == 0);

       I2caRegs.I2CDXR     = EEdata;

       while(I2caRegs.I2CSTR.bit.XRDY == 0);

    }

    int16 Reade2Prom(Uint16 e2promaddress)

    {

       addresshigh      = (e2promaddress & 0x0300) >> 8;

       addresslow       = (e2promaddress & 0x00FF);

    I2caRegs.I2CSAR = EEPROM_ADDR;//0x0050;

    I2caRegs.I2CCNT = 0x0002;

    I2caRegs.I2CDXR = addresshigh;

    I2caRegs.I2CMDR.all = 0x2620; // Transmitter mode - master mode // START - slave address - n data bytes (I2CCNT) //

       while(I2caRegs.I2CSTR.bit.XRDY == 0);

       I2caRegs.I2CDXR     = addresslow;

       while(I2caRegs.I2CSTR.bit.XRDY == 0);

    I2caRegs.I2CCNT = 0x0001;

    I2caRegs.I2CMDR.all = 0x2C20; // Receiver mode - master mode // START - slave address - n data bytes (I2CCNT) - STOP //

       while(I2caRegs.I2CSTR.bit.RRDY == 0);

    quadbyte      = I2caRegs.I2CDRR;

    I2caRegs.I2CSTR.bit.RRDY = 1;

    return(quadbyte);

    }

    Some tests with stange behavior.

    1 –  In “TEST A”  read was performed:

    all EEPROM adressess in the range (0 - 255) returns the same value quadbyte = 55;

    all EEPROM adressess in the range (256 - 511) returns the same value quadbyte = 77;

    all EEPROM adressess in the range (512 - 767) returns the same value quadbyte = 254;

    all EEPROM adressess in the range (768 - 1023) returns the same value quadbyte = 77;

    2 –  In “TEST B”  write was performed  at some address in the range (768 - 1023) (ie. 1000) with the data value = 99

    3 –  In “TEST C”  read was performed:

    all EEPROM adressess in the range (0 - 255) returns the same value quadbyte = 55;

    all EEPROM adressess in the range (256 - 511) returns the same value quadbyte = 77;

    all EEPROM adressess in the range (512 - 767) returns the same value quadbyte = 255;

    the entire range (512 – 767) was changed unexpectedly;

    all EEPROM adressess in the range (768 - 1023) returns the same value quadbyte = 99;

    A single write operation was performed and the entire range (768 - 1023) returns the value that should be only in the selected adress (ie. 1000).

    4–  In “TEST D”  write was performed  at some address in the range (768 - 1023) (ie. 1000) with the data value = 88

    5 –  In “TEST E”  read was performed:

    all EEPROM adressess in the range (0 - 255) returns the same value quadbyte = 55;

    all EEPROM adressess in the range (256 - 511) returns the same value quadbyte = 77;

    all EEPROM adressess in the range (512 - 767) returns the same value quadbyte = 0;

    the entire range (512 – 767) was changed unexpectedly;

    all EEPROM adressess in the range (768 - 1023) returns the same value quadbyte = 88;

    A single write operation was performed and the entire range (768 - 1023) returns the value that should be only in the selected adress (ie. 1000).

  • I think you've misread the AT24C08C datasheet. The upper two bits of the word address are sent as part of the I2C (word) address. They're not sent as a data byte. Only the lower 8 word address bits are sent as a data byte. So your read sequence should be:

    Start - > Device address + 3 MSBs of word address (write) -> 8 LSBs of word address -> Start - > Device address + 3 MSBs of word address (read) -> 8 LSBs of word address -> EEPROM data -> Stop

    and your write byte sequence should be:

    Start - > Device address + 3 MSBs of word address (write) -> 8 LSBs of word address -> Data to write -> Stop
  • Dear Adam,

    Thank you very much.

    following your instructions i changed the code and now it is working.

    //========================================================

    int16 Reade2Prom(Uint16 e2promaddress)
    {

    addresshigh = (e2promaddress & 0x0300) >> 8;
    addresslow = (e2promaddress & 0x00FF);
    I2caRegs.I2CSAR = (EEPROM_ADDR | addresshigh);
    I2caRegs.I2CCNT = 0x0001;
    I2caRegs.I2CDXR = addresslow;
    I2caRegs.I2CMDR.all = 0x2620; // Transmitter mode - master mode // START - slave address - n data bytes (I2CCNT) //
    while(I2caRegs.I2CSTR.bit.XRDY == 0);

    I2caRegs.I2CCNT = 0x0001;
    I2caRegs.I2CMDR.all = 0x2C20; // Receiver mode - master mode // START - slave address - n data bytes (I2CCNT) - STOP //
    while(I2caRegs.I2CSTR.bit.RRDY == 0);
    quadbyte = I2caRegs.I2CDRR;
    I2caRegs.I2CSTR.bit.RRDY = 1;
    return(quadbyte);

    }

    //========================================================

    void Write2Prom(Uint16 e2promaddress, Uint16 EEdata)
    {

    addresshigh = (e2promaddress & 0x0300) >> 8;
    addresslow = (e2promaddress & 0x00FF);
    I2caRegs.I2CSAR = (EEPROM_ADDR | addresshigh);
    I2caRegs.I2CCNT = 2 ;
    I2caRegs.I2CDXR = addresslow;
    I2caRegs.I2CMDR.all = 0x2E20; // Transmitter mode - master mode // START - slave address - n data bytes (I2CCNT) - STOP //
    while(I2caRegs.I2CSTR.bit.XRDY == 0);
    I2caRegs.I2CDXR = EEdata;
    while(I2caRegs.I2CSTR.bit.XRDY == 0);

    }