Sunday, March 12, 2017

Leer y escribir memoria 93CSeries Microwire EEPROM con Arduino.

Bienvenidos a esta nueva entrada. Os pongo el código de arduino para leer y escribir una memoria EEPROM a través del protocolo Microwire, que es una variacion del protocolo SPI.

El sketch de arduino está disponible para su descarga aquí.

Saludos!

/****************************************************
 ********CREATED BY INGENIERIA EN CASA***************
 **********10.03.2016********************************
 *********EEPROM READER/WRITER 93C56 SERIES**********
 ****************************************************
 */

#define PIN_CLK 8   //PIN TO SEND CLOCK SIGNAL
#define PIN_ORG 12  //PIN TO SELECT BYTE OR WORD
#define PIN_S 9     //PIN CHIP SELECT
#define PIN_D 10    //PIN DATA INPUT
#define PIN_Q 11    //PIN DATA OUTPUT

#define MEMORY_SIZE 256   //Size in bytes

byte dataOutput[MEMORY_SIZE];   //variable to store data 

/*shift out 12 bits*/
void shift12bits(unsigned int data){
  digitalWrite(PIN_S,HIGH);       //CHIP SELECT HIGH TO ACTIVATE CHIP
  for(byte count = 0; count < 12; count ++){
    digitalWrite(PIN_CLK,LOW);    //PIN CLOCK LOW TO MAKE AFTER SETTING DATA THE TRANSITION
    if(data & 0x0800)             //MSB FIRST  0x0800 '0b 0000 1000 0000 0000
      digitalWrite(PIN_D,HIGH);
    else 
      digitalWrite(PIN_D,LOW);
    digitalWrite(PIN_CLK,LOW);
    digitalWrite(PIN_CLK,HIGH);   //CLOCK PULSE
    data <<= 1;                   //rotate left to prepare for next bit
  }
}

/*shift out data*/
void shiftdata(byte data_write){
  for(byte count = 0; count < 8; count ++){
    digitalWrite(PIN_CLK,LOW);    //PIN CLOCK LOW TO MAKE AFTER SETTING DATA THE TRANSITION
    if(data_write & 0x80)             //MSB FIRST  0x0800 '0b 0000 1000 0000 0000
      digitalWrite(PIN_D,HIGH);
    else 
      digitalWrite(PIN_D,LOW);
    digitalWrite(PIN_CLK,LOW);
    digitalWrite(PIN_CLK,HIGH);   //CLOCK PULSE
    data_write <<= 1;                   //rotate left to prepare for next bit
  }
}

/*get output from chip*/
void getOutput(byte address_local){
  for(byte i = 0; i < 8; i++){
    digitalWrite(PIN_CLK,LOW);
    digitalWrite(PIN_CLK,HIGH);   //rising edge of clock pin is when data is latched out
    if(digitalRead(PIN_Q))
      dataOutput[address_local] |= 1 << (7-i);  //get msb first. when i = 0, we get 0bX0000000
  }
  digitalWrite(PIN_S,LOW);       //CHIP SELECT LOW TO DEACTIVATE CHIP
}

/*reads the whole memory*/
void read_all(void){
  //start bit = 1
  //read op code = 10
  //Address A8-A0  (A8 not decoded in 93C56WP) 
  //variable address store A7-A0
  unsigned int full_address = 0x0000;
  for(unsigned int address = 0; address < MEMORY_SIZE; address ++){
    full_address = 1 << 11 | 1 << 10 | (byte)address;   //create address with start bit and op code  0b 0000 110X AAAA AAAA
    shift12bits(full_address);
    //while(digitalRead(PIN_Q)){};                  //wait until first dummy 0 is sent by chip
    getOutput(address);
    Serial.print("Adress:");
    Serial.print(address,HEX);
    Serial.print("--");
    Serial.print("Data:");
    Serial.println(dataOutput[address],HEX);
    //delay(50);
  }
}

void write_byte(byte address_write,byte data_write){
  //mask for writing 0b 0000 101X AAAA AAAA
  unsigned int write_mask = 0x0A00 | (byte)address_write;
  shift12bits(write_mask);
  shiftdata(data_write);
  digitalWrite(PIN_S,LOW);                    //CHIP SELECT LOW TO DEACTIVATE CHIP
  digitalWrite(PIN_S,HIGH);                   //BEGIN CHECK STATUS
  while(digitalRead(PIN_Q) == LOW){};         //WAIT UNTIL READY
  digitalWrite(PIN_S,LOW);                    //END CHECK STATUS
  
}

void ew_enable(void){
  unsigned int ew_enable_mask = 0x0980;       //0b0000 1001 1XXX XXXX
  shift12bits(ew_enable_mask);                //send enable write erase mask
  digitalWrite(PIN_S,LOW);                    //CHIP SELECT LOW TO DEACTIVATE CHIP
}

void ew_disable(void){
  unsigned int ew_disable_mask = 0x0800;       //0b0000 1000 0XXX XXXX
  shift12bits(ew_disable_mask);                //send disable write erase mask
  digitalWrite(PIN_S,LOW);                     //CHIP SELECT LOW TO DEACTIVATE CHIP
}

void erase_all(void){
  unsigned int erase_all_mask = 0x0900;       //0b0000 1001 0XXX XXXX
  shift12bits(erase_all_mask);                //send enable write erase mask
  digitalWrite(PIN_S,LOW);                    //CHIP SELECT LOW TO DEACTIVATE CHIP
  digitalWrite(PIN_S,HIGH);                   //BEGIN CHECK STATUS
  while(digitalRead(PIN_Q) == LOW){};         //WAIT UNTIL READY
  digitalWrite(PIN_S,LOW);                    //END CHECK STATUS
}

void setup() {
  // put your setup code here, to run once:
  pinMode(PIN_CLK,OUTPUT);
  pinMode(PIN_ORG,OUTPUT);
  pinMode(PIN_S,OUTPUT);
  pinMode(PIN_D,OUTPUT);
  pinMode(PIN_Q,INPUT);

  digitalWrite(PIN_ORG,LOW);    //ORG = 0 (x8 origination) byte read or write
  digitalWrite(PIN_S,LOW);      //standby state of chip select pin  
  digitalWrite(PIN_CLK,LOW);    //initialize pin clk to low

  Serial.begin(9600);
//  read_all();
//  ew_enable();
//  //erase_all();
//  for(unsigned int counter = 0; counter < MEMORY_SIZE; counter ++)
//  write_byte((byte)counter,MEMORY_SIZE-1-(byte)counter);//write_byte(byte address, byte data);
//  ew_disable();
  read_all();
}

void loop() {
  // put your main code here, to run repeatedly:
}

7 comments:

  1. Aunque la memoria esté guardada en x16, leyéndola en x8 ¿se obtienen los valores correctos no?

    Gracias!

    ReplyDelete
  2. Hola J,

    gracias por tu comentario. No puedo probarlo ahora mismo porque no tengo la eeprom a mi disposición, pero casi seguro de que aunque esté la memoria guardada en x16, se puede acceder en modo x8 obteniendo los valores correctos. Lo único será configurar el pin ORG en el modo correspondiente, ORG conectado a VCC para modo x16 (data in y data out D15-D0) y ORG conectado a GND para x8 (data in y data out D7-D0).

    Un saludo!

    ReplyDelete
  3. The chip I have does not have a ORG pin. How do I set this up?

    ReplyDelete
  4. Hola,sirven tambien para la serie 9532 ??

    ReplyDelete
  5. hola como estas que excelente video me podrias pasar tu numero de whatsapp para conversar de un proyecto contigo.....gracias

    ReplyDelete
  6. Hola, muy buen dia.
    ¿Funcionaria de igual forma para SPI?

    ReplyDelete