cancel
Showing results for 
Search instead for 
Did you mean: 

I2C and M24C16

enrico2399
Associate II
Posted on November 02, 2005 at 06:45

I2C and M24C16

3 REPLIES 3
enrico2399
Associate II
Posted on October 26, 2005 at 08:12

Hi All,

I've got a problem writing and reading data with a M24C16 eeprom. Following previous forum discussions, I've tested the examples posted by RISC (I2Ceeprom.zip + i2c_byteread.zip) introducing lib modifications and fixes: I've always the problem that polling eeprom busy sequence (during write operations) exit immediately. Executing step-by-step I've no problem in read/write operations, while executing at full speed read after write doesn't work properly (it returns 0xFF for every byte).

Also sjofix doesn't change the result.

Maybe it's an already posted question but I'd appreciate a suggestion.

Thanks

Have you got an example of ''read-after-write operation'' with lib fixes included?

enrico2399
Associate II
Posted on October 26, 2005 at 11:57

Hi Risc,

thank you very much for your support: I've tested your new code but the problem still arises. I've modified EEPROM_WaitForlastTask function adding a counter for every time I cycle polling the eeprom but I always exit at first run. I've also modified I2C_FlagStatus (in i2c.c) to loop if I detect an ACK failure (as I'd expect when writing is in progress) but it never happens. If I introduce a bare delay after writing everything is ok.

I'm not able to detect the correct acknoledge failure during the polling phase. Maybe I've got to investigate the problem with the scope, but I don't think it's an hw problem.

I'm using keil compiler v2.40a and keil mcbrstr7 evb.

Thanks for your help,

Enrico

enrico2399
Associate II
Posted on November 02, 2005 at 06:45

Hi all,

I've test the code and I suggest to modify the function to check the busy state of the eeprom: the while loop used to check for end of address tx will clear the acknoledge failure flag in register SR2, so you exit the loop always at first time.

do

{

cnt++;

I2C_STARTGenerate( I2C0, ENABLE );

while( I2C_FlagStatus( I2C0, DIRECT, I2C_SB) == RESET );

I2C_AddressSend( I2C0, M24C08_Block3ADDRESS, I2C_Mode7, I2C_TX );

while(!((I2CStatus = I2C_GetStatus( I2C0 ))& I2C_EVF));

while( I2C_FlagStatus( I2C0, DIRECT, I2C_ENDAD ) ==RESET );

I2C_FlagClear( I2C0, I2C_ENDAD );

} while( I2C_FlagStatus( I2C0, INDIRECT, I2C_AF, I2CStatus ) == SET );

I suggest this code, where after sending the address you check directly SR1 for EVF and then SR2 for AF. In case of AF == 0 you exit the infinite while.

do

{

cnt++;

I2C_STARTGenerate( I2C0, ENABLE );

while( I2C_FlagStatus( I2C0, DIRECT, I2C_SB) == RESET );

I2C_AddressSend( I2C0, M24C08_Block3ADDRESS, I2C_Mode7, I2C_TX );

while(((I2CStatus = I2C0->SR1) & I2C_EVF) == 0);

if(((I2CStatus = I2C0->SR2) & 0x10) == 0) {

cnt++;

I2C_FlagClear( I2C0, I2C_ENDAD );

break;

}

I2C_FlagClear( I2C0, I2C_ENDAD );

} while(1);

Hope this is useful.

Regards,

Enrico