Main Site Documentation

Writing Data to EEPROM Register Address


#1

I am stuck on a seemingly simple operation. I am using the 24FC256 I2C EEPROM where the A0,A1,and A2 pins are wired to ground, creating an I2C address of 0x50. I am able to create my EEPROM object just fine but the issue comes into play when I try to do EEPROM.Write(int address, byte data). I receive an ArgumentException from a command such as Write(0,bytes[1]) where bytes[1] is an int converted.

How are my inputs to Write() wrong?


#2

ok look at that - you started your own thread. Great ! I’d stop asking the same question in multiple places in future.

Where’s the driver?


#3

bytes[1] may not be what you think it is. That is the most likely argument that is causing an exception. Just test simply - write a block of data, 0 in address 0, 1 in 1 etc, and then read it back. Prove the simple stuff works, then move on to writing your own data, then move on to reading your own data back


#4

So would that just be EEPROM.Write(0,0)?

And yes I created my own thread because although the one I originally posted in was the exact same setup, I realized people are MUCH faster to respond to a new topic. I will refrain from posting in multiple places…unless I am stuck and in an extreme hurry like today. Here is the driver I have been using, can’t find the original link because all of code share seems broken / missing.

/*
 Copyright 2010 Christophe Gerbier
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance             with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an         "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
*/

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

namespace PandaMotorsDriver
{
 /// <summary>
/// PandaEEprom class
/// </summary>
public class PandaEEprom
{
    private static I2CDevice.Configuration I2CConfig;
    private static I2CDevice I2C;

    /// <summary>
    /// Initializes a new instance of the <see cref="PandaEEprom"/> class.
    /// </summary>
    public PandaEEprom(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 !!!
    }

    /// <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 !!!
    }

    /// <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);
        xActions[0] = I2CDevice.CreateReadTransaction(Data);
        I2C.Execute(xActions, 1000);

        return Data[0];
    }
}

}


#5

This doesn’t guarantee that you know if the I2C transaction worked. Update any Executes with this block:

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


#6

Could this be an issue with an eight bit address versus a seven bit address? Or is this only an issue with SPI?


#7

Ok thank you I will implement that now. To write a 0 to block 0 like you said, is that just Write(0,0)? I get really confused with all these different address formats.


#8

This is using I2C and I have no idea what I am doing wrong lol.


#9

How am I obtaining RegisterValue[0] after attempting the execution?


#10

it’s ok, we figured that out too :wink:

It’s unlikely to be the 7-bit vs 8-bit address thing, but it could be… that’s why the debug output of transactions working or not is important. I looked at the old doco page https://old.ghielectronics.com/docs/12/i2c to see what I had modified in the earlier GHI doco for transaction checking, and there’s also text there about 7-bit addressing.

For RegisterValue, look at the full code example in the link above


#11

Ok I will go through that doc first thing tomorrow morning. Can you think of any other possible errors besides 7bit/8bit?


#12

only what you’re passing in :slight_smile:

It’s either addressing (and you’ll see that because all transactions fail, none work - but that could also identify you have a wiring issue) or it’s that you’re passing the wrong data in, hence my suggestion to go back to simple steps first.


#13

The following line in the write code posted above seems not to make sense with an address of 0x50? Unless I2C can have a sixteen bit address?

buffer[0] = (byte)(Address >> 8);


#14

@Mike that is the address in the EEPROM not the I2C address


#15

AH! That makes sense…


#16

Would I be able to create the EEPROM I2C Object if there was a wiring issue? In other interfaces it usually gives a hardware error. I actually had a loose wire before I posted this but once I pushed it in I stopped getting the hardware exception and began getting the ArgumentException we have been discussing.


#17

This is one part I have been confused about, why is this in the Read() part of that driver? Trying to figure out a could place to create RegisterValue


#18

I tried writing Write(0,bytes[0]) where bytes[0]=BitConverter(0); and still get the same error.

One possible thing it could be is the fact I didn’t use pull down resistors on A0-A2 - my electrical engineer said it wouldn’t make a difference if I went straight to ground but maybe he was wrong. It’s such a simple chip to set up…that’s the only mistake I can see. Much easier than that damned L6470…and soon I will be damning the FT232’s tininess.


#19

As far as wiring goes: I have A0,A1,A2,Vss, and WP (enables writing when low) all wired to ground (Pins 1,2,3,4, and 7). Vcc (pin 8) is +5V, SCL goes to the SCL pin on uC, SDA goes to SDA pin on uC and is pulled high with a 2k ohm resistor to Vcc.

Literally the only deviation is lack of pulldown resistors on Pins 1-3.


#20

Wiring pins 1-3 to ground will not make a functional difference. The pulldowns may be useful for testing purposes a board manufacturing test.