Interest in a 32KB SPI SRAM Shield for Arduino RAM expansion?

So I was looking over a datasheet for the Microchip 23K256, a 32KB 3.3v serial (SPI) SRAM chip, that would make a dang good addition to Arduino with just a little really efficient (I'm thinking 80-100% assembly) library work. Heck, I almost wonder if we could describe the device to avr-libc itself, and have it work with that data using the library methods, and not even have to think about it.

The circuit would be stupid-simple, but would make a rather valuable addition as a shield. I was just curious if anyone has some interest in such a thing... the way I figure it, it would allow things like:

  • improved graphics capabilities for graphic LED-based projects (animation at least... maybe even decoding PNG/JPEG?)
  • improved audio capabilities for WaveShield and related projects (we can already do short echo sequences using 2kb RAM, maybe we could decode low-bitrate MP3s with 32kb of RAM available?)
  • enable true data compression using 32kb RAM as a hash table for already-working libraries like FastLZ (which need to be crippled to fit in 2kb RAM, doesn't compress anything but basic runs of identical bytes), which needs 8kb RAM for the hash table
  • stack multiple RAM expansions and use different "hold" pins, get 64...128...256KB of RAM if you're so daring... maybe even make different variations of the RAM expansion board with numbers of chips on them!
  • "and so much more"... just imagine what we could do with more RAM.

And it wouldn't tie up the bus either - it uses digital 13, 12, and 11 for hardware SPI, but has a "hold" pin that can be used to make it "ignore" inputs but still keep its memory. A simple jumper could move that sort-of "enable" pin to any available digital pin, specify that pin in the program, and voila, the SRAM chip essentially uses "one" pin.

Programming with it would be a series of simple library commands... like "sram.read(uint16_t addr)", "sram.write(uint8_t byte, uint16_t addr)", "sram.readPage(uint8_t *buffer[32], uint16_t page)", "sram.writePage(uint8_t *buffer[32], uint16_t page)". If it's possible to interface directly with avr-libc, we should even be able to get away with standard types in the way that PROGMEM is used, like "char myLongLine[4096] SPIRAM = {0}". Who knows!

Just want to see how much interest there is in this sort of thing. I haven't built a shield before and think this would be a great place to get started - I'm a sucker for detail and I know what always bugs me about other shields that would be great to "get right the first time"... and given the low price (looks like under $2) and decent availability of the RAM chip and the proliferation of custom shield PCBs having been produced (so they must be relatively cheap), it seems like a very good possibility to build this little thing!

Who'd buy one for $15? :sweat_smile:

What about extending the RAM on a Mega board with the external memory interface?

And most importantly, what else would you put in that shield? Just the RAM? What about a DAC or a really good ADC in case you want to work lots of numbers with analog readings... or maybe with an ethernet interface...

If you use SPI for any good reason, maybe F(erro)Ram devices (Ramtron) are more valuable because this are "NONVOLATILE RAM".
Could easyly replace SD-Card for datalogging.

Greetz

I think that serial SRAM is probably too slow and hard to use to effectively "upgrade" the RAM in an Arduino (even modifying libc (which is well below the level that Arduino normally modifies) would be insufficient, since "RAM" is sort of explicitly the memory that the compiler can access without using libraries.)

Well, the serial SRAM runs at up to 20MHz, so with a /1 prescaler it should be no problem to clock data I/O at ~clk/10 rates... translation: really freaking fast, probably about as fast as accessing stuff from PROGMEM.

Speaking of PROGMEM data, that's basically the access method I'm going for here. Data stored in Flash needs tiny extra work-arounds to access (like pgm_read_byte()), that everyone's pretty much used to by now. A similar method would exist to access data on the RAM chip. With decent software, it should be pretty much painless to work with :slight_smile:

The idea of tweaking libc to work with it directly was kinda far-fetched, and after considering the parallels of PROGMEM with this setup, I think it's probably not reasonable to expect truly seamless integration as "extended memory space", especially on chips without memory expansion options. However, it's far significantly faster than EEPROM or other types of permanent storage (which is what makes it attractive: it's not intended to be permanent storage), so it should prove to be quite useful for long-running calculations.

Of course the first step is getting the chip itself to play with. I found that it's readily available as a standard PDIP-8 package as well, so it can be very easily played with on a breadboard which is where I do almost all my Arduino work anyway. I'm going to order up a batch of 10 of these things and see what can be done with them, maybe sell the surplus on eBay (there are no serial SRAM chips on eBay that I could find).

I got a shield design sketched up in Fritzing already, but it's not 100%. It'll be my single-sided tester board to see just how good an idea this is... it was a pretty big PITA to get the parts arranged such that everything fits nicely on a single layer :wink:

BTW, I think this is the same chip used in the "Logic shrimp" logic analyzer, which is open source, so you may be able to get some tips from there. Logic Shrimp logic analyzer - DP

.. I connected the FM25H20 2mbit SPI FRAM to my pic24 dev board (pic24HJ @50Mhz Fcpu), and did some experiments with it.
You must be aware, that there is a big overhead when writing/reading bytes, though. The FM25H20 needs 5/4 bytes "header" in order to write/read 1 byte randomly (header=command+wren+3bytes address for 256kByte address space). You may use a "burst mode" as the FRAM has an auto incremental mode for the address, so you may issue 5 bytes header for write_op and then shoot single bytes, until you unselect /cs (write_stop). In this mode I achieved (routines in C30) ~1MByte/sec at 12.5MHz SPI (1/4 Fcpu), with packet lenght 1024bytes (= the burst lenght), or ~140kByte/sec when writing a single byte to a random address. So writing/reading a single byte efficiency is ~14% from max speed.
Fazit: when you do plan to use for example the above FRAM, with Arduino at 16MHz (8MHz SPI, I guess), as an "operational flash/ram", then the FRAM's write/read (to one random byte) access time will be > ~22usec (against 62.5ns internal ram/flash access time when assuming for example 1 cycle r/w).
-Pito.