DS1307 NV SRAM need some help

Hi Guys,

I succeeded in writing and reading data back from the DS1307 NV SRAM. The way I did was like:


// Write Data
    public void SaveData(int eled, int elen, int gas, int wat)
    {
      xaction = new I2CDevice.I2CWriteTransaction[1];
      byte[] sb = new byte[17] { 0x08, 
                                WriteInt32(eled)[0],
                                WriteInt32(eled)[1],
                                WriteInt32(eled)[2],
                                WriteInt32(eled)[3],
                                WriteInt32(elen)[0],
                                WriteInt32(elen)[1],
                                WriteInt32(elen)[2],
                                WriteInt32(elen)[3],
                                WriteInt32(gas)[0],
                                WriteInt32(gas)[1],
                                WriteInt32(gas)[2],
                                WriteInt32(gas)[3],
                                WriteInt32(wat)[0],
                                WriteInt32(wat)[1],
                                WriteInt32(wat)[2],
                                WriteInt32(wat)[3]
                                };

      xaction[0] = I2CDevice.CreateWriteTransaction(sb);
      if (I2C.Execute(xaction, 1000) == 0)
      {
        new Exception("Failed to send I2C data");
      }
    }

// Read Data
    public int[] ReadData()
    {

      xaction = new I2CDevice.I2CTransaction[2];
      xaction[0] = I2CDevice.CreateWriteTransaction(new byte[] { 0x08 });
      byte[] RetCounters = new byte[16];
      xaction[1] = I2CDevice.CreateReadTransaction(RetCounters);
      if (I2C.Execute(xaction, 1000) == 0)
      {
        new Exception("Failed to send I2C data");
      }
      byte[] eled = new byte[4] {RetCounters[0], RetCounters[1], RetCounters[2], RetCounters[3]};
      byte[] elen = new byte[4] { RetCounters[4], RetCounters[5], RetCounters[6], RetCounters[7] };
      byte[] gas = new byte[4] { RetCounters[8], RetCounters[9], RetCounters[10], RetCounters[11] };
      byte[] wat = new byte[4] { RetCounters[12], RetCounters[13], RetCounters[14], RetCounters[15] };

      int[] vals = new int[4] { ReadInt32(eled, 0), ReadInt32(elen, 0), ReadInt32(gas, 0), ReadInt32(wat, 0)  };
     return vals;
    }

// helpers
    private static byte[] WriteInt32(int value)
    {
      byte[] result = new byte[4];
      result[0] = (byte)((value & 0xFF000000) >> 24);
      result[1] = (byte)((value & 0x00FF0000) >> 16);
      result[2] = (byte)((value & 0x0000FF00) >> 8);
      result[3] = (byte)((value & 0x000000FF));

      return result;
    }

    public static int ReadInt32(byte[] buf, int offset)
    {
      return (buf[offset + 0] << 24) + (buf[offset + 1] << 16) + (buf[offset + 2] << 8) + (buf[offset + 3]);
    }

Now seen that this is somehow limited, I’m looking for a more general approach.
In the code above I’m only using 16 bytes out of a total available of 56 bytes. I would like to use the remaining 40 bytes (in the future) and therefor it would be nice if I can prepare my code now (instead of modifying it later). One nice issue that I’ve read in the DS1307 datasheet is:

Once we can come up with a nice solution I will update the ds1307 driver on code.tinyclr.com so everyone can benefit from this.

One solution I have in mind is working with an address table, so we know what data goes where:



    // Value1 to Value4 are in this case Int32 (4bytes)
    public enum ValueAddress
    {
      Value1 = 0x08,
      Value2 = 0x12,
      Value3 = 0x16,
      Value4 = 0x20
    }

Are there other solutions?

Greetings,
Eric

Possble to offload to a CPLD?

Arduino SRAM Expansion: Featuring the Amani 64 CPLD Shield
[url]http://majolsurf.net/wordpress/?page_id=1001[/url]

I don’t need another hardware solution, but looking for a more user-friendly software approach, so that anyone who incorporates the DS1307 in their project can use the 56byte storage.

Why? This is a 72mhz 32-bit processor :slight_smile:

Apologies for jumping in too quick. Now I see, 56-bytes!

You need to separate your business logic from the read/write process. I suggest you create a driver that only exposes this methods (+ one extra for I2C initialization).


bool Write(byte[] bytes, byte startAddress);
bool Write(byte[] bytes, byte offset, byte count, byte startAddress);
byte[] Read(byte startAddress, byte count);

The start address should be always >= 0x08 and startAddress + count should be <= 0x40

Than you can encapsulate you business logic int some other class and select where and how are you goinf to store and retrieve the data. This you almost already have.

Gralin,

can you elaborate a bit on your 2nd Write line? The 1st Write and the Read line are clear to me.

Thanks in advance

The second line is just a overload to make the class more user friendly. Sometime you have an array but you want to write only part of it. Since this is not regular .NET you don’t want to create another array with only those bytes you are interested in. In that case the second Write method let’s you specify the data source (bytes), tell it where the data starts (offset) and how much data you want to write (count).

You could add more overloads with different parameters, like int[] for example…

And then there is the 2 kB RTC SRAM on the processor for more information.

Copy form the data sheet:
[italic]The Battery RAM is a 2 kbyte static RAM residing on the APB bus. The address range is
0xE008 4000 to 0xE008 47FF. The SRAM can be accessed word-wise (32-bit) only.

The Battery RAM is powered from the VBAT pin along with the RTC, both of which exist in
a power domain that is isolated from the rest of the chip. This allows them to operate while
the main chip power has been removed.[/italic]

It can be accessed in the same way as Gralin describes.

On what page do you see that?

The only Maxim RTC’s that have 2kb ram are the DS32B35 and DS32C35

He’s talking about the 2KB SRAM in the LPC2387 (USBizi) chip.

Indeed he did, all Fezzez (except for the mini) have an RTC built in.
Just connect a battery or a special C.