SRAM class using 23K256

I had a need in a project for a fast easy external memory.
Microchip's 23K256 is ideal.

I looked at Spi Library and Spi RAM Library from the arduino playground.

What I really wanted was to have the ram accessible continually from my code.
I did not want to pass address and length each time I stored or retrieved data.

My class has four functions:

writestream: Setup the SRAM in sequential write mode starting from the passed address.
Data can then be written one byte at a time using RWdata(byte data).
Each byte is stored in the next location and it wraps around 32767.

readstream: Setup the SRAM in sequential read mode starting from the passed address.
Data can then be read one byte at a time using byte RWdata(0).The passed data is irrelavent.
Each byte is read from the next location and it wraps around 32767.

RWdata: Write or read the data from the SRAM.
If the writesteam is open the passed data will be written to the current address.
If the readstream is open the data from the current address will be returned.

closeRWstream: Use to close the open read or write stream.
Dont need when changing between read/write.
Close before using SPI somewhere else.

digital pin 13 SCK
digital pin 12 MISO
digital pin 11 MOSI
digital pin 10 SS

I want it for blocks of data, but it can still be used for individual bytes.
This is the example RWbyte you will find in the library:

#include <SRAM.h>

void setup()
{
Serial.begin(9600); // initialize serial communications
}//end of setup

void loop()
{
SRAM.writestream(22767); //open writestream address from 0 to 32767

SRAM.RWdata(75); //the byte to write to SRAM at current address

SRAM.readstream(22767); //open readstream address from 0 to 32767

int data = SRAM.RWdata(0xff); //read byte from SRAM at current address

Serial.println(data); //check data

delay(1000);
}//end of loop

This example to write and read all 32768 bytes is in the library:

#include <SRAM.h>

void setup()
{
Serial.begin(9600); // initialize serial communications
}//end of setup

void loop()
{
SRAM.writestream(0); // start address from 0

unsigned long stopwatch = millis(); //start stopwatch

for(unsigned int i = 0; i < 32768; i++)
SRAM.RWdata(0x55); //write to every SRAM address

Serial.print(millis() - stopwatch);
Serial.println(" ms to write full SRAM");

SRAM.readstream(0); // start address from 0

for(unsigned int i = 0; i < 32768; i++)
{
if(SRAM.RWdata(0xFF) != 0x55) //check every address in the SRAM
{
Serial.println("error in location ");
Serial.println(i);
break;
}//end of print error
if(i == 32767)
Serial.println("no errors in the 32768 bytes");
}//end of get byte

delay(1000);
}//end of loop

If it all works you should see:

116 ms to write full SRAM
no errors in the 32768 bytes

For the library and circuit download SRAMclass.zip from:

Hi, Karl. I tried your SRAM, and with some iterations in the proper hardware setup, could have it running, but on a DueMilleNuove.... When I moved to a Mega1280, nothing happens, not even a start of the code, so I suspect some initialization due to SRAM.h does not work... any hint?
Philippe

I'm sorry but I am not familar withn the Mega1280.

As you say the .h file sets up the pins to use for the interface:

digital pin 13 SCK
digital pin 12 MISO
digital pin 11 MOSI
digital pin 10 SS
*/
#ifndef SRAM_h
#define SRAM_h

#define setupSPI SPCR = 0x50 //Master mode, MSB first, SCK phase low, SCK idle low, clock/4
#define setupDDRB DDRB |= 0x2c //set SCK(13) MOSI(11) and SS as output
#define selectSS PORTB &= ~0x04 //set the SS to 0 to select
#define deselectSS PORTB |= 0x04 //set the SS to 1 to deselect

The 1280 uses different pins for the SPI then you will have to change those.

The 328 uses PB2 as SS (you can use any pin here)
PB3 as MOSI
PB4 as MISO
PB5 as SCK(these 3 are set)

You may also have to change

setupSPI SPCR = 0x50 The SPCR may need a different value.

Thanks, Carl. I'll check on that and keep you posted.
Best regards,
Ph

The 1280 uses different pins for the SPI then you will have to change those.

The 328 uses PB2 as SS (you can use any pin here)
PB3 as MOSI
PB4 as MISO
PB5 as SCK(these 3 are set)

You may also have to change

setupSPI SPCR = 0x50 The SPCR may need a different value.

Hi, Carl. SPCR are identical on both cpus... So I assume this should not be an issue. Looking further... but what is very strange is that the program seems to lock at the start, no loop info in console... Seems it kind of address some wrong place and hangs.... Ph

I'm sorry I dont have a 1280 or I could give you better answers.

You will have to change the port setup as I have for the 1280:
MISO PB3
MOSI PB2
SCK PB1

As for locking up it could easily happen in:

byte SRAMclass::RWdata(byte data)
{
SPDR = data;
while (!(SPSR & _BV(SPIF)))
;
return SPDR;
}//end of RWdata

In the SPSR we wait for the data transfer flag SPIF.

This could be different in the 1280.

OR more likely if you have not set the SPI pins for the 1280 then you wont get a data transfer.

carl47:
I'm sorry I dont have a 1280 or I could give you better answers.

You will have to change the port setup as I have for the 1280:
MISO PB3
MOSI PB2
SCK PB1

As for locking up it could easily happen in:

byte SRAMclass::RWdata(byte data)
{
SPDR = data;
while (!(SPSR & _BV(SPIF)))
;
return SPDR;
}//end of RWdata

In the SPSR we wait for the data transfer flag SPIF.

This could be different in the 1280.

OR more likely if you have not set the SPI pins for the 1280 then you wont get a data transfer.

Hi, Carl. Problem solved! There is a difference in the DDRB and PORTB between the 168 and the 1280.. so adapting the SRAM.h to cope with the right position of the ports solved the issue. The RAM is now working perfectly on the 1280...:). Thanks for your previous help and support. Ph

No problem.

Your code for the 1280 could be of help to other forum uses.

How about posting your code at say "code.google". I'm now using this rather than sourceforge
which is now getting very unwieldy.

Or you could just add the code as an attachment to a reply to this post.

You may use all or part of my code without reference.

carl47:
No problem.

Your code for the 1280 could be of help to other forum uses.

How about posting your code at say "code.google". I'm now using this rather than sourceforge
which is now getting very unwieldy.

Or you could just add the code as an attachment to a reply to this post.

You may use all or part of my code without reference.

Will do for sure... actually code is VERY similar to yours, only 3 lines are modified to cope with the 1280/2560 SPI pinout. Regarding the schematics, it took me a while too, so I will dump a quick scheme. As soon as I have a few minutes.

Once again, thanks a lot for your great help on this.
Philippe

Hi Philippe,

I try to use the SRAM library with a mega2560 but it does not work for the moment.

I looked at the shematics (Uno and mega2560) and also at the mapping address board http://cna.mikkeliamk.fi/Oppilas/MB210/CV/cvavr/inc/mega2560.h

I changed the following lines in the SRAM.h to match with the mega2560

#define setupSPI SPCR = 0x2c //Master mode, MSB first, SCK phase low, SCK idle low, clock/4
#define setupDDRB DDRB |= 4 //set SCK(13 52) MOSI(11 51) and SS as output
#define selectSS PORTB &= ~5 //set the SS to 0 to select
#define deselectSS PORTB |= 5 //set the SS to 1 to deselect

The pins I use on the boards are :

#define SCK_PIN 52
#define MISO_PIN 50
#define MOSI_PIN 51
#define SS_PIN 53

Would you please help me to solve this problem ?

Best Regards,
Vincent

Hi Vincent.

I have not seen anything from Philippe.

He may not be watching this thread.

Try sending a email through this forum.

Cheers.

Hi Carl,

Just did it. Waiting for an answer now :roll_eyes:

Hope I will solve this problem.

Best Regards
Vincent

Hi,

Sorry for the delay, was not on forums for a while... overloaded!!!!

So let me try to answer this. I basically used the Carl's splendid work information as it is, with the modification related to the pins assignment, and a very slightly adapted electronic setup (resistors) scheme.

The one I am using is attached in jpeg image. I also pictured the actual implementation which runs perfectly, I use it so temporarily store pictures snapped from a serial camera, before sending those via communications.

The main change is on the SRAM.h file, as follow, to cope with the mega 2560 pin assignments. The changes are as follows:

#define setupSPI SPCR = 0x50
#define setupDDRB DDRB |= 0x07
#define selectSS PORTB &= ~0x01
#define deselectSS PORTB |= 0x01

Your set is different, so you may have some issue there. The one above is in my SRAM.h and I use it daily, so I guess it is OK...:slight_smile: The scheme attached is also functional, on a hourly base, never failed once!

For the usage, I took CARL's routine, which work perfectly for me.

Hope this helps. Come back to me if needed.

Ph

All the best.

Philippe

Oops... Here is the scheme.... sorry

Thank you for your help.

I ordered a few resistors required for assembly.

I will keep you informed as soon as I've experienced.

Best Regards,
Vincent

Good luck. MUST work, it does for me..:slight_smile: Keep me posted.
Ph

Hi Philippe,

I received the resistors today and YES it works ! THANKS 4 your help 8)

But there's still a small problem either with the Uno board or the Mega board.

When I plug or reset the Arduino, the Serial prints

121 ms to write full SRAM
error in location
1

Luckily I made a this: Unplug and replug the 1K resistor between MOSI and SI, while keeping the board (Uno or Mega) plugged and the serial console open. And there it works :-)))

122 ms to write full SRAM
no errors in the 32768 bytes

Other thing, it doesn't works correctly if I plug the 0.1µf capacitor.

121 ms to write full SRAM
error in location
481

Does anyone has an idea about this problem ?

Best Regards
Vincent

Hi, Vincent,

great to read it works... but I'm surprised though with the problems you have... as you see on the picture, mine is connected permanently and never failed... You may have to experiment a little with resistors of similar value to possibly reach stability.. Do you use the 3.3V from the areduino? do you have a common ground between arduino and sram chip?

Hi Philippe.

Problem solved 8)

I had a faulty cable and I had to experimented with the resistors.

Finally, it works without any problems with the 0.1µf capacitor but I had to removed the 1K resistor between ground and Pin 6 of the 23K256, that made the system unstable when I moved it. Strange, but now it works like expected !

Now, I'll have to check that with this 23K256, I'll be able to solve the memory problem I have with my "Big" program. It takes 4ko of memory when I upload it to the board then exceeds the 8Ko available with the mega board when it runs. That's another story.

Thanks again.
Vincent

Hi,

You have changed in the SRAM.h

#define setupSPI SPCR = 0x50
#define setupDDRB DDRB |= 0x07
#define selectSS PORTB &= ~0x01
#define deselectSS PORTB |= 0x01

But in the file of registers definitions for the ATmega2560 : http://cna.mikkeliamk.fi/Oppilas/MB210/CV/cvavr/inc/mega2560.h

I read :
sfrb DDRB=4;
sfrb PORTB=5;

Could you explain why.

Could you give me a example for write and read in the SRAM 23K256.

Thanks for you help I so lost !!!