Go Down

Topic: Trouble with SPI interfaced SRAM chip (Read 4538 times) previous topic - next topic

PolkaDot


(I) figured since you were having a problem I'd see what the internet had to say.


I certainly appreciate the help! Its been very helpful that you were able to replicate the problem.


Something is still wrong because I don't understand this comment (what did you do to correct it?):
Quote from: el_supremo

RSTIO is an instruction like WRITE or WRMR. This writes 0xFF to the mode register and that isn't valid.



You can think of sending
spiTransfer(WRMR);
spiTransfer(RSTIO);
as calling WriteModeRegister(RSTIO); . Since RSTIO is a command, not a parameter, we want to call what would be RSTIO(); .

Abstraction aside, you fix it by removing the WRMR line, or:
Code: [Select]

  digitalWrite(CS,LOW);    //set to single SPI mode
  SPI.transfer(RSTIO);
  digitalWrite(CS,HIGH);



Have you tried tying the HOLD pin to VCC?


This is how I have it configured. /HOLD to Vcc and unused pin 3 to GND.


everything works fine with even shorter wires


I'm having success now, even with longer jumpers; the fix seemed to come from sending 0xFF instead of 0x00 after READ commands. I really don't know why that should affect performance.. data sheet claims it's a don't-care.
I'm away from my board right now, but I'm going to write a conclusive test case (ie write and read 0-255 and compare for errors) before wrapping up the topic and summarizing changes. But I hope it's done!

PolkaDot

Okay I take back the bit about longer jumpers.. using 15cm jumpers I got an error every roughly 200 sequences (the whole sequence corrupted).

Making my own, I wrote to 1024 memory addresses 256 times with zero errors.
I have a picture of my setup attached, and my final test code below. Enjoy!

Code: [Select]

// Verify SRAM functionality
/*
  Microchip 23LC512--Arduino Uno
  1  /CS --- 8
  2  SO  --- 12
  3  NC  --- GND
  4  Vss --- GND
  5  SI  --- 11
  6  SCK --- 13
  7  HOLD--- Vcc
  8  Vcc --- Vcc
 
  Use short jumpers if breadboarding!!
*/

#include <SPI.h>

//Pin definitions:
#define CS 8

#define LENGTH 512  //length of each write sequence

//SRAM SPI commands
#define READ 0x03    //READ and WRITE to be followed by 16 bit address
#define WRITE 0x02
#define RDMR 0x05    //read mode register
#define WRMR 0x01    //write to mode register
#define RSTIO 0xFF   //reset input mode
//Mode arguments
#define BYTE 0x00
#define PAGE 0x80
#define SEQUENTIAL 0x40

void configureRAM(void);    //declare function

//Incoming and outgoing start addresses (16 bit)
unsigned int cw_addr=0x0000;
unsigned int ccw_addr=0x1000;

byte incoming=0xFF;      //incoming SPI data
byte cw_status[LENGTH];  //bytes read from first address
byte ccw_status[LENGTH];  //bytes read from second address
byte checkValue=0;        //value being written
int checkValueint=0;      //neccessary to check every value of byte checkValue

long i=0;
int errors=0;

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  configureRAM();
 
  //Write a sequence of bytes starting at two memory addresses
  for(checkValueint=0;checkValueint<256;checkValueint++)
  { 
    //write values to array starting at first address
    digitalWrite(CS,LOW);      //select SRAM
    SPI.transfer(WRITE);
    SPI.transfer(highByte(cw_addr));  //16 bit address transfered one byte at a time
    SPI.transfer(lowByte(cw_addr));
    for(i=0;i<LENGTH;i++)              //write the check value to each byte
      SPI.transfer(checkValue);
    digitalWrite(CS,HIGH);      //deselect
   
    //write values to array starting at second address
    digitalWrite(CS,LOW);
    SPI.transfer(WRITE);
    SPI.transfer(highByte(ccw_addr));
    SPI.transfer(lowByte(ccw_addr));
    for(i=0;i<LENGTH;i++)              //write the check value to each byte
      SPI.transfer(checkValue);
    digitalWrite(CS,HIGH);
   
    //read first array
    digitalWrite(CS,LOW);
    SPI.transfer(READ);
    SPI.transfer(highByte(cw_addr));
    SPI.transfer(lowByte(cw_addr));
    for(i=0;i<LENGTH;i++)
      cw_status[i]=SPI.transfer(0xFF);  //errors occur when sending values other than 0xFF
    digitalWrite(CS,HIGH);
   
    //read second array
    digitalWrite(CS,LOW);
    SPI.transfer(READ);
    SPI.transfer(highByte(ccw_addr));
    SPI.transfer(lowByte(ccw_addr));
    for(i=0;i<LENGTH;i++)
      ccw_status[i]=SPI.transfer(0xFF);
    digitalWrite(CS,HIGH);
   
    //compared stored values against expected.
    for(i=0;i<LENGTH;i++)
    {
      //if an error, display expected and received values.
      if(!(cw_status[i]==checkValue&&ccw_status[i]==checkValue))
      {
        Serial.print("Checking ");
        Serial.println(checkValue);
       
        Serial.print(cw_status[i]);          //display received values
        Serial.write('\t');
        Serial.println(ccw_status[i]);
        errors++;                            //increment error count
      }
    }
   
    checkValue++;
  }
 
  Serial.print("Errors encountered: ");      //display total errors
  Serial.println(errors);
}

void loop()
{
 
}


//Configure RAM settings and clear memory status bytes.
//Must initialize SPI before calling configureRAM()
void configureRAM(void)
{
  SPI.setClockDivider(SPI_CLOCK_DIV2);    //SPI clock at 8MHz
  SPI.setDataMode(SPI_MODE3);             //CPOL=1, CPHA=1
  SPI.setBitOrder(MSBFIRST);              //MSB first
 
  pinMode(CS,OUTPUT);
 
  digitalWrite(CS,LOW);    //set to single SPI mode
  SPI.transfer(RSTIO);
  digitalWrite(CS,HIGH);
 
  digitalWrite(CS,LOW);
  SPI.transfer(WRMR);        //Set data mode to sequential
  SPI.transfer(SEQUENTIAL);
  digitalWrite(CS,HIGH);
 
  digitalWrite(CS,LOW);
  SPI.transfer(RDMR);        //Verify status register
  incoming=SPI.transfer(0xFF);
  digitalWrite(CS,HIGH);
 
  Serial.write('\n');
  Serial.println("Status Register:");
  Serial.println(incoming,HEX);
}

Go Up
 


Please enter a valid email to subscribe

Confirm your email address

We need to confirm your email address.
To complete the subscription, please click the link in the email we just sent you.

Thank you for subscribing!

Arduino
via Egeo 16
Torino, 10131
Italy