i2c eeprom only return 0xff

Discussion in 'General Electronics Chat' started by omolhs, Aug 4, 2013.

  1. omolhs

    Thread Starter New Member

    Aug 3, 2013
    2
    0
    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.

    Code ( (Unknown Language)):
    1.  
    2. unsigned char WRITE_READ(unsigned int address, unsigned char data_in)
    3. {
    4.     unsigned char adress_msb, adress_lsb;
    5.     unsigned char data_out;
    6.    
    7.     adress_msb = address / 256;
    8.     adress_lsb = address % 256;
    9.    
    10.     // start write
    11.    
    12.     unsigned char write_complete = 0;
    13.    
    14.     while ( write_complete == 0 )
    15.     {
    16.         I2C_Start();
    17.        
    18.         while ( I2C_Write_Byte(ADDRESS_WRITE) == 1 )      
    19.         {
    20.             I2C_Start();
    21.         }        
    22.        
    23.         if ( I2C_Write_Byte(adress_msb) == 0 )
    24.         {
    25.              if ( I2C_Write_Byte(adress_lsb) == 0 )
    26.              {
    27.                  if ( I2C_Write_Byte(data_in) == 0 )
    28.                  {
    29.                      write_complete = 1;
    30.                  }    
    31.              }
    32.          }        
    33.          
    34.          I2C_Stop();
    35.     }    
    36.    
    37.     // start read
    38.    
    39.     write_complete = 0;
    40.    
    41.     while ( write_complete == 0 )
    42.     {
    43.         I2C_Start();
    44.         while ( I2C_Write_Byte(ADDRESS_WRITE) == 1 )      
    45.         {
    46.             I2C_Start();
    47.         }    
    48.        
    49.         if ( I2C_Write_Byte(adress_msb) == 0 )
    50.         {
    51.              if ( I2C_Write_Byte(adress_lsb) == 0 )
    52.              {
    53.                  I2C_Start();
    54.                  if ( I2C_Write_Byte(ADDRESS_READ) == 0 )
    55.                  {
    56.                      data_out = I2C_Read_Byte();
    57.                      write_complete = 1;
    58.                  }
    59.              }
    60.          }    
    61.          
    62.         I2C_Send_NACK();
    63.         I2C_Stop();    
    64.     }
    65.        
    66.     return data_out;
    67. }
    68.  

    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:

    Code ( (Unknown Language)):
    1.  
    2.     j=0;
    3. [LEFT]        for (i=0;i<256;i++)
    4.         {
    5.             I2C_Start();
    6.             if ( I2C_Write_Byte(i) == 0 )
    7.             {
    8.                 ADDRESS[j] = i;
    9.                 j++;
    10.             }
    11.         }
    12. [/LEFT]



    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!!!
     
    Last edited by a moderator: Aug 4, 2013
  2. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,392
    1,606
    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:

    Code ( (Unknown Language)):
    1.  
    2.     #define ADDRESS_WRITE 0xA0
    3.  
    4.     #define ADDRESS_READ  0xA1
    The code outline would work like so:

    Code ( (Unknown Language)):
    1.  
    2.     I2C_Start();
    3.  
    4.     I2C_Write_Byte(ADDRESS_WRITE)
    5.        
    6.     I2C_Write_Byte(address_msb)
    7.        
    8.     I2C_Write_Byte(address_lsb)
    9.  
    10.     I2C_Start();
    11.  
    12.     I2C_Write_Byte(ADDRESS_READ)
    13.  
    14.     data_out = I2C_Read_Byte();
    15.  
    16.     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.
     
  3. omolhs

    Thread Starter New Member

    Aug 3, 2013
    2
    0
    Thank you so much!!!
     
Loading...