GithubHelp home page GithubHelp logo

eeprom-programmer's Introduction

Arduino EEPROM programmer

Copyright 2017 Ben Eater

This code and schematic are MIT licensed.

Circuit

This is a simple circuit for programming the 28C16, 28C64, 28C256, and similar parallel EEPROMs using an Arduino. Since the Arduino doesn’t have enough pins to directly control all of the address, data, and control lines of the EEPROM, two 74HC595 shift registers are used for the 11 address lines (15 for the 28C256) and the output enable control line.

Schematic of EEPROM programmer

What’s here?

There are four different Arduino sketches that correspond to several YouTube videos. A lot of the code is duplicated since each sketch built on the previous ones. But I’ve kept them separate to make it easier to find the exact code that goes with a particular video:

1. Basic programmer

The code in /eeprom-programmer is the basic programmer that programs a few bytes into the EEPROM and dumps the contents.

That software, along with the EEPROM programmer’s hardware are described in detail in the following video. This is a good place to start if you’re looking for the fastest way to make sense of this repo:

2. 8-bit decimal display

The code in /multiplexed-display is for programming an EEPROM to be used to decode 8-bit values and drive a 4-digit 7-segment display. Check out this video for more:

3. 8-bit computer microcode

The code in /microcode-eeprom-programmer is for programming a pair of EEPROMs to serve as an instruction decoder for an 8-bit breadboard computer. You’ll probably want to watch the whole 8-bit computer playlist (see below) for this to really make sense, but the specific videos describing the code here are:

4. 8-bit computer microcode with flags register

The code in /microcode-eeprom-with-flags adds functionality for a flags register to the microcode above to support conditional instructions. Again, you’ll likely want more context from the full series of videos, but here’s the video describing the code:

More information

This EEPROM programmer was designed as part of a larger project to build an 8-bit computer from scratch. There’s a much larger series of videos about this project on YouTube as well. In all likelihood, if this repo interests you, you want to binge that whole playlist.

eeprom-programmer's People

Contributors

beneater avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

eeprom-programmer's Issues

Question on the delay of 10 ms when writing to the EEPROM

In the video where you go through how to build an EEPROM programmer with the Arduino Uno you ended up using delay(10); at the end of the writeEEPROM() function. Did you come to any understanding why this was the case?

What if you want to write all the 2048 bytes, then it would take almost 20 seconds and it would be even worse for an EEPROM with 128 or 256 kbits.

Would it be possible to optimize the writeEEPROM() function to let it take an array of bytes and put the delay(10) at the end of writing all the bytes?

Write protected EEPROMS from China

Hi,
I've received several EEPROMs from Ebay, but I'm only able to program one of seven AT28C256.
Of course these are weird fakes or old dead ones, but I have tried to software erase those or disable protection. No luck yet. Am I doing it right?

Docs:
CHIP erase - http://ww1.microchip.com/downloads/en/Appnotes/doc0544.pdf
Protection - http://ww1.microchip.com/downloads/en/Appnotes/DOC0543.PDF

unsigned long time;
void setup() {
 pinMode(SHIFT_DATA, OUTPUT);
 pinMode(SHIFT_CLK, OUTPUT);
 pinMode(SHIFT_LATCH, OUTPUT);
 digitalWrite(WRITE_EN, HIGH);
 pinMode(WRITE_EN, OUTPUT);
 Serial.begin(230400);

 Serial.print("\nUnlocking EEPROM... ");
 time = millis();
 writeEEPROM(21845, 0xaa);
 writeEEPROM(10922, 0x55);
 writeEEPROM(21845, 0x80);
 
 writeEEPROM(21845, 0xaa);
 writeEEPROM(10922, 0x55);
 writeEEPROM(21845, 0x10);
 
 writeEEPROM(1, 0x55);
 writeEEPROM(2, 0xaa);
 writeEEPROM(32767, 0x55);

 time = millis() - time;
 Serial.print("...done in ");
 Serial.println(time);
 
 printContents();
 writeEEPROM(1, 0x55);
}

It finished in 12 ms as I have reduced WRITE_EN cycle:

 digitalWrite(WRITE_EN, LOW);
  delayMicroseconds(1);
  digitalWrite(WRITE_EN, HIGH);
  delay(1);

Any thoughts?

28c256 infinite loop while erasing

I modified the code so that it would overwrite the whole chip with 0xea. Turns out when i change the break condition in the erase loop to 32767 to match the size of the eeprom it goes into a seemingly infinite loop. My guess is that the 16 bit signed INT of the arduino overflows so that the break condition of the erase loop will never be met. Changing this to an unsigned INT solved the problem for me. But because of my inexperience with arduinos i could also be wrong.

Repeating last byte for all addresses

I'm having some difficulty with writing to the 256 eeprom. If I link pin 8 of the 74HC595 to GND the eeprom erases but won't write the test data. When I remove these the correct number of test bytes are written but they are all set to the value of the last byte of the test string. Any help would be appreciated.

at28c256 write protection

hi. i have a problem to program the at28c256 eeprom. with the at28c16 works perfectly . I have read in its datasheet that there is a write protection to unlock with a sequence of byte in some registers.
I have tried to write this sequence with the library write function, but it did't work

Read/Write to 0x8000-0xFFFF may cause damage to the chip

I'm not totally sure but my AT28C256 seems damaged. Adresses 0x7FE0 and 0x7FF0 returns 00 and when writting to them, the value is written to the next byte (respectively 0x7FE1 and 0x7FF1), and the same for 0x7FE2-0x7FEE and 0x7FF2-0x7FFE. Write 0x7FEF and 0x7FFF does nothing. I first though my wiring had an issue but everything seems fine when I read/write in 0X0000-0x7FDF so I guess my eeprom is damaged.

I guess that I damaged it trying to write at adresses > 0x7FFF because the Output Enable pin is then true whatever the outputEnable parameter is (I did that by mistake with a copy/paste of a write loop with base<=xxx where I replaced xxx by 32768). I think a simple address&=0x7FFF; at the beginning of the setAddress function would be more secure.
But again, not sure it was the problem but the fix is safe...

Lack of indirect memmory access implies need of self-modifying code (to be Turing-complete)

Sorry if this issue is in wrong place. I cannot find a project about 8-bit computer. But it is still about the data that are written to EEPROM.


With current microcode, the memory address register can be set only by address hard-coded in instruction operand. It is now difficult* to write code that access an array element:

*) by difficult i mean that you have to use self-modifying code, which is non-standard construction

C example:

uint8_t array[4] = {10, 11, 12, 13};
uint8_t index = 2;
uint8_t c;

c = array[index];

Assembly representation:

0: LDA 0xE ; load variable index to register A
1: ADD 0x9 ; add op-code of instruction which loads first element of an array
2: STA 0x3 ; modify next instruction so it will load data from array[index] instead of array[0]
3: LDA 0xA ; this is modified to LDA 0xC (A <-- array[index]) before running
4: STA 0xF ; save result to variable c
5: HLT;
6:
7:
8:
9: LDA 0xA ; instruction which would load array[0], used for indirect access
A: 10 ; array[0]
B: 11 ; array[1]
C: 12 ; array[2]
D: 13 ; array[3]
E:  2 ; index
F:  0 ; c (the result)

"Usual" instruction sets would be Turing-complete even if we disallow self-modifying code (e. g. forbid writes to code segment of memory). In fact, this is quite common: In "normal" computers, the program is run from RAM. But it is usually in write-protected segments and data segments are protected from execution. It is not that common for code to self-modify itself. Same applies also to theoretical models. Neither Turing Machine nor Random Access Machine can modify its own code. But both are Turing-complete.

On the other hand, the Turing completeness of your 8-bit computer instruction set relies on ability of code to self-modify. Without self-modifying code, it can access only constant size of memory. So it cannot do anything like loop through an input array. In that case this 8-bit computer would not be Turing-complete anymore.

It basically means, that it is Turing-complete, but in different way than "normal" computers. I know, that you want to keep your 8-bit computer as simple as possible, but for educational purpose this difference should be at least noted somewhere.

If i may use analogy with Turing Machine from your video "Making a computer Turing complete". Turing machine's new state depends on data, so we need conditional jump. And same apply to memory address: Turing machine's next memory address (head position) also depends on data, so we need to set memory register based on data and not just to position fixed by a code.

And yes, current implementation overcomes lack of indirect access with self-modifying code. That is something that Turing Machine or Random Access Machine cannot do -- both models cannot modify their code, so they both need some kind of indirect access.

I suggest to add a pair of instructions which would do indirect load/store operations. Load is quite simple to implement: we can define LDAX instruction which will load data from address stored in register A:

 { MI|CO,  RO|II|CE,  AO|MI,  RO|AI,  0,           0, 0, 0 },   // 1001 - LDAX

But there are few issues with store. There is no instruction to manipulate with B register directly, so instruction that would save A to address stored in B would be useless. (Unless something like MOV A -> B is also added.)

So second option is to have indirect instructions LDAI/STAI load/store from/to address stored in memory address specified with operand.

 { MI|CO,  RO|II|CE,  IO|MI,  RO|BI,  BO|MI,   RO|AI, 0, 0 },   // 1001 - LDAI
 { MI|CO,  RO|II|CE,  IO|MI,  RO|BI,  BO|MI,   AO|RI, 0, 0 },   // 1001 - STAI

Only problem is, that these instructions are too long: 6 steps. But maybe it is possible to write directly from RAM register to Memory register (i am not sure about buffering there):

 { MI|CO,  RO|II|CE,  IO|MI,  RO|MI,   RO|AI, 0, 0, 0 },   // 1001 - LDAI
 { MI|CO,  RO|II|CE,  IO|MI,  RO|MI,   AO|RI, 0, 0, 0 },   // 1001 - STAI

After that, the example from beginning can be written without code modification:

0: LDA  0xE ; load variable index to register A
1: ADD  0xA ; add address of first element of an array
2: STA  0x9 ; save pointer *array[index] to temporary variable
3: LDAI 0x9 ; indirect load
4: STA  0xF ; save result to variable c
5: HLT;
6:
7:
8:
9:  0 ; temporary variable used to overcame lack of address registers
A: 10 ; array[0]
B: 11 ; array[1]
C: 12 ; array[2]
D: 13 ; array[3]
E:  2 ; index
F:  0 ; c (the result)

Well. What i just wrote is not entirely true. Turing Machine may be still simulated even if we do not have indirect access and we forbid self modifications of code. But we would need to extend word size to incredible lengths and store whole array in just one word. Than something as indirect access can be simulated using bit shifts and masking. So it can be computed with current instructions without self-modification. But that would be even bigger hack, which is usually forbidden even in theoretical models like Random Access machine.

Typo in schematics (74HC595 pinout)

image

Pin 13 on the 74HC595 chips (the output enable pin, OE) is labeled as "G", and pin 8 (the ground pin, GND) is not labeled.
Both Pin 8 (GND) and Pin 13 (OE) need to be tied to ground for this design to work properly.

I saw "G" tied to ground and assumed that was referring to ground, and didn't give it a second thought. a couple hours later with the oscilloscope I finally figured out why it wasn't working for me- my OE pins were floating because I wasn't paying attention.

It's my own fault for not paying attention, but I'm submitting this just incase someone else has the same issue.

Actually a question.....

This is not actually an issue, but a question.
If we use Arduino Mega for this project, do we still need the 2 shift registers?
As I understand, Arduino Mega has enough pins to directly control all the lines of the EEPROM.

Thanks,
Panagiotis.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.