Pages: [1] 2   Go Down
Author Topic: Interface SRAM 23k256 to Arduino Duemilanove  (Read 2760 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I'm new in the Arduino programming, I'm just an hobbyst. So please be gentle, also with my english.
Anyway, I want post an argument which could be useful for many developers involved in storing physical data from sensors, in particular the amount of data and the speed of reading/writing.
For this purpose I read about the new Microchip SRAM's 23K256 and suppose it's a very good solution to improve the limit of the Arduino Duemilanove board (which has only 2K of ram).
So I invite an interested reader to take a look at Datasheet of this powerful ram chip.
I post this article because I encountered problems in interfacing it with Arduino Duemilanove, ...nothing is going as in theory it should go.
I enclose next my code. What is wrong?

#define CS 10 // Arduino pin 10 - 23K256 CS pin

#define MOSI 11 // Arduino pin 11 - 23K256 MOSI pin

#define MISO 12 // Arduino pin 12 - 23K256 MISO pin

#define SCK 13 // Arduino pin 13 - 23K256 SCK pin


byte value;

byte clr;


char spi_transfer(volatile char data)

{

SPDR = data; // Start the transmission

while (!(SPSR & (1<<SPIF))) // Wait the end of the transmission

  {};

return SPDR; // return the received byte

}


void setup()

{

Serial.begin(9600);

pinMode(MOSI, OUTPUT);

pinMode(SCK, OUTPUT);

pinMode(CS, OUTPUT);

pinMode(MISO, INPUT);

digitalWrite(CS, HIGH); //disable device


//Configure SPI control register (SPCR)

SPCR = B1010000;

// | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |

// | SPIE | SPE | DORD | MSTR | CPOL | CPHA | SPR1 | SPR0 |

// SPIE - Enables the SPI interrupt when 1

// SPE - Enables the SPI when 1

// DORD - Sends data least Significant Bit First when 1, most Significant Bit first when 0

// MSTR - Sets the Arduino in master mode when 1, slave mode when 0

// CPOL - Sets the data clock to be idle when high if set to 1, idle when low if set to 0

// CPHA - Samples data on the falling edge of the data clock when 1, rising edge when 0'

// SPR1 and SPR0 - Sets the SPI speed, 00 is fastest (4MHz) 11 is slowest (250KHz)

//--------------------------------

clr=SPSR;

clr=SPDR;

digitalWrite(CS,LOW);delay(10);

spi_transfer(0x01);

spi_transfer(0x41);

digitalWrite(CS,HIGH);

delay(10);

}


void loop()

{

  digitalWrite(CS,HIGH);

  delay(100);


  Serial.print("Read Status Register Config -> ");

  digitalWrite(CS,LOW);

  spi_transfer(0x05);

  value=spi_transfer(0xFF);

  digitalWrite(CS,HIGH);

  Serial.println(value,DEC);

  delay(100);


  Serial.println("Write data to RAM ");

  digitalWrite(CS,LOW);

  spi_transfer(0x02); //write command

  spi_transfer(0x00); //MSB address byte

  spi_transfer(0x00); //LSB address byte

  for (int i=1; i<=10; i++)

   {

      spi_transfer(0x33); //example data to write

   }

  digitalWrite(CS,HIGH);

  delay(100);

  Serial.println("Read data from RAM ");

  digitalWrite(CS,LOW);

  spi_transfer(0x03); //read command

  spi_transfer(0x00); //MSB address byte

  spi_transfer(0x00); //LSB address byte

  for (int i=1; i<=10; i++)

   {

      value=spi_transfer(0xFF); //send a dummy byte and receive byte stored

      Serial.print(value,DEC); Serial.print(" ");

   }

  digitalWrite(CS,HIGH);

  Serial.println();Serial.println();

  delay(2000);

}


I obtain non-sense values from the Read Status Register routine, to verify the right configuration (Serial storage mode) and also from Read command.
I suppose the answer must require a better knowledge than mine, and a very deepened study of the matter.
Thank you in advance.
Logged

Greenwood, Indiana
Offline Offline
God Member
*****
Karma: 0
Posts: 508
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.arduino.cc/en/Tutorial/SPIEEPROM

It should be possible to use it similar to this but I've not gotten very far with Arudino yet.
Logged

If it was designed by man it can be repaired by man.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 21
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I have tried with this code on arduino, and also with similar code on a Atmega128.

I am currently using 10k inline resistors for the level convert and a 1k inline+10 to 3v3 for CS.
4k7 pullup to 3v3 on MISO.

I dont have a scope to check what is actually on the wire, so its blind luck if its code or hardware that is the problem.

Have you checked the spi mode is correct?

Code:
#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

//opcodes
#define WRITE  2
#define READ   3


char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
  {
    Serial.print('.',BYTE);
  };
  return SPDR;                    // return the received byte
}

void setup()
{
 Serial.begin(9600);
 
 Serial.print('h',BYTE);
 Serial.print('i',BYTE);
 Serial.print('\n',BYTE);//debug
 
 pinMode(DATAOUT, OUTPUT);
 pinMode(DATAIN, INPUT);
 pinMode(SPICLOCK,OUTPUT);
 pinMode(SLAVESELECT,OUTPUT);
 digitalWrite(SLAVESELECT,HIGH); //disable device  
 delay(100);
 }

void loop()
{  

  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x41);
  digitalWrite(SLAVESELECT,HIGH);


  
  delay(1000);
SPCR = (1<<SPE)|(1<<MSTR);
byte clr=SPSR;
clr=SPDR;
delay(10);

digitalWrite(SLAVESELECT,LOW);
spi_transfer(WRITE);
spi_transfer(0);
spi_transfer(0);
spi_transfer(1);
spi_transfer(2);
spi_transfer(3);
spi_transfer(4);
spi_transfer(5);
digitalWrite(SLAVESELECT,HIGH);

delay(3000);
digitalWrite(SLAVESELECT,LOW);
spi_transfer(READ);
spi_transfer(0);//address
spi_transfer(0);//address
char data1 = spi_transfer(0xFF); //get data byte
char data2 = spi_transfer(0xFF); //get data byte
char data3 = spi_transfer(0xFF); //get data byte
char data4 = spi_transfer(0xFF); //get data byte
char data5 = spi_transfer(0xFF); //get data byte
digitalWrite(SLAVESELECT,HIGH);

Serial.print(data1,DEC);
Serial.print('\n',BYTE);
Serial.print(data2,DEC);
Serial.print('\n',BYTE);
Serial.print(data3,DEC);
Serial.print('\n',BYTE);
Serial.print(data4,DEC);
Serial.print('\n',BYTE);
Serial.print(data5,DEC);
Serial.print('\n',BYTE);
}

If I comment out the init code for seq access and hold disabled, it returns -1, otherwise its stuck in the wait loop.

But I think the -1 is really from the spi function, not the sram itself.
« Last Edit: October 06, 2009, 07:25:54 am by MORA » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

After some frustrating tests in interfacing the Microchip SRAM 23K256 with Arduino duemilanove, the results are without success.
I'm quite confused about this simple hardware and software interfacing, as reported in the Datasheet and in Application notes.
From the Hardware point of view, I used the next wiring:
- an in-line resistor of 1K on pin CS (SLAVESELECT) plus a 10K pull-up resistor to 3,3 volt;
- an in-line resistor of 10K on pin MOSI (DATAIN);
- an in-line resistor of 10K on pin SCLK (SERIALCLOCK);
- direct connection to pin MISO (DATAOUT);
- a power of 3,3 volts coming directly from the proper pin on Arduino, connected to pin Vdd of 23K256 chip;
- SPI mode 1 (CPOL=0 and CPHA=1).
I also tried to simplify the code, just limiting it to only two simple steps:
1) configuring the Write Status Register of the SRAM;
2) reading the above configuration.
In the next code I post, I first send the command Write Status Register (0x01), then send the configuration Sequential mode and Hold pin disabled (0x41).
In second place, I send the Read Status Register Command (0x05) and finally send a dummy byte (0xFF) to obtain a byte from the MISO pin.
Unfortunately I do not obtain the value 0x41 (65 in decimal format), as I should expect !
I just obtain -1 or 0.
The solution of the above two steps is crucial for the next phase of storing true data coming from an high resolution ADC.
Is there anybody interested with this challenge?
 
#define DATAOUT 11//MOSI
#define DATAIN  12//MISO
#define SPICLOCK  13//sck
#define SLAVESELECT 10//ss

byte clr;
char value;

char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait for the end of the transmission
  {
    //Serial.print('.');
  };
  return SPDR;                    // return the received byte
}

void setup()
{
 Serial.begin(9600);
 pinMode(DATAOUT, OUTPUT);
 pinMode(DATAIN, INPUT);
 pinMode(SPICLOCK,OUTPUT);
 pinMode(SLAVESELECT,OUTPUT);
 digitalWrite(SLAVESELECT,HIGH); //disable device  
 delay(10);
 SPCR= (1<<SPE)|(1<<MSTR)|(0<<CPOL)|(1<<CPHA);  //SPI mode 1
 clr=SPSR;
 clr=SPDR;
 delay(10);
}


void loop()
{  
  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x01); Serial.println("send 0x01 Write Status Register Command ");
  delay(100);
  spi_transfer(0x41); Serial.println("send 0x41 Select Sequential mode, Hold disabled");
  digitalWrite(SLAVESELECT,HIGH);
  delay(100);

  digitalWrite(SLAVESELECT,LOW);
  spi_transfer(0x05); Serial.println("send 0x05 Read Status Register Command ");
  delay(100);
  value=spi_transfer(0xFF);
  digitalWrite(SLAVESELECT,HIGH);
  Serial.print("Data from Status Register -> "); //should obtain 0x41 or 65 in dec mode
  Serial.println(value,DEC);
  Serial.println();
  delay(3000);
}
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've written a library that interfaces with this chip which I've uploaded to the playground. I'd include a link but the board won't let me as this is my first post ...

--
Phil
« Last Edit: November 08, 2009, 03:22:43 pm by LichP » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Spi RAM link:

http://www.arduino.cc/playground/Main/SpiRAM
« Last Edit: November 08, 2009, 03:22:06 pm by LichP » Logged

carolinas
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

hi, does this library work with arduino 017? I can't get this one working.
The IDE does not recognize it as a library,even though it was placed in the libraries folder.

thanks.
Logged

Manchester (England England)
Offline Offline
Brattain Member
*****
Karma: 602
Posts: 33362
Solder is electric glue
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Yes it works, put them in a folder called SpiRAM and then at the start of the sketch put the lines:-
Quote
#include "Spi.h"
#include "SpiRAM.h"

As the note says you need the Spi library in first.
« Last Edit: January 26, 2010, 10:05:39 am by Grumpy_Mike » Logged

carolinas
Offline Offline
Newbie
*
Karma: 0
Posts: 9
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your response. I had all of that in already, I must have something else wrong.
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Anyone know if using an SPI SRAM chip would be any faster than using an I2C EEPROM chip?

   Right now I'm experimenting with an I2C EEPROM chip of the same size. It works great, but it takes 5ms to write a single byte. I know I could write it about 30 bytes at a time, but one is easier.

  I imagine this SPI SRAM chip is capable writing a single byte in less than 5ms.


thanks,
Phil
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 10
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Writing to SRAM should be much faster than writing to EEPROM. Looking at the data sheet for the 23K256, the only limitation I see is that the clock frequency at 3.0V has to be below 20MHz for the industrial version and below 16MHz for the automotive version. In other words, it can accept data as fast as the Arduino can push it out. Just keep in mind that while your EEPROM will retain data for decades, the SRAM will lose its data as soon as Vcc drops below 1.2V.
Logged

Kauai
Offline Offline
Newbie
*
Karma: 0
Posts: 36
Amani 64 CPLD Shield
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I measured the 23K256 transfer process to be around 260us.  Not great but far better than 5ms!

Below is a link to some work I've done with the 23K256, a CPLD, and the Arduino.  I have a method of injecting addressing in the 23K256 data stream and expanding memory.  I have tested up to 256KB, the theoretical limit is 2MB.  The practical limit is far less due to cost and real estate.

http://majolsurf.net/wordpress/?p=930
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,

I'm trying to make this work with Arduino 021, but so far no success. I want to use the included SPI library instead of "Spi.h" that the library in the playground uses. So far this is my code:
Code:
# SPIRAM.h
#include <WProgram.h>
#include <SPI.h>

// SRAM opcodes
#define READ  0b00000011
#define WRITE 0b00000010
#define RDSR  0b00000101
#define WRSR  0b00000001

#define HOLD 1
#define BYTE_MODE (0x00 | HOLD)
#define PAGE_MODE (0x80 | HOLD)
#define STRM_MODE (0x40 | HOLD)

class SPIRAM {
public:
  SPIRAM();
  void writeByte(uint8_t address, uint8_t data);
  uint8_t readByte(uint8_t address);
private:
  void setMode(uint8_t mode);
  
  uint8_t mode_;
};

Code:
# SPIRAM.cpp
#include "pins_arduino.h"
#include "SPIRAM.h"

SPIRAM::SPIRAM() {
  digitalWrite(SS, LOW);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  SPI.setDataMode(SPI_MODE1);
  mode_ = BYTE_MODE;
}

void SPIRAM::writeByte(uint8_t address, byte data) {
  setMode(BYTE_MODE);
  digitalWrite(SS, LOW);
  SPI.transfer(WRITE);
  SPI.transfer((byte)(address >> 8));
  SPI.transfer(address);
  SPI.transfer(data);
  digitalWrite(SS, HIGH);
}

byte SPIRAM::readByte(uint8_t address) {
  byte data;
  
  setMode(BYTE_MODE);
  digitalWrite(SS, LOW);
  SPI.transfer(READ);
  SPI.transfer((byte)(address >> 8));
  SPI.transfer(address);
  data = SPI.transfer(0x00);
  digitalWrite(SS, HIGH);
  return data;
}

// write the status register (bites 7 and 6)
void SPIRAM::setMode(uint8_t mode) {
  if (mode != mode_) {
    digitalWrite(SS, LOW);
    SPI.transfer(WRSR);
    SPI.transfer(mode);
    digitalWrite(SS, HIGH);
    mode_ = mode;
  }
}

Code:
#SRAMTest.pde
#include <SPI.h>
#include "SPIRAM.h"

SPIRAM spiRAM;

void setup() {
  Serial.begin(9600);
}

void loop() {
  char data_to_chip[17] = "Testing 90123456";
  char data_from_chip[17] = "";
  int i;
  
  for (i=0; i < 17; i++) {
    spiRAM.writeByte(i, data_to_chip[i]);
  }
  
  // read back data
  for (i=0 ; i < 17; i++) {
    data_from_chip[17] = spiRAM.readByte(i);
  }
  data_from_chip[i] = '\0';
  Serial.print("data: ");
  Serial.println(data_from_chip);
  delay(3000);
}

On the hardware side, I'm using this (taken from this post):



I just want to test the sram with a simple write/read byte and the go to page/stream.

Any idea where could be my problem?
thanks!
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is what I'm getting back from the sram:

Code:
will write data 'T' to address 0
will write data 'e' to address 1
will write data 's' to address 2
will write data 't' to address 3
will write data 'i' to address 4
will write data 'n' to address 5
will write data 'g' to address 6
will write data ' ' to address 7
will write data '9' to address 8
will write data '0' to address 9
will write data '1' to address A
will write data '2' to address B
will write data '3' to address C
will write data '4' to address D
will write data '5' to address E
will write data '6' to address F
will write data '' to address 10
read data '0' from address 0
read data '0' from address 1
read data 'FC' from address 2
read data 'F8' from address 3
read data 'FF' from address 4
read data 'FD' from address 5
read data 'FF' from address 6
read data 'FC' from address 7
read data '70' from address 8
read data 'FF' from address 9
read data 'FF' from address A
read data 'FF' from address B
read data 'E7' from address C
read data 'FF' from address D
read data 'FF' from address E
read data 'FF' from address F
read data 'FF' from address 10
Logged

Greenwood, Indiana
Offline Offline
God Member
*****
Karma: 0
Posts: 508
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

http://www.ramtron.com/products/nonvolatile-memory/serial-product.aspx?id=6
Logged

If it was designed by man it can be repaired by man.

Pages: [1] 2   Go Up
Jump to: