Skip to main content
Topic: 93C86 (Read 7683 times) previous topic - next topic

93C86

Hi everyone here (again), I had a new question for some pirate soul ;).

The last week I was repairing a circuit board and in order to get it working I need to read and write a 93C86 serial eeprom.

I had read some datasheets: http://www.atmel.com/atmel/acrobat/doc1237.pdf and http://ww1.microchip.com/downloads/en/devicedoc/21132e.pdf and it seems to use a 3 wire serial protocol, the protocol is not difficult to understand and I think that is not very difficult to implement.

Before to try to add such protocol to the bus pirate, I wish to know if it is already implemented on it, I think that is some kind of SPI in combination with a ChipSelect CS wire (a rising edge on CS and DI is the start bit), also it have a dual data width: 8bits or 16bits depending if the ORG ping is tied to VCC or GND/unconnected ..., well I didn't read the full datasheet and before to go in depth with it, I want to know if the bus pirate already support this kind of protocol.

That's it, thanks for your kind support

Re: 93C86

Reply #1
The bus pirate has two options for you: SPI or raw3wire. The first one is a pure spi and the second one let you interface SPI like busses. You can read more about the protocols and how to use them here; http://dangerousprototypes.com/bus-pirate-manual/

Re: 93C86

Reply #2
Ummm, maybe I will first try to full understand SPI and fight a bit my own stupidity ;).

Thanks mate.

Re: 93C86

Reply #3
This chip looks just like my 93C66 Serial EEPROM. It's very simple to interface with this.

CS -> CS
CLK -> CLK
MOSI -> DI
MISO -> DO
+5V -> Vcc
GND -> Vss


I would also tie ORG to Vss for 8-bit orginization, and PE to Vss to prevent accidental writes. When interfacing with the 93C66 it was best to use the raw3wire. The difference between SPI mode and RAW3WIRE is that RAW lets you toggle the clock, and MOSI high/low manually. You can also read the MISO pin state. Gives you granular control for the non-standard protocols. This comes in handy because the 93C66 needed 9-bits for a read address. I can send that 1 extra bit followed by a normal 8-bit address "0xFF". Here's what I suggest.

Enter raw3wire mode, enable power supplies if needed and set CS low with "[" command. Default is CS high when entering RAW mode.  Per data sheet DI high with CS high sets the start condition so "]0b1" is a start condition. Next is your OP code for read instruction "0b10" followed by an 11-bit address. Think of the first 3-bits as your block position and the last 8-bits as your position in that 256 byte block.

When sending binary, hex, or decimal I do believe the buspirate converts it to an 8-bit value so sending 0b1 really sends 00000001 down the wire. I'm not 100% on this. That being said, this should read the entire EEPROM.

Code: [Select]
]0b110 _^_^_^ 0x00 r:0x800[

CS high "]" followed by start condition with read OP instruction "0b110", then 3-bits low = 000  "_^_^_^" and 8-bit address "0x00". Now we read 0x800 = 2048 Bytes "r:0x800". Then set CS low "["

Read the first few bytes "]0b110 _^_^_^ 0x00 r:0x20[" then try reading for 0x801 "]0b110 _^_^_^ 0x00 r:0x801[". The address counter should loop and start at address 0 again. The last byte of the read will be the first byte at address 0. This should verify the size of the EEPROM. If you want to write to it, you'll need to tie PE to Vcc or leave it floating. You will also need to send the Write Enable OP code only once per power on.

Write Enable/EWEN:
Code: [Select]
]0b10011[

Write Disable/EWDS:
Code: [Select]
]0b10000[

Write Byte 0xEE at address 0:
Code: [Select]
]0b10011[
]0b101 _^_^_^ 0x00 0xEE[
]0b10000[

As you can see the Write instruction including the start bit is "0b101" followed by 11-bit address then 8-bits of data to be written. This should shed some light for ya. Say that 3 times fast:)

Re: 93C86

Reply #4
Hi mate, thanks for your answer.

I was reading the datasheets and when I decided to try something I had seen your post and is nearly the same that I was planing to try, buutttt ;), I get some problems.

As you suspect bus pirate pack data in this mode into bytes so, effectively ]0b110 is the start condition, followed by _^_^_^ and 0x00 seems is a complete read command, but 0b110 is sent as 0x06, so there are sent 5 not desired bits over the wire.

The chip that I'm trying to read is using the 16bits data configuration so it have 1024x16bits words, giving a 10 bits for address, but is nearly the same as the 8bit config.

Another problem I didn't know how to solve, and really don't know if it appears is that if you read one byte or word at a time the data out is preceded by a dummy zero before the real data, and worst, if you do sequential reads on the sequential ones this bit doesn't appears (as I'am seeing on the datasheets it seems that maybe isn't read as it appears before the read command ends and ends just before the read command ends, so I need to test what really happens).

Here you have some examples:
Code: [Select]
RAW3WIRE>]0b110 _^_^ 0x00 r:0x10[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x01 CLOCK TICKS
DATA OUTPUT, 0
0x01 CLOCK TICKS
WRITE: 0x00
READ 0x10 BYTES:
0x00 0x09 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

Code: [Select]
RAW3WIRE>]0b110 _^_^_^ 0x00 r:0x10[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x01 CLOCK TICKS
DATA OUTPUT, 0
0x01 CLOCK TICKS
DATA OUTPUT, 0
0x01 CLOCK TICKS
WRITE: 0x00
READ 0x10 BYTES:
0x00 0x12 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

What do you think?, I had not read anything about the binary modes but maybe is the way to go on, but it sounds a more complicated approach.

Again, thanks for your help.

Re: 93C86

Reply #5
When you send CS high, the EEPROM waits for DI to go high. When this happens it's a start condition. The 5 bits XXXXX110 are ignored because DI hasn't gone high yet to signal start. So you could use "0x06", or "0b110", or "6" and it will be the same result.

It seems like your getting data. Even if you don't take care of the dummy bit, you should be able dump all the data with a continous read. I see in the datasheet there is a dummy logic 0 sent after getting the read instruction. This is an ACK bit to acknowledge receipt of a correct instruction. This bit is only sent once if you are doing a continuous sequencial read.

Try:
Code: [Select]
]0b110 _^_^ 0x00 _^ r:0x401[
-or-
]0b110 _^:2 0x00 ! r:0x401[

Basicaly you need to just send an extra clock when you expect the dummy bit or you can read 1 bit w/clock "!" on the MISO.

I would make note of the 1st byte at address 0. Then dump the entire EEPROM+1 and see if the last byte matches. If it does, then you know how to read it.  0x400 = 1024x16.

The 2nd part of your log looks like the correct data.  We actually took care of the dummy bit because we thought we were using 11-bits for addressing in x8. Since your in x16 ORG it only needs 10-bits. So "_^_^_^ 0x00" = 11-bits. This would send 10-bits as 0, and while we try sending that 11th bit we are getting the ACK. The 11th bit sent is actually ignored because DO is sending the 0 on that clock cycle.  looking at your results 0x09 = 1001 in binary. If you shift it left 1 bit(Dummy bit) you get 0x12 = 10010

The best approach is to take a couple different dumps of the first few bytes and then actually write 1 byte to address 0. Then read it. This will make it clear as crystal. You'll then know if your 1 bit off in the read instruction. Since your in x16 you actually have to write minimum 2 bytes/16-bits. Let me know how it goes!

Re: 93C86

Reply #6
Hi akuma, now I'm at work, as soon as I arrive to home I will try it. I didn't noticed that the first five bits of 00000110 will be ignored due the start bit condition, ummm, your words are promising ;), in a few hours I will post the results.

See you in a moment ;)

Re: 93C86

Reply #7
I'm back.

Well akuma, that are the results :(, it seems that there must be another problem, I really don't know. I'm too conditioned by the target circuit as I can't desolder the chip (is partially under a servo motor), I can't try to write it before reading it (I need to put the content of the chip in another circuit), seeing the circuit it seems that the DI and DO are tied together (between them a resistor maybe a pullup or pulldown) ... too many constraints for a first approach.

Well, who said that this will easy ;). (that's the funny part)

Here are the tests I did:

Code: [Select]
RAW3WIRE>]0b110 _^:2 0x00 ! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ 0x08 BYTES:
0x00 0x12 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

That makes sense as you said on the last post.

Code: [Select]
RAW3WIRE>]0b110 _^:2 0x00 !! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ BIT: 0
READ 0x08 BYTES:
0x00 0x24 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

Ok, if we shift another bit it gets multiplied by 2, try to read 3 bits this time:

Code: [Select]
RAW3WIRE>]0b110 _^:2 0x00 !!! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ 0x08 BYTES:
0x00 0x48 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

Another left shift. from where comes that zeros? as DO go to high impedance and maybe is tied to a pullup resistor, umm, they must be ones ¿?, try another one:

Code: [Select]
RAW3WIRE>]0b110 _^:2 0x00 !!!! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ 0x08 BYTES:
0x00 0x90 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

Here we go wit another one:

Code: [Select]
RAW3WIRE>]0b110 _^:2 0x00 !!!!! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ 0x08 BYTES:
0x01 0x20 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

Well it continues shifting to the left. Trying some of crazy one: ]0b110 _^:2 0x00 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! r:8[

Code: [Select]
RAW3WIRE>]0b110 _^:2 0x00 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 1
READ BIT: 0
READ BIT: 0
READ BIT: 1
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ 0x08 BYTES:
0x00 0x00 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

Well we have 101 travelling to the left, and?, well I am not really really sure that I'm at 16bits mode (it seems it because there is no trace to that pin at least visually, because I cant access to it (I can't remove the upside motor), but the 8bit results are saying the same:

Code: [Select]
RAW3WIRE>]0b110 _^:3 0x00 ! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x03 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ 0x08 BYTES:
0x00 0x24 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

Well I'm flying blind ;), any suggestion?

I will be out working until tomorrow so I will not answer or can do tests in 18 hours (more or less), but on Friday night I will have another circuit on which I can remove or break the motor to have direct access to the eeprom and work in better conditions.

Until tomorrow, see you and thanks, regards from Spain.

Re: 93C86

Reply #8
Take a few dumps:
Code: [Select]
]0b110 _^:2 0x00 r:8[
]0b110 _^:2 0x00 ! r:8[
]0b110 _^:2 0x00 !! r:8[
]0b110 _^:2 0x00 !!! r:8[

Write down the first two bytes of each dump. Then I would try a full eeprom dump+1.

Code: [Select]
]0b110 _^:2 0x00 r:0x401[
]0b110 _^:2 0x00 ! r:0x401[
]0b110 _^:2 0x00 !! r:0x401[
]0b110 _^:2 0x00 !!! r:0x401[
The last byte of the read should match the bytes you wrote down. The internal address counter will have looped and ended at address "_^_^ 0x01" IF we are in x16 mode. x8 would require "r:0x801" for the same result. If the data matches, then you have succesfully interfaced with this EEPROM. If it doesn't match and all you get is 0xFF after the first "0x00 0x12" then you have a conflict or possible pull-up/pull-down issue.

1025x16
Code: [Select]
RAW3WIRE>]0b110 _^:2 0x00 ! r:0x401[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ 0x00 BYTES:
0x00 0x12 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF......................................................................0x00 0x12
CS ENABLED
RAW3WIRE>

1026x16
Code: [Select]
RAW3WIRE>]0b110 _^:2 0x00 ! r:0x402[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ 0x00 BYTES:
0x00 0x12 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF......................................................................0x00 0x12 0xFF 0xFF
CS ENABLED
RAW3WIRE>

These are my predictions. Once you feel that you have the correct output, try and write over address 0. Replace 0x00 with 0xEE and read it back. You should see "0xEE 0x12 0xFF...".

Re: 93C86

Reply #9
Hi akuma, how are you?

Before going to bed I had done some tests, before the good news, I desoldered another eeprom from another circuit and I'm having a bit of bad luck and it's like yours, a 93C66. After desoldering and soldering some wires, I can read it perfectly & repeatedly, so it will be a problem of the target circuit.

Here are the various tests you suggest me:

Code: [Select]
RAW3WIRE>]0b110 _^:2 0x00 r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ 0x08 BYTES:
0x00 0x09 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>]0b110 _^:2 0x00 r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ 0x08 BYTES:
0x00 0x09 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>]0b110 _^:2 0x00 r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ 0x08 BYTES:
0x00 0x09 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>]0b110 _^:2 0x00 ! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ 0x08 BYTES:
0x00 0x12 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>]0b110 _^:2 0x00 ! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ 0x08 BYTES:
0x00 0x12 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>]0b110 _^:2 0x00 !! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ BIT: 0
READ 0x08 BYTES:
0x00 0x24 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>]0b110 _^:2 0x00 !!! r:8[
CS DISABLED
WRITE: 0x06
DATA OUTPUT, 0
0x02 CLOCK TICKS
WRITE: 0x00
READ BIT: 0
READ BIT: 0
READ BIT: 0
READ 0x08 BYTES:
0x00 0x48 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
CS ENABLED
RAW3WIRE>

Also I tried 0x401 and 0x801 with no,one,two and three exclamations having a dump of two bytes and the rest of 0xFF.

So before to continue I must check the target circuit to be sure that all is ok, but it seems that I'm forgetting something or doing something bad (uffff, I need to sleep a bit).

Tomorrow afternoon a bit more (I will recheck the target circuit for strange pullups/pulldowns), in the meantime, have a nice day, Cheers, beth.

Re: 93C86

Reply #10
Hi (hello akuma), last week I was a bit busy and I must wait for the weekend to try something with the 93CXX chips.

In order to automatize the reading and writing tasks of this chips, I decided to write some Python code to support the Micro Wire protocol.

I'm not a Python programmer and my background is C/C++/C# or whatelse that starts with C, so maybe the code has errors, is not optimun and so on, so take that into consideration and if you find any improvement, feel free to modify the code or tell me it and will do de modifications for you.

Well, the code consist a first try to read a memory chip that uses the 3 wire Micro Wire serial protocol, you can see that on the MicroWire.py file, and use the supplied shell script 93C66.sh to see some command line arguments of it.

The last two days I was getting repetitive results (good or bad but repetitive between runs), but yesterday when I was merging the code with the code.google.com repository, I found that the github repository of Sean Nelson was not synced with the google's one, so I really don't know why but actually I don't have the same results between runs, maybe yesterday night I was a bit tired and I have some bad probe contact or something similar, I will check this afternoon/night.

Please akuma, could you download the code from the google repository: http://code.google.com/p/the-bus-pirate/source/checkout, and try the "/scripts/pyBusPirateLite/93C66.sh" and see the results, use if you want the -m 8 to read 8 extra elements, (ummm, maybe -e will be more descriptive than -m "more", bahh who cares).

Another thing that I detect, the reading proccess is really slow, I think by the delays used on the pyBusPirateLite, but when it works I will try to reduce that delays.

That's it for now, later I will do more tests, and post results here. Regardsssssss.