Go Down

Topic: 23LC1024 SRAM Library (Read 7353 times) previous topic - next topic

MathiasVDA

I've got 2 of thoose RAM chips. One with SS on 30 and one on 32. I've adjusted the script accordingly with no success. I'll debug some more tonight.

Just for your information: Ive been writing that script in my previous post myself before I knew of this lib. Some problems I've had with them before:
- Setting the SS pin to high in setup()
- Putting 'byte' before SRAM_READ and iunt_8 before the return variable

Riva


I've got 2 of thoose RAM chips. One with SS on 30 and one on 32. I've adjusted the script accordingly with no success. I'll debug some more tonight.

Just for your information: Ive been writing that script in my previous post myself before I knew of this lib. Some problems I've had with them before:
- Setting the SS pin to high in setup()
- Putting 'byte' before SRAM_READ and iunt_8 before the return variable

Right, I think I see what the problem was. I had not allowed for non standard (hardware) SS pins. I have altered the library and the test sketch (zip file attached to first post in this thread) and testing it with my Mega using pin 9 as SS works fine (have also tested it using pin 30 but UNO does not have a pin 30 so altered test sketch to use 9 instead)

MathiasVDA

Great! Thanks for all your work on this!

I will test it out tonight (in approx 10 hrs ;-))

MathiasVDA

It's working perfectly now!

Just a reminder for beginners: if you have other IC's connected to the SPI bus, then you need to deactivate them by setting the pin HIGH...

Thanks Riva!

MathiasVDA

#19
Dec 27, 2013, 01:50 pm Last Edit: Dec 27, 2013, 02:49 pm by MathiasVDA Reason: 1
Hey Riva,

Small comment about your example. Shouldn't this:

Code: [Select]
const uint16_t ramSize = 0x1FFFF;

Code: [Select]
const uint32_t ramSize = 0x1FFFF;

?

(about the other topic with multiple SPI IC's, I'll get back to that when I've stabilized my sketches a little bit ;-))

Riva


Hey Riva,

Small comment about your example. Shouldn't this:

Code: [Select]
const uint16_t ramSize = 0x1FFFF;

Code: [Select]
const [b]uint32_t [/b]ramSize = 0x1FFFF;

?

(about the other topic with multiple SPI IC's, I'll get back to that when I've stabilized my sketches a little bit ;-))

Nice spot, fixed data type in example sketch but not tested with RAM.

As to the other problem I think having ~hold tied to ~cs is wrong as both are active low so when the chip is selected (cs low) then hold becomes active. Maybe better to tie ~hold to VCC.

MathiasVDA


As to the other problem I think having ~hold tied to ~cs is wrong as both are active low so when the chip is selected (cs low) then hold becomes active. Maybe better to tie ~hold to VCC.


I've just also commented in the other thread. HOLD is pulled up on 5V. But 5V is also connected to CS with a resistor (10k) so I guess this is ok?

MathiasVDA

Another comment about the lib. Related to the earlier comment about the ramSize variable:

Code: [Select]
void SpiRAM::readBuffer(uint32_t address, char *buffer, uint16_t length) {
  digitalWrite(_ss_Pin, LOW);
  setAddressMode(address, READ);
  for (uint16_t i = 0; i < length; i++) buffer[i] = SPI.transfer(0x00);
  digitalWrite(_ss_Pin, HIGH);
}

void SpiRAM::writeBuffer(uint32_t address, char *buffer, uint16_t length) {
  digitalWrite(_ss_Pin, LOW);
  setAddressMode(address, WRITE);
  for (uint16_t i = 0; i < length; i++) SPI.transfer(buffer[i]);
  digitalWrite(_ss_Pin, HIGH);
}

void SpiRAM::fillBytes(uint32_t address, byte value, uint16_t length) {
  digitalWrite(_ss_Pin, LOW);
  setAddressMode(address, WRITE);
  for (uint16_t i = 0; i < length; i++) SPI.transfer(value);
  digitalWrite(_ss_Pin, HIGH);
}


all references to an address should be uint32_t. This includes: 'length' and 'i'. So the above should be the below:

Code: [Select]
void SpiRAM::readBuffer(uint32_t address, char *buffer, uint32_t length) {
  digitalWrite(_ss_Pin, LOW);
  setAddressMode(address, READ);
  for (uint32_t i = 0; i < length; i++) buffer[i] = SPI.transfer(0x00);
  digitalWrite(_ss_Pin, HIGH);
}

void SpiRAM::writeBuffer(uint32_t address, char *buffer, uint32_t length) {
  digitalWrite(_ss_Pin, LOW);
  setAddressMode(address, WRITE);
  for (uint32_t i = 0; i < length; i++) SPI.transfer(buffer[i]);
  digitalWrite(_ss_Pin, HIGH);
}

void SpiRAM::fillBytes(uint32_t address, byte value, uint32_t length) {
  digitalWrite(_ss_Pin, LOW);
  setAddressMode(address, WRITE);
  for (uint32_t i = 0; i < length; i++) SPI.transfer(value);
  digitalWrite(_ss_Pin, HIGH);
}


And don't forget the .h:

Code: [Select]
    // Read several bytes starting at address and of length into a char buffer
    void readBuffer (uint32_t address, char *buffer, uint16_t length);
   
    // Write several bytes starting at address and of length from a char buffer
    void writeBuffer(uint32_t address, char *buffer, uint16_t length);
   
    // Write several bytes of value, starting at address and of length
    void fillBytes  (uint32_t address, byte value, uint16_t length);


Code: [Select]
    // Read several bytes starting at address and of length into a char buffer
    void readBuffer (uint32_t address, char *buffer, uint32_t length);
   
    // Write several bytes starting at address and of length from a char buffer
    void writeBuffer(uint32_t address, char *buffer, uint32_t length);
   
    // Write several bytes of value, starting at address and of length
    void fillBytes  (uint32_t address, byte value, uint32_t length);


It is soooooo easy to miss with those variable declarations... That is undoubtedly the hardest part when moving form a higher programming language to a lower... I get this all the time and it is driving me crazy.  :smiley-mr-green:

Riva


It is soooooo easy to miss with those variable declarations... That is undoubtedly the hardest part when moving form a higher programming language to a lower... I get this all the time and it is driving me crazy.  :smiley-mr-green:

They were originally 32 bit but got changed to 16 bit. I have bought a couple of SRAM chips in to work and will test them with some updated library code and then publish it. I now see why Rob was not keen on taking on the library  :D

Grumpy_Mike

I have been trying this on my Mega 1280 and while it appears to work at first sight a more rigorous memory test shows some errors.
Basically a 256 byte buffer is filled with random numbers and written to SRAM, then they are read back and any discrepancies printed and counted. This is repeated for the next 256 bytes of the SRAM until all the SRAM has been tested. Then the total number of errors is printed and  the test is repeated.
I can't get any less than about 25 errors in the 131072 bytes tested in a cycle and sometimes there are many more.
Can other people check this code with their systems please and report back. - Thanks
Code: [Select]

// Tested uning a 23LC1024 sRam chip in a 8 pin DIP package
// By Grumpy Mike 14th Jan 2014
// Test connections are...
// Chip UNO MEGA  NAME
//  1   9   9     SS    (Hardware SS Pin (10 or 53) needs to remain output no matter what other pin you may for SS)
//  2   12  50    MISO
//  3   NC  NC
//  4   GND GND   Vss
//  5   11  51    MOSI
//  6   13  52    SCK
//  7   +5V +5V   ~HOLD
//  8   +5V +5V   Vcc


#include <SPI.h>
#include <SpiRAM.h>

byte ramContents[256];
long int page = 0; // 256 byte pages
int totalErrors = 0;

SpiRAM sRam(53);     // Initialize the RAM

void setup(){
  randomSeed(0xff); // important that the same random numbers are produced from reset
  Serial.begin(9600);
  Serial.println("Ram Tests Begin.");
 
  SPI.setClockDivider(SPI_CLOCK_DIV8);
}

void loop(){
    setContents();
    readContents();
    page += 256;
    if(page > 0x1ffff){
      Serial.print("One cycle complete ");
      Serial.print(totalErrors);
      Serial.println(" errors");
      totalErrors = 0;
      page = 0;
      delay(2000);
    }

}

void setContents(){
  for(int i =0; i<256; i++){ // write something to the memory
  ramContents[i] = random(0xff);
  ramWrite((long)i, ramContents[i]);
  }
}

void readContents(){
  byte value;
  boolean fault = false;
  for(int i =0; i<256; i++){ // read something from the memory
  value = ramRead((long)i); // read a byte
  if(ramContents[i] != value){
    fault = true;
    printReading((long)i, value, ramContents[i]);
    totalErrors++;
    }
  }
  if(!fault){
    Serial.print("verified cycle page ");
    Serial.println(page,HEX);
  }
}

byte ramRead(long add){
  add += page;
  return sRam.readByte(add);
}

void ramWrite(long add, byte val){
  add += page;
  sRam.writeByte(add, val);
}

void printReading(long add, int got, int should){
  Serial.print("At address ");
  Serial.print(add + page, HEX);
  Serial.print("  -  Read ");
  Serial.print(got, HEX);
  Serial.print("  -  should be ");
  Serial.println(should, HEX);
}



Typical of the output I get is:-
Code: [Select]

At address 1F5FF  -  Read 7C  -  should be 43
At address 1F64D  -  Read 44  -  should be BA
At address 1F6C3  -  Read CA  -  should be 5D
verified cycle page 1F700
verified cycle page 1F800
verified cycle page 1F900
verified cycle page 1FA00
verified cycle page 1FB00
verified cycle page 1FC00
verified cycle page 1FD00
At address 1FE1A  -  Read 40  -  should be 6B
verified cycle page 1FF00
One cycle complete 252 errors

------------------------------


verified cycle page 1F400
At address 1F577  -  Read 0  -  should be 78
verified cycle page 1F600
verified cycle page 1F700
verified cycle page 1F800
verified cycle page 1F900
verified cycle page 1FA00
verified cycle page 1FB00
verified cycle page 1FC00
verified cycle page 1FD00
verified cycle page 1FE00
verified cycle page 1FF00
One cycle complete 30 errors


Grumpy_Mike

Just run some long term tests by commenting out the intermediate print statements and got this:-
Code: [Select]

Ram Tests Begin.
One cycle complete 12489 errors
One cycle complete 69 errors
One cycle complete 63 errors
One cycle complete 1093 errors
One cycle complete 69 errors
One cycle complete 3947 errors
One cycle complete 4297 errors
One cycle complete 75 errors
One cycle complete 63 errors
One cycle complete 7237 errors
One cycle complete 61 errors
One cycle complete 3317 errors
One cycle complete 57 errors
One cycle complete 59 errors
One cycle complete 29349 errors
One cycle complete 57 errors
One cycle complete 55 errors
One cycle complete 55 errors
One cycle complete 56 errors
One cycle complete 52 errors
One cycle complete 46 errors
One cycle complete 50 errors
One cycle complete 48 errors
One cycle complete 52 errors
One cycle complete 55 errors
One cycle complete 52 errors
One cycle complete 50 errors
One cycle complete 48 errors
One cycle complete 52 errors
One cycle complete 54 errors
One cycle complete 48 errors
One cycle complete 47 errors
One cycle complete 48 errors
One cycle complete 44 errors
One cycle complete 50 errors
One cycle complete 1946 errors
One cycle complete 53 errors
One cycle complete 51 errors
One cycle complete 3166 errors
One cycle complete 50 errors
One cycle complete 42 errors
One cycle complete 48 errors
One cycle complete 42 errors
One cycle complete 47 errors
One cycle complete 44 errors
One cycle complete 44 errors
One cycle complete 47 errors
One cycle complete 47 errors
One cycle complete 47 errors
One cycle complete 46 errors
One cycle complete 48 errors
One cycle complete 49 errors
One cycle complete 50 errors
One cycle complete 48 errors
One cycle complete 49 errors
One cycle complete 52 errors
One cycle complete 3113 errors
One cycle complete 9916 errors
One cycle complete 64 errors


For the record the chip is soldered up with lots of decoupling on the board, 0.1uF surface mount ceramics an 22uF electrolytics.

Riva

#26
Jan 14, 2014, 02:06 pm Last Edit: Jan 14, 2014, 02:22 pm by Riva Reason: 1

I have been trying this on my Mega 1280 and while it appears to work at first sight a more rigorous memory test shows some errors.
Basically a 256 byte buffer is filled with random numbers and written to SRAM, then they are read back and any discrepancies printed and counted. This is repeated for the next 256 bytes of the SRAM until all the SRAM has been tested. Then the total number of errors is printed and  the test is repeated.
I can't get any less than about 25 errors in the 131072 bytes tested in a cycle and sometimes there are many more.
Can other people check this code with their systems please and report back. - Thanks

Do you get the same results if you set SPI clock speed to SPI_CLOCK_DIV8. My initial tests months ago were done using an UNO with the SRAM breadboarded and it worked fine but later testing with a Mega I was getting random read errors but reducing the clock speed cured it.

EDIT: Ignore the above as I see you have already put SPI_CLOCK_DIV8. in the sketch.

Riva

#27
Jan 14, 2014, 02:28 pm Last Edit: Jan 14, 2014, 02:42 pm by Riva Reason: 1
I just quickly plugged up the SRAM (see picture) and loaded your sketch and it performs without errors. I then remmed out the SPI_CLOCK_DIV8 and it still works without error.
Code: [Select]
Ram Tests Begin.
verified cycle page 0
verified cycle page 100
verified cycle page 200
verified cycle page 300
verified cycle page 400
verified cycle page 500
verified cycle page 600
verified cycle page 700
verified cycle page 800
verified cycle page 900
verified cycle page A00
verified cycle page B00
verified cycle page C00
verified cycle page D00
verified cycle page E00
verified cycle page F00
<SNIP>
verified cycle page 1F000
verified cycle page 1F100
verified cycle page 1F200
verified cycle page 1F300
verified cycle page 1F400
verified cycle page 1F500
verified cycle page 1F600
verified cycle page 1F700
verified cycle page 1F800
verified cycle page 1F900
verified cycle page 1FA00
verified cycle page 1FB00
verified cycle page 1FC00
verified cycle page 1FD00
verified cycle page 1FE00
verified cycle page 1FF00
One cycle complete 0 errors
verified cycle page 0


EDIT:
I have now tested both spare SRAM chips I have and they work without error at 4MHz SPI clock

Grumpy_Mike

Thanks for the test.
I will have to try my system with a 2560 Mega.

GistA

Thanks for sharing your code!
Unfortunately i've got a Leonardo. As you know, there is no SS Pin on it's ICSP header. Is there a way to use your library and sketch with my Arduino? Or do i have to use other pins than the once on the ICSP header?

Thanks a lot - GistA

Go Up