0

I'm trying to write to and read from an AT93C46D eeprom using an Arduino UNO but for some reason the output I'm getting is not what I expect.

The eeprom has a data structure of 128 words of 8 bits each and I'm trying to write 10000010 to each word. When reading back the data however I get 11000001. When I write 00000000 to all words I get 10000000 for all words when reading. I tested my code on 2 AT93C46D eeproms and both gave the same result.

It looks like the MSB is always 1 (when reading) for some reason.

I'm probably making a stupid mistake but I can't seem to find it, any help is greatly appreciated!

Datasheet: http://www.atmel.com/images/atmel-5193-seeprom-at93c46d-datasheet.pdf

#include<SPI.h>
#define DATAOUT 11//MOSI
#define DATAIN  12//MISO 
#define SPICLOCK  13//sck
#define SS 10//ss


void setup()
{
  pinMode(SS,OUTPUT);
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  digitalWrite(SS,LOW);

  Serial.begin(9600);

  SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));

  fill();

  dump();
}

void loop()
{

}

void fill()
{
  Serial.println("Send EWEN opcode");
  digitalWrite(SS,HIGH);
  SPI.transfer(B10011); //EWEN
  SPI.transfer(B0000000);
  digitalWrite(SS,LOW);

  delay(100);

  for (int i=0; i < 128; i++) {
    digitalWrite(SS,HIGH);
    SPI.transfer(B101);
    SPI.transfer(i);
    SPI.transfer(B10000010);
    delay(10);
    digitalWrite(SS,LOW);
  }

  delay(100);

  Serial.println("Send EWDS opcode");
  digitalWrite(SS,HIGH);
  SPI.transfer(B1000); //EWDS
  SPI.transfer(B00000000);
  digitalWrite(SS,LOW);

  delay(10);
}

void dump(){
  Serial.println("Dumping AT93C46D");

  byte b;

  for (int i=0; i < 128; i++) {
    digitalWrite(SS,HIGH);
    SPI.transfer(B110); //read opcode
    SPI.transfer(i);
    b = SPI.transfer(B00000000); //clock data out
    digitalWrite(SS,LOW);
    Serial.println(b, BIN);
  }
}
  • That does not look like an SPI device (or at least 8-bit aligned). Might need to bit-bang that device. – Mikael Patel Feb 25 '16 at 12:42
  • B10011? Don't you mean B10011000? – Gerben Feb 25 '16 at 13:43
0

After looking at the product spec again I think it might be possible to get this working. The protocol is MSB with a start bit S followed by two bit op-code, and parameters. SPI on AVR is 8-bit transfer but transfer can be byte aligned with the start bit.

READ is op-code(10) followed by 7-bit address, a dummy bit and the read value. That is in total 11+8-bits. Mapping that to 8-bit transfer would be:

spi.transfer(0b110);
spi.transfer(addr << 1);
data = spi.transfer(0);

That will give 5-bit zero, start-bit, op-code in the first transfer, and followed by 7-bit address and dummy bit (LSB) in second transfer. The third transfer is the read data.

EWEN would map to:

spi.transfer(0b1001);
spi.transfer(0b10000000);

EWEN has op-code(00), followed by 9-bits, 0b11XXXXXXX.

The WRITE operation becomes:

spi.transfer(0b10);
spi.transfer(0x80 | addr);
spi.transfer(data);

Cheers!

  • I updated my .ino file per your suggestion: gist.github.com/anonymous/5f29911c6f1c15d0660f But now I get even stranger results, by writing 0 to all bits the output is '10000000' for the first half of the words and '11111111' for the second half. What is your reasoning behind doing address & 0x7f? – user3027128 Feb 25 '16 at 17:47
  • There is much more to consider with the other commands. In any case, the READ command has to create the sequence S(1), OP(10), ADDR(7-bit). The LSB of OP is MSB of the 8-bit with address therefore addr & 0x7f (alternatively alway keep address less than 128). The was a way to explain where the LSB of OP was. – Mikael Patel Feb 25 '16 at 18:52
  • You need to verify all other sequences and then there is a special dummy bit in READ response that needs some consideration. – Mikael Patel Feb 25 '16 at 18:53
  • Thanks for your help! I adjusted my code one final time and added some comments: gist.github.com/anonymous/3e085bd2d639f137d1a3 It might be useful for other in the future. – user3027128 Feb 26 '16 at 15:40
  • You are welcome. I had a look. Here are some possible changes (and tests). line 88-91: Could rewrite this as "data1 = (data1 << 1) | (data2 != 0);". line 82-85: Could you test this: "SPI.transfer(0b110); SPI.transfer(address << 1); data1 = SPI.transfer(0); " – Mikael Patel Feb 26 '16 at 15:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.