Go Down

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

PolkaDot

I'm trying to get my Uno communicating with an SRAM chip (Microchip 23LC512) via SPI.
As a simple verification, I write several bytes of data then go back and read them, and print it on the serial monitor. But, when I run my code I get this:

Memory status:   
20   1010101
21   1010101
22   1010101
23   1010100
400   10101010
401   1010101
402   1010101
403   1010101


Memory addresses are 16 bit, shown in hex; values are in binary. In this case I wrote B10101010 to each memory address.
I can't find any consistent pattern--sometimes several bytes in a row are correct, others none. Here it looks like it's wrapping values from the back to the front?
Any help is very much appreciated!

The code:
Code: [Select]
// Read and write to SRAM via SPI

#include <SPI.h>

//Pin definitions:
#define CS 8

//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 mode register
#define RSTIO 0xFF   //reset input mode
//Mode commands
#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=0x0020;
unsigned int ccw_addr=0x0400;

byte incoming=0xFF;      //incoming SPI data
byte cw_status[4];
byte ccw_status[4];

int i=0;

void setup()
{
  Serial.begin(9600);
  SPI.begin();
  configureRAM();
 
 
  //read CW memory status byte
  digitalWrite(CS,LOW);
  SPI.transfer(READ);
  SPI.transfer(highByte(cw_addr));
  SPI.transfer(lowByte(cw_addr));
  for(i=0;i<4;i++)
  {
    cw_status[i]=SPI.transfer(0x00);
  }
  digitalWrite(CS,HIGH);
 
  //read CCW memory status byte
  digitalWrite(CS,LOW);
  SPI.transfer(READ);
  SPI.transfer(highByte(ccw_addr));
  SPI.transfer(lowByte(ccw_addr));
  for(i=0;i<4;i++)
  {
    ccw_status[i]=SPI.transfer(0x00);
  }
  digitalWrite(CS,HIGH);
 
  //print results
  Serial.println("Memory status:\t");
 
  for(i=0;i<4;i++){
    Serial.print(cw_addr+i,HEX);
    Serial.write('\t');
    Serial.println(cw_status[i],BIN);
  }
  for(i=0;i<4;i++){
    Serial.print(ccw_addr+i,HEX);
    Serial.write('\t');
    Serial.println(ccw_status[i],BIN);
  }
}

void loop()
{
 
}


//Configure RAM settings and clear memory status bytes.
//Initialize SPI before calling configureRAM()
void configureRAM(void)
{
  SPI.setClockDivider(SPI_CLOCK_DIV2);    //SPI clock at 8MHz
  SPI.setDataMode(SPI_MODE0);            //CPOL=0, CPHA=0
  SPI.setBitOrder(MSBFIRST);              //MSB first
 
  pinMode(CS,OUTPUT);
 
  digitalWrite(CS,LOW);    //set to single SPI mode
  SPI.transfer(WRMR);
  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(WRITE);        //clear outgoing memory status byte
  SPI.transfer(highByte(cw_addr));  //16 bit address transferred one byte at a time
  SPI.transfer(lowByte(cw_addr));
  for(i=0;i<4;i++){
  SPI.transfer(0xAA);
  }
  digitalWrite(CS,HIGH);      //pulse CS
 
  digitalWrite(CS,LOW);
  SPI.transfer(WRITE);        //clear incoming memory status byte
  SPI.transfer(highByte(ccw_addr));
  SPI.transfer(lowByte(ccw_addr));
  for(i=0;i<4;i++){
  SPI.transfer(0xAA);
  }
  digitalWrite(CS,HIGH);
 
}

PolkaDot

180 views.. who has the answers?
I have checked all the SPI modes, and the chip is rated for 20MHz.
The 23LC512 is functionally equivalent to the more popular 23LC256.. can anyone replicate the problem?
Thanks all

CrossRoads

Sorry, don't have either of those chips. Haven't had time to browse the datasheet yet.
Designing & building electrical circuits for over 25 years. Check out the ATMega1284P based Bobuino and other '328P & '1284P creations & offerings at  www.crossroadsfencing.com/BobuinoRev17.
Arduino for Teens available at Amazon.com.

el_supremo

This doesn't look right:
Code: [Select]
  digitalWrite(CS,LOW);    //set to single SPI mode
  SPI.transfer(WRMR);
  SPI.transfer(RSTIO);
  digitalWrite(CS,HIGH);


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

Pete

PolkaDot


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


Good catch; the problem persists, however.

Go Up