An archive of community.esquilo.io as of Saturday January 26, 2019.

Stuck on port of Adafruit FRAM library

softwarejanitor

I'm not having any luck getting this to work... Maybe someone who knows the Esquilo I2C library and the Arduino Wire library can look at it and tell me what I am doing wrong. It seems so easy but I've tried all kinds of things and can't get it to work.

Here's the ported code so far...

/**************************************************************************
@file Adafruit_FRAM_I2C.nut
@author KTOWN (Adafruit Industries)
Ported from Arduino to Esquilo by Leeland Heins
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, Adafruit Industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
( NCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*************************************************************************/

const MB85RC_DEFAULT_ADDRESS = 0x50; /* 1010 + A2 + A1 + A0 = 0x50 default */
const MB85RC_SLAVE_ID = 0xF8;

class Adafruit_FRAM_I2C
{
i2c = null;
addr = null;
_framInitialised = false;

manufacturerID = null;
productID = null;

constructor (_i2c, _addr)
{
    i2c = _i2c;
    addr = _addr;
}

};

/*========================================================================*/
/* PUBLIC FUNCTIONS */
/*========================================================================*/

/**************************************************************************
Initializes I2C and configures the chip (call this function before
doing anything else)
**************************************************************************/
function Adafruit_FRAM_I2C::begin()
{
/* Make sure we're actually connected */
getDeviceID();
if (manufacturerID != 0x00A) {
print("Unexpected Manufacturer ID: 0x" + manufacturerID + "\n");
return false;
}
if (productID != 0x510) {
print("Unexpected Product ID: 0x" + productID + "\n");
return false;
}

/* Everything seems to be properly initialised and connected */
_framInitialised = true;

return true;

}

/**************************************************************************
@brief Reads an 8 bit value from the specified FRAM address
@params[in] i2cAddr
The I2C address of the FRAM memory chip (1010+A2+A1+A0)
@params[in] framAddr
The 16-bit address to read from in FRAM memory
@returns The 8-bit value retrieved at framAddr
**************************************************************************/
function Adafruit_FRAM_I2C::write8(framAddr, value)
{
i2c.address(addr);
i2c.write8(0x00, 0xa0);
i2c.write8(0x01, framAddr >> 8);
i2c.write8(0x02, framAddr & 0xFF);
delay(5);
i2c.write8(0x00, value);
}

/**************************************************************************
@brief Reads an 8 bit value from the specified FRAM address
@params[in] i2cAddr
The I2C address of the FRAM memory chip (1010+A2+A1+A0)
@params[in] framAddr
The 16-bit address to read from in FRAM memory
@returns The 8-bit value retrieved at framAddr
**************************************************************************/
function Adafruit_FRAM_I2C::read8(framAddr)
{
i2c.address(addr);
i2c.write8(0x00, 0xa0);
i2c.write8(0x01, framAddr >> 8);
i2c.write8(0x02, framAddr & 0xFF);
i2c.write8(0x03, 0xa1);
delay(5);
return i2c.read8(0x00);
}

/**************************************************************************
@brief Reads the Manufacturer ID and the Product ID from the IC
@params[out] manufacturerID
The 12-bit manufacturer ID (Fujitsu = 0x00A)
@params[out] productID
The memory density (bytes 11..8) and proprietary
Product ID fields (bytes 7..0). Should be 0x510 for
the MB85RC256V.
**************************************************************************/
function Adafruit_FRAM_I2C::getDeviceID()
{
local a;
a = blob(3);
a[0] = 0;
a[1] = 0;
a[2] = 0;
local results;

i2c.address(addr);
i2c.write8(0x00, MB85RC_SLAVE_ID);
i2c.write8(0x01, 0xa1);
i2c.write8(0x02, MB85RC_SLAVE_ID | 0x01);
delay(5);
a[0] = i2c.read8(0x00);
a[1] = i2c.read8(0x01);
a[2] = i2c.read8(0x02);
print("a0=" + a[0] + "\n");
print("a1=" + a[1] + "\n");
print("a2=" + a[2] + "\n");

/* Shift values to separate manuf and prod IDs */
/* See p.10 of http://www.fujitsu.com/downloads/MICRO/fsa/pdf/products/memory/fram/MB85RC256V-DS501-00017-3v0-E.pdf */
manufacturerID = (a[0] << 4) + (a[1]  >> 4);
productID = ((a[1] & 0x0F) << 8) + a[2];

print("manufacturerId=" + manufacturerID + "\n");
print("productID=" + productID + "\n");

}

Here is the test program:

require("I2C");

// Create an I2C instance
i2c <- I2C(0);

dofile("sd:/Adafruit_FRAM_I2C.nut");

local fram = Adafruit_FRAM_I2C(i2c, 0x50);

fram.begin();

fram.write8(0x0000, 0x65);
fram.write8(0x0001, 0x66);

local ack;
local pth;

ack = fram.read8(0x0000);
pth = fram.read8(0x0001);

print("ack=" + ack + "\n");
print("pth=" + pth + "\n");

You can find the original code here:

https://github.com/adafruit/Adafruit_FRAM_I2C

Here is the datasheet for the part:

w.fujitsu.com/downloads/MICRO/fsa/pdf/products/memory/fram/MB85RC256V-DS501-00017-3v0-E.pdf

Thanks in advance to anyone who can offer help!

softwarejanitor

After thinking about this overnight I think I may need to use i2c::xfer() and i2c::write() instead of i2c::read8() and i2c::write8() for this device... I am going to try that later...

softwarejanitor

Well, I tried the below and so far no bueno...

/**************************************************************************
@file Adafruit_FRAM_I2C.nut
@author KTOWN (Adafruit Industries)
Ported from Arduino to Esquilo by Leeland Heins
@section LICENSE
Software License Agreement (BSD License)
Copyright (c) 2013, Adafruit Industries
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holders nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
( NCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*************************************************************************/

const MB85RC_DEFAULT_ADDRESS = 0x50; /* 1010 + A2 + A1 + A0 = 0x50 default */
const MB85RC_SLAVE_ID = 0xF8;

class Adafruit_FRAM_I2C
{
i2c = null;
addr = 0;
_framInitialised = false;

manufacturerID = null;
productID = null;

constructor (_i2c, _addr)
{
    i2c = _i2c;
    addr = _addr;
}

};

/*========================================================================*/
/* PUBLIC FUNCTIONS */
/*========================================================================*/

/**************************************************************************
Initializes I2C and configures the chip (call this function before
doing anything else)
**************************************************************************/
function Adafruit_FRAM_I2C::begin()
{
/* Make sure we're actually connected */
getDeviceID();
if (manufacturerID != 0x00A) {
print("Unexpected Manufacturer ID: 0x" + manufacturerID + "\n");
return false;
}
if (productID != 0x510) {
print("Unexpected Product ID: 0x" + productID + "\n");
return false;
}

/* Everything seems to be properly initialised and connected */
_framInitialised = true;

return true;

}

/**************************************************************************
@brief Reads an 8 bit value from the specified FRAM address
@params[in] i2cAddr
The I2C address of the FRAM memory chip (1010+A2+A1+A0)
@params[in] framAddr
The 16-bit address to read from in FRAM memory
@returns The 8-bit value retrieved at framAddr
**************************************************************************/
function Adafruit_FRAM_I2C::write8(framAddr, value)
{
/*i2c.address(addr);
i2c.write8(0x00, 0xa0);
i2c.write8(0x01, framAddr >> 8);
i2c.write8(0x02, framAddr & 0xFF);
delay(5);
i2c.write8(0x00, value);*/
local b;
b = blob(4);
b[0] = 0xa0;
b[1] = framAddr >> 8;
b[2] = framAddr & 0xFF;
b[3] = value;
i2c.address(addr);
i2c.write(b);
}

/**************************************************************************
@brief Reads an 8 bit value from the specified FRAM address
@params[in] i2cAddr
The I2C address of the FRAM memory chip (1010+A2+A1+A0)
@params[in] framAddr
The 16-bit address to read from in FRAM memory
@returns The 8-bit value retrieved at framAddr
**************************************************************************/
function Adafruit_FRAM_I2C::read8(framAddr)
{
/*i2c.address(addr);
i2c.write8(0x00, 0xa0);
i2c.write8(0x01, framAddr >> 8);
i2c.write8(0x02, framAddr & 0xFF);
i2c.write8(0x03, 0xa1);
delay(5);
return i2c.read8(0x00);*/
local a;
local b;
local c;
a = blob(1);
a[0] = 0;
b = blob(4);
b[0] = 0xa0;
b[1] = framAddr >> 8;
b[2] = framAddr & 0xFF;
b[3] = 0xa1;
i2c.address(addr);
i2c.xfer(b, a);
c = a[0];
return c;
}

/**************************************************************************
@brief Reads the Manufacturer ID and the Product ID from the IC
@params[out] manufacturerID
The 12-bit manufacturer ID (Fujitsu = 0x00A)
@params[out] productID
The memory density (bytes 11..8) and proprietary
Product ID fields (bytes 7..0). Should be 0x510 for
the MB85RC256V.
**************************************************************************/
function Adafruit_FRAM_I2C::getDeviceID()
{
/*local a;

a = blob(3);

i2c.address(addr);
i2c.write8(0x00, MB85RC_SLAVE_ID);
i2c.write8(0x01, 0xa1);
i2c.write8(0x02, MB85RC_SLAVE_ID | 0x01);
delay(5);
a[0] = i2c.read8(0x00);
a[1] = i2c.read8(0x01);
a[2] = i2c.read8(0x02);*/
local a;
local b;
a = blob(3);
a[0] = 0;
a[1] = 0;
a[2] = 0;
b = blob(3);
b[0] = MB85RC_SLAVE_ID;
b[1] = 0xa1;
b[2] = MB85RC_SLAVE_ID + 1;
i2c.address(addr);
i2c.xfer(b, a);
print("a0=" + a[0] + "\n");
print("a1=" + a[1] + "\n");
print("a2=" + a[2] + "\n");

/* Shift values to separate manuf and prod IDs */
/* See p.10 of http://www.fujitsu.com/downloads/MICRO/fsa/pdf/products/memory/fram/MB85RC256V-DS501-00017-3v0-E.pdf */
manufacturerID = (a[0] << 4) + (a[1]  >> 4);
productID = ((a[1] & 0x0F) << 8) + a[2];

print("manufacturerId=" + manufacturerID + "\n");
print("productID=" + productID + "\n");

}

softwarejanitor

Well, I finally came up with a driver that works. I ended up throwing everything out and starting from scratch. I figured it out after looking at SwitchDocLabs' Python code, but this is completely new.

You can find it here on my github...

https://github.com/softwarejanitor/MB85RC256V