Writing Data to EEPROM Register Address

Maybe the EEPROM itself is bad?

Yes, it will.

Well because a READ of the EEPROM requires you to WRITE to the EEPROM Control registers, and then read back the data you want.

You had one simple test to do that would tell you whether you were talking to the eeprom or not - add the debugging in on the return from execute. Whats the status of that???

I added the code you told me to but that part gets skipped over after the exception is triggered. It fails at Execute according to the stack trace.

I double checked the wiring and everything looks good and corresponds to the instructions in the datasheet.

then clearly you are still passing incorrect parameters to the call !

step back to the basics please, write a stand alone app that just passes “good” values in.

I have had this in a standalone app the whole time. All I am doing is putting a 0 into a byte array and writing that respective array index to either address 0 or 1. Still getting the same error. I’ll post my code in a few minutes.

Does SCL need a pull up resistor? The datasheet only says SDA needs a pull up but only has one sentence about SCL.

SCL is driven by the micro, so no it does not need pull-up/down

I read online that since its open drain it needs one or else it cant be pulled high to initiate a start/stop flag, I haven’t had a chance to try it though because I had to help make 475 MIMICs lol, CRAZY.

Do you have any other suggestions?

SDA is open drain. SCL is an input, and nowhere in the datasheet does it say it is open drain

Yes, SHOW US YOUR TEST APP CODE.

This is the first free moment I have had all day…they had me on assembly for a million dollar order.

 using System;
 using Microsoft.SPOT;
 using System.Threading;

namespace MFConsoleApplication2
{
public class Program
{
   
    
    public static void Main()
    {
        try
        {
            int y = 1;
         
           // var bytes = new byte[TabsFinal.Length * sizeof(int)];
           // bytes= BitConverter.GetBytes(y);
            //for (int x = 0; x < Tabs.Length; x++)
            //{
            //    Array.Copy(BitConverter.GetBytes(TabsFinal[x]), 0, bytes, x * sizeof(int), sizeof(int));
            //}
            EEPROM memory = new EEPROM(0x50, 1000);
            memory.Write(0, "10");
           // for (var j = 0; j < bytes.Length; j++)
          //  {
            //    memory.Write(j, bytes[1]);
            //    Thread.Sleep(5);
           // }

          //  var buffer = memory.Read(0x50);
            //   var results=new int[buffer.Length/sizeof(int)];
            //for (var i=0; i<results.Length;i++){
            //results[i]=BitConverter.ToInt32()
            //}
        }
        catch(Exception ex)
        { Debug.Print(ex.ToString()); }
    }
}
    namespace MFConsoleApplication2
 {
        /// <summary>
     /// EEprom class
     /// </summary>
public class EEPROM
{
    private static I2CDevice.Configuration I2CConfig;
    private static I2CDevice I2C;

        /// <summary>
    /// Initializes a new instance of the <see cref="EEPROM"/> class.
    /// </summary>
    public EEPROM(byte Address, int ClockRateKHz)
    {
        I2CConfig = new I2CDevice.Configuration((ushort)(Address >> 1), ClockRateKHz);  // 400 KHz, A0-A2 shorted to ground (by design) = 0x50
        I2C = new I2CDevice(I2CConfig);
    }

    /// <summary>
    /// Writes a one byte data at the specified address.
    /// </summary>
    /// <param name="Address">The address to write to.</param>
    /// <param name="data">The byte to write</param>
    public void Write(int Address, byte data)
    {
        var xActions = new I2CDevice.I2CTransaction[1];
        xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF), data });
     
       // I2C.Execute(xActions, 1000);
      //  Thread.Sleep(5); // Mandatory after each Write transaction !!!
        if (I2C.Execute(xActions, 1000) == 0)
        {
            Debug.Print("Failed to perform I2C transaction");
        }
        
        var Data = new byte[1];
        xActions[0] = I2CDevice.CreateReadTransaction(Data);
        I2C.Execute(xActions, 1000);
        Thread.Sleep(5);

        if (I2C.Execute(xActions, 1000) == 0)
        {
            Debug.Print("Failed to perform I2C transaction");
        }
        else
        {
            Debug.Print("Register value: " + Data[0].ToString());
        }
      
    }

    /// <summary>
    /// Writes the string Text at the specified address.
    /// </summary>
    /// <param name="Address">The starting address to write to</param>
    /// <param name="Text">The text to write to EEprom</param>
    public void Write(int Address, string Text)
    {
        var Addr = Address;
        var xActions = new I2CDevice.I2CTransaction[1];
        byte[] buffer = System.Text.Encoding.UTF8.GetBytes("00" + Text);  // the "00" string reserves the room for the 2 bytes address that follows
        buffer[0] = (byte)(Address >> 8);
        buffer[1] = (byte)(Address & 0xFF);
        xActions[0] = I2CDevice.CreateWriteTransaction(buffer);
        //I2C.Execute(xActions, 1000);
   //     Thread.Sleep(5); // Mandatory after each Write transaction !!!
        if (I2C.Execute(xActions, 1000) == 0)
        {
            Debug.Print("Failed to perform I2C transaction");
        }
        var Data = new byte[1];
        xActions[0] = I2CDevice.CreateReadTransaction(Data);
        I2C.Execute(xActions, 1000);
        Thread.Sleep(5);
        if (I2C.Execute(xActions, 1000) == 0)
        {
            Debug.Print("Failed to perform I2C transaction");
        }
        else
        {
            Debug.Print("Register value: " + Data[0].ToString());
        }
    }

    /// <summary>
    /// Reads the specified address.
    /// </summary>
    /// <param name="Address">The address to be read</param>
    /// <returns>One byte from the EEprom</returns>
    public byte Read(int Address)
    {
        var Data = new byte[1];
        var xActions = new I2CDevice.I2CTransaction[1];
        xActions[0] = I2CDevice.CreateWriteTransaction(new byte[] { (byte)(Address >> 8), (byte)(Address & 0xFF) });
        Thread.Sleep(5);   // Mandatory after each Write transaction !!!
        I2C.Execute(xActions, 1000);
        if (I2C.Execute(xActions, 1000) == 0)
        {
            Debug.Print("Failed to perform I2C transaction");
        }
        xActions[0] = I2CDevice.CreateReadTransaction(Data);
        I2C.Execute(xActions, 1000);
        if (I2C.Execute(xActions, 1000) == 0)
        {
            Debug.Print("Failed to perform I2C transaction");
        }
        else
        {
            Debug.Print("Register value: " + Data[0].ToString());
        }
        return Data[0];
    }
     }
}  

 }

EEPROM memory = new EEPROM(0x50, 400);

And

public EEPROM(byte Address, int ClockRateKHz)
{
    I2CConfig = new I2CDevice.Configuration((ushort)Address, ClockRateKHz);  // 400 KHz, A0-A2 shorted to ground (by design) = 0x50
    I2C = new I2CDevice(I2CConfig);
}
1 Like

Slight improvement with matching the clock frequencies to 400 - it now does not give me the argument exception, it actually makes it through the if else statements and triggers “Failed I2C transaction.” Still not working but one step closer now, thank you.

I lowered Vcc down to 2 V to match the 400 kHz clock speed. Not sure what to do next.

I removed the left shift like you did and it successfully wrote and returned a register value. Not sure if it was the correct value yet but yay!

I wrote a 0 and it returned a register value of 255. Thats not right is it?

Still stuck on this. Not sure why I only get 255 back

I successfully wrote a 1 to address 5 but now I can’t get anything else to write :frowning: it keeps reading back the same values…46 255 255 255 1. I also wrote the 46 when trying to write multiple bytes but that was the only one that actually wrote and haven’t gotten past that. attached is my screen shot of my SDA line, haven’t gotten the second channel to work simultaneously on the scope yet so I can’t show SCL at the same time until I get some help tomorrow.

I think I have a 24LC256 around here somewhere but I can’t lay my hands on it to do a benchmark test to compare - I’m still searching (but if you saw my bench you’d understand that it’s non trivial :slight_smile: )

So can you please point out WHY you did that? Have you un-done it? From the Microchip datasheet for 24XX256 I can see 400khz maximum is fine for 2.5v to 5.5v, so going to 2v is out of spec. http://ww1.microchip.com/downloads/en/DeviceDoc/20001203U.pdf

edit: I see you have the FC part. That does nemtion having a 1.7v to 2.5v power for 400khz (max) so I assume that you can still power with 3.3v where the max is listed as 1000khz, and run it at 400khz which is below the maximum…

and can you confirm what you did with the WP pin? Tied to GND or VCC?