i2c eeprom only return 0xff

Thread Starter

omolhs

Joined Aug 3, 2013
2
Hello,

This is my first time posting so i hope i do this right.

i am trying to write and then read a value from a FM24C64 EEPROM but all i receive is 0xff.

I am using bit-banging routines that i have used before successfully.
I attached the bit-banging routines and the datasheet for the EEPROM.

here is my code that i am trying to use to do a simple read-write.
you will notice that in order to confirm that there is an ACK i placed them in a if-loop and checked with the deubbuger that it ran all the way through the code. and it did, but it still will only return 0xff.

Rich (BB code):
unsigned char WRITE_READ(unsigned int address, unsigned char data_in)
{
    unsigned char adress_msb, adress_lsb;
    unsigned char data_out;
    
    adress_msb = address / 256;
    adress_lsb = address % 256;
    
    // start write
    
    unsigned char write_complete = 0;
    
    while ( write_complete == 0 )
    {
        I2C_Start();
        
        while ( I2C_Write_Byte(ADDRESS_WRITE) == 1 )      
        {
            I2C_Start();
        }        
        
        if ( I2C_Write_Byte(adress_msb) == 0 )
        {
             if ( I2C_Write_Byte(adress_lsb) == 0 )
             {
                 if ( I2C_Write_Byte(data_in) == 0 )
                 {
                     write_complete = 1;
                 }    
             }
         }        
         
         I2C_Stop();
    }    
    
    // start read
    
    write_complete = 0;
    
    while ( write_complete == 0 )
    {
        I2C_Start();
        while ( I2C_Write_Byte(ADDRESS_WRITE) == 1 )       
        {
            I2C_Start();
        }    
        
        if ( I2C_Write_Byte(adress_msb) == 0 )
        {
             if ( I2C_Write_Byte(adress_lsb) == 0 )
             {
                 I2C_Start();
                 if ( I2C_Write_Byte(ADDRESS_READ) == 0 )
                 {
                     data_out = I2C_Read_Byte();
                     write_complete = 1;
                 }
             }
         }    
         
        I2C_Send_NACK();
        I2C_Stop();    
    }
        
    return data_out;
}

i have a scope incase any data from a scope is needed.

but so far i have tried everything i can read on forums but cant seem to solve this problem!

to confirm that the EEPROM is responding and that the setup is ok i ran this code:

Rich (BB code):
    j=0;
for (i=0;i<256;i++) { I2C_Start(); if ( I2C_Write_Byte(i) == 0 ) { ADDRESS[j] = i; j++; } }​



and the ADDRESS array had 2 values, address_write and address_read of the EEPROM, so i know that the EEPROM is ACKing at least the first byte.

i also attached the scope view of the function (in a zip)

as you can see, there is an ack at the first few commands, but when trying to read, after the address_lsb is sent, there is no ack!
i cant figure out why.

(possibly i misunderstand the scope)

I would really appreciate any and all help!!!
 

Attachments

Last edited by a moderator:

ErnieM

Joined Apr 24, 2011
8,377
To read data back you have to perform the tasks as given in the data sheet Figure 9 for Selective (Random) Read (on sheet 7). In your code it seems you are (quite properly!) checking the NAK bit to see if the transaction is going well. I would suggest forgoing this until you get the code working, then add in the protections.

(Aside: this is the sort of task I find difficult to do cleanly in C. It needs either a goto or some auxiliary variable to flow thru the various error tests.)

The write to a memory follows a simple logical pattern:

write to address the device
write to set (hi) sub address
write to set (lo) sub address
write to set data
(repeat write data if required)

A read is not so intuative:

write to address the device
write to set (hi) sub address
write to set (lo) sub address
restart
read to get data
(repeat read data if required)

So you need to write in order to read; that always made my head spin.

Write and Read addresses are like so for A0=A1=A2=ground:

Rich (BB code):
    #define ADDRESS_WRITE 0xA0

    #define ADDRESS_READ  0xA1
The code outline would work like so:

Rich (BB code):
    I2C_Start();

    I2C_Write_Byte(ADDRESS_WRITE)
        
    I2C_Write_Byte(address_msb)
        
    I2C_Write_Byte(address_lsb)

    I2C_Start();

    I2C_Write_Byte(ADDRESS_READ)

    data_out = I2C_Read_Byte();

    I2C_Stop();
That should report back good data to your micro, or give you something to check with your scope. When it is clean then add in the NAK error checks.
 
Top