Sunday, March 8, 2015

Arduino Retro Computer: Program Memory (FRAM)

Arduinos have a very limited amount of internal RAM. Between the code for my video output, sound output, joystick input, keyboard input, and BASIC interpreter, I am running out of memory for the user's programs. FRAM is this very nice memory I found on Adafruit's website. It is very fast, non-volatile (does not lose memory when unpowered), and comes in large enough sizes for decent sized BASIC programs.

Adafruit has 2 types of interfaces for their FRAMs: I2C and SPI. I went with I2C to make it easy to expand the computer with additional FRAM chips if I want to in the future.

I soldered leads onto the FRAM chip.

I'm connecting pins as follows:
FRAM SDA to Arduino SDA (Digital Pin 20)
FRAM SCL to Arduino SCL (Digital Pin 21)
FRAM VCC to Arduino 5V
FRAM GND to Arudino GND
Uses I2C address 0x50 - Default

FRAM A0/A1/A2 control the I2C address so you can have multiples connected at once.

(I know my little computer is turning into a mess of wires; I'll work on a case for it soon.)

The FRAM library is available via the Adafruit website, I included it in my OS sketch:

// FRAM Library
#include <Wire.h>
#include <Adafruit_FRAM_I2C.h>

However at compile time it threw an error of not being able to find Wire.

It turns out my version of the Arduino IDE (1.0.5) is so old it didn't contain new standard libraries that the FRAM uses. I downloaded / installed the new IDE (1.6.0), but then I got a different error:
'prog_ucar' has not been declared

A type definition that Gameduino was using was deprecated and removed in the latest IDE.

To solve this problem, I modified my Gameduino library's GD.h file; at the top I added:

typedef const unsigned char prog_uchar;

Now that the upgrade errors have been resolved, I was able to create a global FRAM object:

Adafruit_FRAM_I2C fram = Adafruit_FRAM_I2C();

Initialize the object in setup():

void setup()

And finally make a simple test to make sure it was reading and writing.

  fram.write8(0, 'a');
  fram.write8(1, 'b');
  fram.write8(2, 'c');
  char test0 = (char)fram.readu(0);
  char test1 = (char)fram.readu(1);
  char test2 = (char)fram.readu(2);

The output was "bac", perfect!

That's all for now. Up next for the computer will either be a case or the start of the BASIC interpreter. The interpreter will store the user's BASIC code into the FRAM so I can keep the Arduino's SRAM available for operating system expansion.

No comments:

Post a Comment