4

Alright, so I have an Atmel 93C66, http://www.atmel.com/Images/doc0172Z.pdf Datasheet and I'm wanting to read whatever is in it.

I copied the following code from this thread http://forum.arduino.cc/index.php?topic=96411.0 and made some changes to it, mainly I deleted the part where it writes:

//difining pins for eeprom   
int CLOCK =4;          
int DATA_OUT =3;
int DATA_IN = 2;
int CHIP_SEL =5;

int low =0;     //low address 

byte READ  = 0b1100;                //read instruction 

void setup(){

  pinMode(CLOCK ,OUTPUT);
  pinMode(DATA_OUT ,OUTPUT);
  pinMode(DATA_IN ,INPUT);
  pinMode(CHIP_SEL ,OUTPUT);
  digitalWrite(CHIP_SEL ,LOW);
  digitalWrite(CLOCK, LOW);
  Serial.begin(9600); 
}

void loop()
{

  for (int i=0;i<=511;i++)
  { 
    digitalWrite(CHIP_SEL ,HIGH);
    shiftOut(DATA_OUT,CLOCK,MSBFIRST,READ); //sending READ instruction 
    shiftOut(DATA_OUT,CLOCK,MSBFIRST,low);   //sending low address
    byte incoming = shiftIn(DATA_IN,CLOCK,MSBFIRST); //receiving data
    digitalWrite(CHIP_SEL ,LOW);

    Serial.print(low);
    Serial.print("/t");
    Serial.print(incoming, BIN);
    Serial.print("/t");
    Serial.print(incoming, HEX);
    Serial.println():

    low++;       //incrementing low address

  } 
  while(1);
}

What I'm trying to understand is:

In the 93C66 datasheet page 5, table 6, it says that to read the contents of memory I need to send SB 1, OPCODE 10, and memory address, which I don't know exactly how to do, but I guess the chip wants a 110 (or a HIGH, HIGH, LOW signal) plus memory address (variable “low”=0). The SB and OP CODE are similar to the BYTE variable READ in the code above, but this variable has an extra 0 (1100). I tested the code with 110 and I get different incoming data. I also thought if BYTE is 8 bits then why not make the BYTE variable READ 11000000, but it changes the incoming data. So now I don't really know how exactly to send SB 1 and OP CODE 10. Need help with that.

Also, as you can see I'm printing the variable "low" and the variable "incoming" (in Binary and Hex) on one line, I thought it would be printing 1 bit per line, but it prints varying amounts of bits. Sometimes it would print 4 bits, 6 bits, or 8 bits, as in 1110, 11111111, 111100. I thought the line byte incoming = shiftIn(DATA_IN,CLOCK,MSBFIRST); would get filled with 8 bits all the time, so when I Serial.print() it would have 8 bits, but it's not happening, why?

Also I thought the shifting in of the bits into the variable "incoming" occurs once in the for loop, or is there an inner loop in shiftIn()? I ask because I first made the for loop go for i=<4095, since there are 4096 bits in this EEPROM, but the increment of I doesn’t match the amount of bits I’m getting on each Serial.print() line. i.e. I would get something like this:

1   10111111    BF 

I thought it would be getting something like this. (I’m thinking the shiftIn() of the 1st bit at address 0 happens when i=0, then 2nd bits gets shiftIn() when i=1, and so forth)

1   1   
2   1   
3   0
4   1
Etc, etc

How is shiftIn() shiftinf in the bits into the BYTE variable?

Thanks and sorry if it’s so many questions.

2

OK I know this is a little late, but for other readers having the same problem, here's a sketch I wrote to read a 93c46 when I had to dump the EEPROM from a car radio. I've deliberately not included the EWEN instruction anywhere as the last thing I wanted to do was accidentally write to the EEPROM.

The key is the modified shiftOut routine which adds a parameter specifying how many bits you want to shift out.

To adapt sketch for other 93c packages, change the number of 16bit words at start of loop{} and number of address bits in 2nd call to myshiftOut.

If your package has an ORG pin, tie it to Vcc.

Hope this helps someone...

/*
Arduino Uno sketch to dump a 93c46 EEPROM in 16 bit mode.  Metalbanana 12/9/16, with thanks to raint.
Easily modified for other 93c series parts. Note many 93c46 from autos are 'rotated' pinout,
i.e. those with a T following part no. e.g. 'TEM8':

1=NC    8=ORG
2=Vcc   7=GND
3=CS    6=DO
4=SK    5=DI

so check pcb for Vcc and GND locations with a meter first! An Arduino ProtoShield is ideal to mount IC
as it has a SOIC pad (Note: you can't use the mini breadboard at same time as it covers one set of headers).
Standard shiftOut is not suitable as it sends 8 bits, our addresses are 6 bits,
instructions are 3 bits so sketch uses a modified shiftOut called myshiftOut.
*/



// define pins for eeprom
const int CHIP_SEL = 8;  // to CS
const int CLOCK = 9;     // to SK
const int DATA_IN = 10;  // to DO
const int DATA_OUT = 11; // to DI

const byte READ  = B110;                //read instruction

bool debug = 0;


void myshiftOut(uint8_t dataPin, uint8_t clockPin, uint8_t bitOrder, byte val, uint8_t bits)
{
  for (int i = 0; i < bits; i++)  {
    if (bitOrder == LSBFIRST) {
      digitalWrite(dataPin, !!(val & (1 << i)));
      if (debug)Serial.print(!!(val & (1 << i)));
    }
    else
    {
      digitalWrite(dataPin, !!(val & (1 << (bits - 1 - i))));
      if (debug)Serial.print(!!(val & (1 << (bits - 1 - i))));
    }
    digitalWrite(clockPin, HIGH);
    digitalWrite(clockPin, LOW);
  }
}


void setup() {
  pinMode(CHIP_SEL, OUTPUT);
  pinMode(CLOCK, OUTPUT);
  pinMode(DATA_OUT, OUTPUT);
  pinMode(DATA_IN, INPUT_PULLUP);

  Serial.begin(9600);
  Serial.println("\n\n");
}



void loop()
{
  for (int addr = 0; addr < 64; addr++) // 64 words for 93c46
  {
    // print address at start of each line
    if (addr % 8 == 0) {
      Serial.println();
      if (addr < 8) Serial.print("0");
      Serial.print(addr * 2, HEX);
      Serial.print(": ");
    }

    digitalWrite(CHIP_SEL, HIGH);
    myshiftOut(DATA_OUT, CLOCK, MSBFIRST, READ, 3); //send READ instruction
    myshiftOut(DATA_OUT, CLOCK, MSBFIRST, addr, 6); //send address, 6 bits for 93c46


    digitalWrite(CLOCK, LOW); // recommended in language reference
    byte incomingH = shiftIn(DATA_IN, CLOCK, MSBFIRST); //receive high byte
    byte incomingL = shiftIn(DATA_IN, CLOCK, MSBFIRST); //receive low byte

    // reverse byte order & print
    if (incomingL < 16) Serial.print("0");
    Serial.print(incomingL, HEX);
    Serial.print(" ");
    if (incomingH < 16) Serial.print("0");
    Serial.print(incomingH, HEX);
    Serial.print(" ");

    digitalWrite(CHIP_SEL, LOW);
  }

  while (1);
}

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.