FramShield Library
The FramShield Library can be downloaded here.
A pdf version of this documentation is available here.

FramShield uses your Arduinos two-wire interface, but does not require the Wire library.
In order to maximize efficiency, the FramShield library uses custom TWI transfers.
You can still use Wire, because the FramShield library was designed not to interfere with Wire.

The library defines an object, FramShield, with the following methods...
unsigned long Capacity();
boolean Plus();
void GoFast();
boolean Write();
boolean Read();
boolean Fill();
boolean ClockValid();
boolean SetClock();
boolean GetClock();
byte DayOfWeek();
boolean SetAlarm();
boolean AlarmControl();
byte WhichAlarm();
boolean SquareWave();
boolean EnableSquareWave();


A word to the wise.

When using constants to specify addresses or lengths, it is usually a good idea to use the suffix 'UL', to  force the compiler to generate an unsigned long (32 bit) value.

If left to 'guess', the compiler may generate a 16 bit value, which will not work correctly with memory sizes greater than 64K.


Status Section

byte FramShield.Version();

Returns the version number of the library.
The major version is in the upper nybble, minor version in the lower

unsigned long FramShield.Capacity();

Returns the total installed memory on the shield.

boolean FramShield.Plus();

Returns true if there is a hardware clock on board.

void FramShield.GoFast();

Causes FramShield to boost the TWI clock by 4x.
You only need call this once, during setup().
This will not affect use of the Wire library... Wire tranfers will remain at the 1x speed.

Storage Section

The FramShield library is designed to transfer large blocks of data between Arduino memory and FRAM.
Though it may be used to transfer single bytes, ints, longs and floats... it is at its most efficient when transferring larger blocks.
It is capable of a sustained transfer rate of 35 kilobytes per second when used this way.... smaller transfers will see a rate of 30k to 33k. 

boolean FramShield.Write(unsigned long fram_address, void pointer arduino_address, unsigned long length);

Write data from your Arduino to non-volatile memory.
'length' bytes of data are transferred from Arduino memory, begining at 'arduino_address', to FramShield memory beginning at 'fram_address'.
Returns false if the transfer would exceed the shields capacity.

An example...
void WriteExample(){
    byte b;
    int integer;
    long long_integer;
    float singlePrecision;
    float n[16][16];
    #define FLOATADDRESS 0x4000
    #define FLOATARRAY 0x6000

        FramShield.Write( 0UL,  &b, 1UL );
        
FramShield.Write( 1UL, &integer, sizeof integer );
        
FramShield.Write( 0x1000, &long_integer, sizeof long_integer );
        
FramShield.Write( FLOATADDRESS, &singlePrecision, sizeof singlePrecision);
        
FramShield.Write( FLOATARRAY, n, sizeof n);
}

boolean FramShield.Read(unsigned long fram_address, void pointer arduino_address, unsigned long length);

The inverse of Write().  Length bytes are copied from FRAM to Arduino.
Returns false if the operation would exceed the shields capacity.

boolean FramShield.Fill(unsigned long fram_address, unsigned long length, byte filler);

Fills FramShield memory with 'length' bytes of 'filler', starting at fram_address.
Returns false if the fill would exceed the shields capacity.

To 'wipe' your shields memory, use...
FramShield.Fill(0UL, FramShield.Capacity(), 0);



Time Section
Please note that if there is no hardware clock installed, time related methods will have undefined results.
Use the FramShield.Plus() function to determine whether the clock chip is installed.

The library uses a 6 byte array (which you create) to hold date-time values.
To make life easier for you, the library pre-defines array offsets, as listed here along with the legitimate range of values...

_second  0 thru 59
_minute 0 thru 59
_hour  0 thru 23
_day 1 thru 31
_month 1 thru 12
_year  0 thru 99


The hardware clock has no notion of Century, Daylight Savings, Local versus GMT, time zones & etc... though it does keep track of leap years.
Our TimeLord library provides many of these functions, if your sketch requires them.
The FramShield library was designed to 'play well' with TimeLord, so date-time arrays are interchangeable between FramShield and TimeLord.

boolean FramShield.ClockValid();

Returns true, unless the RTC chips internal power-failure detector has been tripped.
If this returns false, the RTC should not be trusted to have the correct time.
In order to clear this, you must set the clock.

If your shield is equipped with a supercapacitor, simply leave the shield powered for 15 minutes to recharge it.
If your shield is equipped with a battery, its time to change it.

boolean FramShield.SetClock( byte time[6]);

Sets the hardware Real Time Clock according to the date and time in the passed array, and clears the internal power-failure flag.
If the passed values make no sense, the operation is aborted, and false is returned.

Example: set the clock to midnight of Christmas day, 2009
byte xmas[6];
xmas[_second]=theTime[_minute]=theTime[_hour]=0;
xmas[_day]=25;
xmas[_month]=12;
xmas[_year]=9;
if(FramShield.SetClock(xmas)) {
    Serial.println("Clock is set to Xmas");
}
else{
    Serial.println("Could not set the clock");
}

boolean FramShield.getClock( byte time[6]);

Fill in the passed array with the current time from the Real Time Clock.

Example: Check whether is it Xmas day...
byte theTime[6];
FramShield.getClock(theTime);
if(theTime[_month]==12 && theTime[_day]==25) Serial.println("It's Xmas!!!!");

byte FramShield.DayOfWeek( byte time[6]);

This function is used internally by the library, and is exposed here for those who may find it convenient.
The return value ranges from 1 (Sunday) through 7 (Saturday).


Clock Signal Section

A word about Alarms, SquareWaves and Interrupts
The Real Time Clock chip, DS1337, provides two alarms, a squarewave generator, and two interrupt pins.
The relationship between them is somewhat complex.
This library attempts to hide most of that complexity from the typical user, without sacrificing flexibility for those who may need more from the chip.
In the following section, the default, simpler usage is described, with notes for the more advanced user in italics.

The two interrupt pins, INTA and INTB, are brought out to a 2 pin female header. The Arduino external interrupt pins are also brought out to an adjacent header, providing a convenient way to connect the RTC outputs to the Arduino... or not.

If you are using INTA or INTB, please note that you may need to enable the pull-up resistor on the corresponding Arduino pin.

Alarm 1 always outputs on INTA. The behavior of Alarm 2 depends on whether or not the SquareWave signal is enabled.

If the SquareWave is enabled, its signal will appear on INTB, and Alarm 2 will appear on INTA.
Otherwise, Alarm 2 will appear on INTB.



boolean FramShield.SetAlarm(byte which, byte time[6]);

Sets the time for an alarm, 'which' may be either 1 or 2.
For alarm 1, the second, minute, and hour are significant.
Alarm 2, however, ignores seconds.

Returns false if the passed values make no sense.

In some alarm modes, the day and seconds are significant.
In modes which use day/date, bit 6 of the passed date is used to discriminate between day(day of week) or date (day of month).
Clear bit 6 to indicate date, set bit 6 to indicate day of week.


boolean FramShield.AlarmControl(byte control);

Controls whether an alarm is enabled. Control is a bit mask.
The allowed values of control are...
0 (no alarms),
1 (Alarm 1 enabled),
2( Alarm 2 enabled)
3 (both alarms enabled).


If alarm 1 is enabled, it will trigger a signal on the INTA pin.
If alarm 2 is enabled, it may signal on either INTB (when the SquareWave is disabled), or on INTA (when the SquareWave is enabled).

Returns false if control is greater than 3.

byte FramShield.WhichAlarm();

Returns a bit mask indicating whether an alarm was tripped.
The possible values are...
0 (no alarm)
1 (Alarm 1 tripped),
2( Alarm 2 tripped)
3 (both alarms tripped).


void FramShield.AlarmMode(byte mode);

Sets the alarm mode.
Mode may be a value obtained from the DS1337 data sheet, using the bit values therin.
No sanity check is performed, you must be careful to use the correct value.
The mode for Alarm 2 is in the upper nybble, the lower nybble contains the mode for alarm 1.
The default mode for the library is 0x88.
The Alarm mode does not take effect until an alarm is set using SetAlarm().


boolean FramShield.SquareWave(byte freq);

Sets the frequency of the squarewave generator.
Possible values of freq are...
0:    1 hz
1:    4.096kHz
2:    8.192kHz
3:    32.768kHz

Returns false if freq is greater than 3.

void FramShield.EnableSquareWave(boolean enable);

Controls the output on the INTB pin.
If enable is true, the squarewave generator signal is output on INTB, and Alarm 2 will signal on INTA.
If enable is false, no signal is output from the squarewave generator, and Alarm 2 will signal on INTB.





Connections
As shown below, the 3.3 volt TWI signal is brought out to a 3 pin female connector at the top, Clocl, Ground, and Data.

The RTC alarms are available from the two pin female connector at the bottom, while Arduino interrupt inputs are available from the adjacent connector.
diagram