Control a SRAM as6c4008 with arduino 2560

Go To Last Post
9 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello!
I'm trying to create a routine for writing and reading a sram AS6C4008 but I can not, and do not know where is the error, if the recording or reading.
below is the code:

                     /*A0,A1,A2,A3,A4,A5,A6,A7,A8,A9,A10,A11,A12,A13,A14,A15,A16,A17,A18*/
const int addrPins[] = {15,52,53,50,51,48,49,46,26,25, 28, 27, 47, 24, 44, 22, 43, 23, 42};
                      /*D0,D1,D2,D3,D4,D5,D6,D7*/
const int dataPins[] = {41,40,43,34,37,36,39,38};
void writeSRAM(unsigned long address, int data, int select){
   readEnable();// 4.During this period, I/O pins are in the output state, and input signals must not be applied.
   digitalWrite(WE_pin, HIGH); 
   digitalWrite(BANK_low, HIGH); // <--- target
   digitalWrite(BANK_high, HIGH);
   asm("nop\n\t");
   setAddress(address);
   digitalWrite(WE_pin, LOW);
   asm("nop\n\t"); // 62,3 nanoseconds Tas time referente ao datasheet
   digitalWrite(BANK_low, LOW);
   writeEnable();
   asm("nop\n\t");
   setData(data);
   digitalWrite(WE_pin, HIGH);
   digitalWrite(BANK_low, HIGH);
   asm("nop\n\t");
   readEnable();// 4.During this period, I/O pins are in the output state, and input signals must not be applied.
}
int readSRAM(unsigned long adr, int select){
   int rv = 0;
   readEnable();
  
   digitalWrite(WE_pin, HIGH); 
   digitalWrite(BANK_low, HIGH); // <-- target
   digitalWrite(BANK_high, HIGH);
   digitalWrite(OE_pin, HIGH);
   asm("nop\n\t");
   setAddress(adr);
   asm("nop\n\t");
   digitalWrite(BANK_low, LOW); 
   digitalWrite(OE_pin, LOW);
   for(int pin = 7; pin >= 0; pin--){
      bitWrite(rv,pin,digitalRead(dataPins[pin]));    
   }
   digitalWrite(OE_pin, HIGH);
   digitalWrite(BANK_low, HIGH);
   digitalWrite(BANK_high, HIGH);
   return rv;
}
void readEnable(){
  /* inicializa porta de dados como output */
  for(int thisPin = 0; thisPin < dataCount; thisPin++){
    pinMode(dataPins[thisPin],INPUT); // Configura como INPUT
  }
}
void writeEnable(){
  /* inicializa porta de dados como output */
  for(int thisPin = 0; thisPin < dataCount; thisPin++){
    pinMode(dataPins[thisPin],OUTPUT);
    digitalWrite(dataPins[thisPin],LOW);
  }
}
void setData(int data){
  int state = 0;
  for(int pin = 7; pin >= 0; pin--){
    if(data & (1<<pin)){ 
      state = 1;
    }else{
      state = 0;
    }  
    digitalWrite(dataPins[pin], state);
  } 
}
void setAddress(long addr){
  int state = 0;
  for(int pin = 18; pin >= 0; pin--){
    if(addr & (1<<pin)){ 
      state = 1;
    }else{
      state = 0;
    }  
    digitalWrite(addrPins[pin], state);
  } 
}
void setup(){
   Serial.begin(115200);
   pinMode(ledBoard, OUTPUT); 
   pinMode(WE_pin, OUTPUT); 
   pinMode(EN_pin, OUTPUT); 
   pinMode(OE_pin, OUTPUT); 
   pinMode(BANK_dir, OUTPUT);  
   pinMode(RESET_pin, OUTPUT); 
   pinMode(BANK_low, OUTPUT); 
   pinMode(BANK_high, OUTPUT);
   pinMode(A12,OUTPUT);
   digitalWrite(A12,LOW);
  
   Serial.println("Pronto para iniciar.");
   digitalWrite(ledBoard, LOW);
}
void loop(){
   delay(2000);
   int i = 0;
   while(Serial.available() > 0){
      i = Serial.read();
  
   Serial.print("Write: ");
   for(int i = 0; i < 10; i++){
      writeSRAM(i,i*2,LOW);
      Serial.print("A: ");
      Serial.print(i);
      Serial.print(" ");
      Serial.print("D: ");
      Serial.print(i*2);
      Serial.print(" -|- ");
   }
  Serial.println();
  delay(1000);
  int r = 0;
  Serial.print("Read:  ");
  for(int i = 0; i < 10; i++){
     r = readSRAM(i, LOW);
     Serial.print("A: ");
      Serial.print(i);
     Serial.print(" ");
      Serial.print("D: ");
     Serial.print(r);
     Serial.print(" -|- ");
   }  
   Serial.println();
}

Some pins are from other functions no show in this post.

when I run I get random numbers.
I know i can retire all delay,.. alread done this.
someone can help me?

Tankfull

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What do you do with CE pin? What is BANK_low and high? You need to show us how you've wired things.

If you do not have a logic analyser or oscilloscope, i would suggest you write a function to print a message and wait for a user input. Call this function between each of the steps in your read and write cycles. At each of the steps use a multimeter to measure the voltage on the port pins to ensure your code is working correctly.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

DL the sch of the ruggedcircuits megaram bd. They have example sw too.

Imagecraft compiler user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

BANK_low is CE line, i'm using two sram, controlled by CE lines.
I analized by a Open bench and the code work fine, i no undestand why AVR keep showing a lot different data from same address line read.

bitWrite(rv,pin,digitalRead(dataPins[pin]));

Write: A: 0 D: 0 | A: 1 D: 10 | A: 2 D: 100 | A: 3 D: 110 |
Read: A: 0 D: 110 | A: 1 D: 110 | A: 2 D: 1101100 | A: 3 D: 110 |

Where "A" is address and "D" is data. Using serial comm.
Ill put a desacople capacitor, but dont believe this go resolv my problem.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

On logic analizer write code is good, but read keep I/O showing wrong data... timming for read a analizer is good also. no more idea?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Using the logic analyser you can confirm that the data is being written and read correctly. If this is the case then you need to make sure your read code correctly reads the data. I have no idea of what of what bitwrite does. I would tie the data bits high and low to confirm that this part of the code does what is expected. I'd also do things like fill the ram with zeroes and see if you read a consistant pattern. Looking at the read values in binary or hex makes it easier to determine if it is one or more bits giving an error. Its a matter of checking everything - it is most likely something very simple but it is a matter of finding it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok! ill fill sram with zeroes and try read.
Syntax
bitWrite(x, n, b)
Parameters
x: the numeric variable to which to write
n: which bit of the number to write, starting at 0 for the least-significant (rightmost) bit
b: the value to write to the bit (0 or 1)

ill use:

int d = digitalRead(dataPins[pin]);
if(d & (1

to read pins, but i believe the result was the same.

PS: I no want expand avr memory, i'm trying control this sram to other propose.

Tankfull for help!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Done!
split two chips on one bus from 8bits separated by a buff 74245 and CE line and when the buff in tri-state occourr wrong info read...
during read and write i set this to ENABLE LOW and resolved my problem.

Thanks for help

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hey This was really nice! It helped me work on my own SRAM project using Arduino and got it working. In case it is useful to anyone I'll share here my code, but here are some details to know first:

  • I was using this SRAM memory: Alliance Memory SRAM, AS6C4008 
  • This was tested on both an Arduino Mega and on an Arduino nano 33 IoT
  • I followed that datasheet to determine the delays but they were not usually more than 50 ns, which I read that probably the minimum to work on Arduino for it to be reliable is 3 microseconds so that was my default delay
  • It saves inputs from the arrays, simulating they are GPS coodinates which was my main goal but I first tested it using constant values. At the end it works perfectly here but not with the actual GPS, I believe it has to do something with the frequency rate but anyways on another normal application this code works
  • The 'N' and 'W' is because that is also a value I could extract from the GPS module I used, so it just basically help me determine if it is positive or negative on a coordinate format
//Demo to test the memory chip

//PINS
const int CE = 4;
const int OE = 3;
const int WE = 2;
                      //A0,A1,A2,A3,A4,A5,A6,A7
const int addrPins[] = {14,15,16,17,18,19,20,21};//CHANGED to 8 addresses
                     //DQ0,DQ1,DQ2,DQ3,DQ4,DQ5,DQ6,DQ7
const int dataPins[] = {13, 11, 10,  9,  8,  7,  6, 5 };

//Global variables
long counter = 0;
long recounter = 0;
char lat_dir = 'N';
char lon_dir = 'W';
float lat_vals[] = {5055.4800,5055.4846,5055.4345,5012.4888};
float lon_vals[] = {124.6934,124.6911,124.6906,124.6868};
int n_vals = 0;
byte read_once = 0;

//Coordinates example:  50 55.4800, -   1 24.6934

int writeSRAM(unsigned long addr, byte datax){
  readEnable();
  digitalWrite(CE, HIGH);
  digitalWrite(OE, HIGH);
  digitalWrite(WE, HIGH); //WRITE
  delayMicroseconds(3);
  setAddress(addr);
  delayMicroseconds(3);
  digitalWrite(CE,LOW);
  delayMicroseconds(3);
  digitalWrite(WE,LOW);
  writeEnable();
  /*Serial.println();
  Serial.print("receive data: ");
  Serial.println(datax);*/
  delayMicroseconds(3);
  setData(datax);
  delayMicroseconds(3);
  digitalWrite(WE,HIGH);
  delayMicroseconds(3);
  digitalWrite(CE, HIGH);
  delayMicroseconds(3);
  readEnable();
}

byte readSRAM(unsigned long addr){
  byte sval = 0;
  readEnable();
  digitalWrite(CE, HIGH);
  digitalWrite(OE, HIGH); //READ
  digitalWrite(WE, HIGH);
  delayMicroseconds(3);
  setAddress(addr);
  delayMicroseconds(3);
  digitalWrite(CE,LOW);
  delayMicroseconds(3);
  digitalWrite(OE,LOW);
  delayMicroseconds(3);
  for (int pin = sizeof(dataPins)/sizeof(dataPins[0]); pin >=0; pin--){
    bitWrite(sval,pin,digitalRead(dataPins[pin]));
  }
  delayMicroseconds(3);
  digitalWrite(CE, HIGH);
  delayMicroseconds(3);
  digitalWrite(OE, HIGH);
  return sval;
}

//To write values to the SRAM - Also known as SRAM input state 
void writeEnable(){ //i = each pin
  for(int i=0;i<sizeof(dataPins)/sizeof(dataPins[0]);i++){
    pinMode(dataPins[i],OUTPUT);
    digitalWrite(dataPins[i],LOW);//HERE
  }
}
//To read the values from the SRAM - Also known as SRAM output state
void readEnable(){ //i = each pin
  for(int i=0;i<sizeof(dataPins)/sizeof(dataPins[0]);i++){
    pinMode(dataPins[i],INPUT);
  }
}

void setData(byte datax){
  byte state = 0;
  for (int pin = sizeof(dataPins)/sizeof(dataPins[0]); pin >=0; pin--){
    if(datax & (1<<pin)){
      state = 1;
    }else{
      state = 0;
    }
    digitalWrite(dataPins[pin], state);
  }
}

void setAddress(unsigned long addr){
  byte state = 0;
  for (int pin = sizeof(addrPins)/sizeof(addrPins[0]); pin >= 0; pin--){
    if (addr & (1<<pin)){
      state = 1;
    }
    else {
      state = 0;
    }
    digitalWrite(addrPins[pin],state);
  }
}

void splitBytes(long num, char compass){
  byte byte1 = num >> 24;//To shift the 8 first bits to the 8 LSB
  if ((compass == 'W') || (compass == 'S')){
  //if (compass == 'W'){
    byte1 = byte1 + 0b10000000;
  }
  byte byte2 = num >> 16;
  byte byte3 = num >> 8; 
  byte byte4 = num & 0xFF;//To keep only the last 8 bits as the rest are 0's
  Serial.print(byte1, BIN);
  Serial.print(" ");
  Serial.print(byte2, BIN);
  Serial.print(" ");
  Serial.print(byte3, BIN);
  Serial.print(" ");
  Serial.print(byte4, BIN);
  Serial.print(" ");
  byte div_num[] = {byte1,byte2,byte3,byte4};//uses i to move
  for (int i=0; i<4; i++){
    writeSRAM(counter,div_num[i]);//counter is overall address position
    Serial.print("Address: ");
    Serial.print(counter);
    Serial.print(" ");
    Serial.print("Data: ");
    Serial.print(div_num[i], BIN);
    Serial.print(" -|- ");  
    counter++;
  }
}

void mergeBytes(unsigned long addr){
   long rvalue = 0;
   byte r1 = readSRAM(addr);
   if (bitRead(r1,7)){
    r1 = r1 - 0b10000000;
    Serial.print("-"); //replaced in this section instead of having an extra negative flag
   }
   byte r2 = readSRAM(addr+1);
   byte r3 = readSRAM(addr+2);
   byte r4 = readSRAM(addr+3);
   byte rtemp[]={r1,r2,r3,r4};
   for (int i=0; i<4; i++){
     rvalue = rvalue << 8;
     rvalue = rvalue + rtemp[i];
   }
   printResults(rvalue);
}

void printResults(long value){
  int ndigits = 1;
  int pointer_space=0;
  int pointer_dp=0;
  //Section to count how many digits in the number
  long compare = 10;
  while (compare <= value){
    compare *= 10;
    ndigits++;
  }
  char coor_str[ndigits];
  ltoa(value,coor_str,10);
  pointer_space = ndigits - 6; //Coordinate's blank space position
  pointer_dp = ndigits - 4; //Coordinate's decimal point position
  for (int i=0;i<ndigits;i++){ 
    if (i == pointer_space){
      Serial.print(" ");
    }
    else if(i == pointer_dp){
      Serial.print(".");
    } 
    Serial.print(coor_str[i]);
  }
}

//MAIN PROGRAM RUN
void setup() {
  //Serial.begin(9600);
  Serial.begin(115200);
  //Control PINS
  pinMode(CE, OUTPUT); 
  pinMode(OE, OUTPUT); 
  pinMode(WE, OUTPUT); 

  for(int i=0;i<sizeof(addrPins)/sizeof(addrPins[0]);i++){
    pinMode(addrPins[i],OUTPUT);
  }
  
  while (!Serial);//To only operate when Serial is open
  Serial.println("Starting");    

//Coordinates example:  50 55.4800, -   1 24.6934
  //Saving latitude and longitude

  
}

void loop() {
//Coordinates example:  50 55.4800, -   1 24.6934   
  if (counter <32){
  long lat_ext = lat_vals[n_vals] * 10000;
  long lon_ext = lon_vals[n_vals] * 10000;
  //WRITING PART
  Serial.println();
  Serial.print("To write: ");
  Serial.print(lat_ext);
  Serial.print(", ");
  Serial.println(lon_ext);  
  Serial.print("Latitude: ");
  splitBytes(lat_ext,lat_dir);//This is to separate the number into different bytes
  Serial.println();
  Serial.print("Longitude: ");
  splitBytes(lon_ext,lon_dir);
  //END OF WRITING PART
  read_once = 1;
  Serial.println();
  //delay(1000); 
  }
  else{ 
    if(read_once){
      Serial.println();
      Serial.println("Coordinates: ");
      //It reads only the addresses that has been written by the GPS thanks to the counter variable
      for (unsigned long j=0; j<counter; j=j+8){ //unsigned long j
        //Latitude
        mergeBytes(j);
        Serial.print(", ");
        //Longitude
        mergeBytes(j+4);     
        Serial.println();
        read_once = 0;
      }
    }
  }
  n_vals++;
  delay(1000);
}

 

db