hello, thx for your share, I tried to flash a chip with this process I have the message "EPROM programmed successfully" but the chip remains empty when I test it. Do you have any idea what's going on? thank you for your reply
my chip is a D8748HD that may be the problem? Otherwise I modify the order of the pins to adapt it to a pcb but I have checked several times and the code corresponds well to the outputs, SO?
/*
Sketch for programming EPROM in Intel D8748H microcontroller using an Arduino Uno
Note the D8748H uses different programming voltages than the 8748.
Inspired by a solution by SaabFAN on EEVblog forum for the 8742 and Ardunio Nano:
[url]https://www.eevblog.com/forum/microcontrollers/simple-programmer-for-vintage-intel-mcs-48-microcontroller/[/url]
Reference: Intel D8748H datasheet [url]http://www.alldatasheet.com/datasheet-pdf/pdf/80208/INTEL/D8748H.html[/url]
Programming the D8748H version requires:
VCC = 5 +/- 0.25 total supply current @ VCC = 100 mA max
VDD_H = 21 +/- 1.0 @ 20 mA max
VDD_L = VCC @ 15 mA max
PROG_H = 18 +/- 0.5 @ 1 mA max
PROG_L = float or 4.0 to VCC @ 1 mA max
EA_H = 18 +/- 0.5 @ 1 mA max
EA_L = VCC
also, P10 & P11 must be tied to ground.
In addition to these signals, the 8748 needs a crystal on pins 2&3, 5V on pin 40 and 0V on pin 20.
The datasheet says there must be a floating state on PROG.
Each byte is programmed then read back immediately for verification. If there is not a match,
programming stops with an error message. To test the hardware is working, the "break" statement
in Step 12 can be commented out and the Arduino will go through the full programming cycle
without stopping.
This code is in the public domain. Use at your own risk, and have fun!
*/
// Put your EPROM program in this array hexProg[]. Use 8bit HEX-Values separated by a ",".
// Set progSize to number of bytes in program.
// The example program data here is for the POLYSIX 8048 cpu board.
#include <avr/pgmspace.h>
const int progSize = 1024;
const byte hexProg[progSize] PROGMEM = {
0x99, 0x1F, 0x27, 0x54, 0xD6, 0x54, 0xDC, 0xD7, 0x09, 0x92, 0x0D, 0x64,
0xB9, 0xD5, 0xB9, 0x14, 0x23, 0x01, 0xA1, 0x19, 0xA1, 0x19, 0x27, 0xA1,
0x19, 0xA1, 0xBB, 0x40, 0xAE, 0x85, 0x24, 0xC8, 0x23, 0x0D, 0xAF, 0x17,
0xAD, 0xBE, 0x00, 0x54, 0x1A, 0x23, 0xFD, 0x62, 0x55, 0xFF, 0x3A, 0x03,
0x20, 0xA8, 0xF0, 0x02, 0x89, 0x40, 0x23, 0x20, 0x6E, 0xA8, 0xB9, 0x10,
0x23, 0xF8, 0x6E, 0xF6, 0x44, 0xFE, 0x04, 0x45, 0x19, 0x03, 0xEF, 0xE3,
0xAB, 0xF9, 0xD5, 0x03, 0xFC, 0xA9, 0xC5, 0xFB, 0x51, 0x96, 0xA5, 0xC9,
0xC9, 0xF1, 0x5B, 0xC6, 0x6A, 0x23, 0xFE, 0x6C, 0xE6, 0x73, 0x23, 0x02,
0x6C, 0xF6, 0x73, 0x19, 0x19, 0xF1, 0x4B, 0xA1, 0x04, 0xA5, 0xFC, 0xC6,
0x70, 0x37, 0x96, 0x73, 0xF1, 0x4B, 0xA1, 0x23, 0x30, 0x6E, 0xA9, 0xF1,
0x37, 0x17, 0x6C, 0xAA, 0xFB, 0xD5, 0x51, 0xC5, 0x96, 0x92, 0xFA, 0xF2,
0x87, 0x04, 0x89, 0x37, 0x17, 0x03, 0xFD, 0xE6, 0xA7, 0xFB, 0xD5, 0x41,
0xA1, 0xC5, 0xFA, 0xF2, 0x9C, 0x60, 0xE6, 0xA0, 0x27, 0x37, 0x04, 0xA0,
0x60, 0xF6, 0xA0, 0x27, 0xA0, 0xFC, 0xA1, 0x04, 0xA7, 0xFC, 0xA0, 0x16,
0xAB, 0x04, 0xA7, 0x65, 0xFE, 0xAF, 0x1E, 0x99, 0xBF, 0xED, 0x27, 0xB8,
0x2E, 0xB9, 0x12, 0xBD, 0x00, 0xD5, 0xB8, 0x3E, 0xBA, 0xFE, 0xBB, 0x10,
0xC5, 0xBE, 0x02, 0x54, 0x30, 0xAC, 0xD5, 0xD0, 0xC5, 0xAA, 0x23, 0xC9,
0x68, 0xE3, 0xAF, 0xFD, 0x03, 0xF9, 0xE3, 0xAB, 0x51, 0x96, 0xDE, 0xFA,
0x5B, 0xC6, 0xE5, 0xF1, 0x4B, 0xA1, 0xFB, 0x37, 0x50, 0x2B, 0x5C, 0x4B,
0xA0, 0x1D, 0xEF, 0xCF, 0xF0, 0x02, 0x18, 0x19, 0xD5, 0x0A, 0x4B, 0x3A,
0x18, 0xFB, 0xE7, 0xAB, 0xC5, 0x9A, 0x0F, 0xEE, 0xC3, 0x86, 0xFD, 0x04,
0xFF, 0x64, 0x1E, 0x89, 0x20, 0xB9, 0x16, 0x54, 0x30, 0x21, 0x37, 0x51,
0x96, 0x0C, 0x24, 0x2E, 0xBA, 0xFF, 0x1A, 0x67, 0xE6, 0x0E, 0xC9, 0x23,
0xEF, 0x51, 0xA1, 0xAB, 0xC9, 0x23, 0xEF, 0x6A, 0xE3, 0xA1, 0xFA, 0x47,
0xD5, 0x2E, 0x53, 0x80, 0x4E, 0xAE, 0xC5, 0x23, 0x20, 0x5B, 0x96, 0xAF,
0x24, 0xC7, 0x19, 0x54, 0x30, 0x21, 0x37, 0x51, 0xAC, 0x23, 0x40, 0x51,
0x4C, 0xAC, 0xC9, 0xC9, 0x53, 0x0F, 0xC6, 0x6F, 0xBA, 0xFF, 0x1A, 0x67,
0xE6, 0x42, 0x23, 0xEF, 0x6A, 0xE3, 0x21, 0x53, 0xF0, 0x41, 0xA1, 0xAB,
0xFA, 0x37, 0x85, 0x32, 0x56, 0x95, 0xD5, 0x12, 0x5E, 0x23, 0x80, 0x4E,
0x24, 0x61, 0x23, 0x70, 0x5E, 0xAE, 0xC5, 0x23, 0x20, 0x5B, 0x96, 0x8D,
0x23, 0x10, 0x5B, 0x96, 0x86, 0x24, 0xC7, 0x23, 0x10, 0x5C, 0xC6, 0x86,
0xF1, 0x43, 0x10, 0x53, 0xDF, 0xA1, 0xC9, 0x27, 0xA1, 0x37, 0xB8, 0x04,
0xC9, 0xA1, 0xE8, 0x80, 0x44, 0x04, 0xB9, 0x15, 0x23, 0x20, 0x51, 0xC6,
0x98, 0xFC, 0x53, 0x40, 0xC6, 0xA9, 0xD5, 0x23, 0x05, 0x6F, 0x24, 0xA6,
0xFC, 0x37, 0x53, 0x60, 0xC6, 0xA0, 0x44, 0x04, 0xF1, 0x43, 0x20, 0xA1,
0xD5, 0x27, 0xAF, 0x44, 0x04, 0xF1, 0x53, 0xDF, 0xA1, 0x44, 0x04, 0xD5,
0xB8, 0x20, 0xFE, 0xA9, 0x27, 0xB6, 0xB9, 0x24, 0xBB, 0x43, 0x02, 0x3A,
0xBD, 0x10, 0xF0, 0x54, 0x58, 0x18, 0xED, 0xBE, 0xC5, 0x24, 0xDE, 0xD5,
0xB8, 0x20, 0xFE, 0xA9, 0x23, 0x01, 0xB6, 0xD2, 0x24, 0xD4, 0x43, 0x02,
0x3A, 0xBD, 0x10, 0x54, 0x45, 0xA0, 0x18, 0xED, 0xD7, 0xC5, 0xB9, 0x0C,
0x27, 0xBA, 0x08, 0xA1, 0x19, 0xEA, 0xE3, 0xBE, 0x00, 0xB8, 0x30, 0xBD,
0x0E, 0x54, 0x1A, 0xA0, 0x18, 0x1E, 0xED, 0xED, 0xB8, 0x3E, 0xD5, 0xBA,
0xFE, 0x54, 0x30, 0xA0, 0x18, 0x54, 0x30, 0xA0, 0xB9, 0x15, 0x24, 0xA9,
0xD5, 0xB8, 0x14, 0xF0, 0x54, 0xD6, 0x18, 0xFF, 0x77, 0x5F, 0x77, 0x53,
0x20, 0x37, 0x50, 0x54, 0xDC, 0xC5, 0x99, 0xDF, 0x04, 0x20, 0xFE, 0x53,
0x0F, 0x3A, 0xBB, 0x80, 0x27, 0xAC, 0xBA, 0x08, 0x6B, 0x02, 0x2B, 0x77,
0x2B, 0x26, 0x2C, 0xAC, 0xFC, 0xEA, 0x24, 0x83, 0xD5, 0xFA, 0x02, 0xE7,
0xAA, 0x09, 0x43, 0xF0, 0xAD, 0xFA, 0x02, 0xE7, 0xAA, 0x09, 0x47, 0x43,
0x0F, 0x5D, 0x37, 0xC5, 0x83, 0x89, 0x80, 0x9A, 0xFE, 0x81, 0x53, 0x0F,
0xAA, 0x8A, 0x01, 0x81, 0x99, 0x7F, 0x47, 0x53, 0xF0, 0x4A, 0x19, 0x83,
0x89, 0x80, 0x9A, 0xFE, 0x91, 0x47, 0x8A, 0x01, 0x91, 0x99, 0x7F, 0x19,
0x83, 0x54, 0x74, 0xF6, 0x65, 0xBF, 0x08, 0x54, 0x74, 0x2B, 0x67, 0x2B,
0xEF, 0x6B, 0xFB, 0x83, 0x97, 0xBA, 0x00, 0x76, 0x7F, 0x56, 0x87, 0xEA,
0x79, 0x44, 0x83, 0x46, 0x87, 0xEA, 0x7F, 0xBD, 0x01, 0xBE, 0x01, 0xB5,
0x16, 0x8B, 0xA7, 0x23, 0xFA, 0x62, 0x54, 0xE2, 0x83, 0xAB, 0x97, 0x54,
0xA5, 0xBF, 0x08, 0xFB, 0x67, 0xAB, 0x54, 0xA5, 0xEF, 0x97, 0x97, 0xA7,
0x54, 0xA5, 0x54, 0xA5, 0x83, 0x54, 0xF0, 0x0A, 0x52, 0xAE, 0x43, 0x0C,
0x44, 0xB0, 0x53, 0x03, 0xAA, 0x23, 0xFC, 0xF6, 0xBA, 0xF7, 0x2A, 0xD3,
0x08, 0x2A, 0x16, 0xBE, 0x44, 0xBA, 0x62, 0xFA, 0x3A, 0x83, 0x54, 0x65,
0xD3, 0x50, 0x96, 0xC2, 0x54, 0x65, 0xD3, 0x36, 0x96, 0xC2, 0x83, 0xB8,
0x00, 0xBD, 0x02, 0x9A, 0xFD, 0x83, 0x02, 0x8A, 0x40, 0x9A, 0xBF, 0x83,
0x02, 0x8A, 0x80, 0x9A, 0x7F, 0x83, 0xB6, 0xE6, 0x44, 0xF0, 0x23, 0x7F,
0x02, 0x09, 0x52, 0xEE, 0x44, 0xF0, 0x64, 0x1E, 0x86, 0xF4, 0x04, 0x00,
0x23, 0xBF, 0x02, 0x09, 0x72, 0xFC, 0x64, 0x1E, 0x83, 0x54, 0xDC, 0x27,
0xAC, 0x54, 0xD6, 0x55, 0x83, 0x23, 0xC0, 0x49, 0x37, 0x96, 0x12, 0xFC,
0x97, 0xA7, 0xF7, 0xAC, 0x54, 0xD6, 0x83, 0x97, 0xA7, 0xBF, 0x00, 0x54,
0xA5, 0xEF, 0x17, 0xEE, 0x17, 0x83, 0x27, 0x54, 0xD6, 0x54, 0xDC, 0xD7,
0x85, 0x65, 0x54, 0xF0, 0x37, 0x12, 0x31, 0x52, 0x8C, 0x32, 0x61, 0x64,
0x24, 0x23, 0x01, 0x54, 0xFD, 0xBE, 0x28, 0x74, 0x13, 0x23, 0x50, 0x54,
0x91, 0x23, 0x36, 0x54, 0x91, 0x54, 0xCF, 0x64, 0x47, 0x8A, 0x02, 0xBE,
0x00, 0xB9, 0x00, 0x54, 0x45, 0x28, 0x68, 0x28, 0x54, 0x91, 0x74, 0x05,
0xEE, 0x4B, 0xED, 0x45, 0xF8, 0x54, 0x91, 0xBE, 0x06, 0x74, 0x13, 0x64,
0x1E, 0x95, 0x54, 0xE2, 0x23, 0x02, 0x54, 0xFD, 0x54, 0xC2, 0x23, 0x32,
0x54, 0xDC, 0x54, 0xCF, 0x64, 0x74, 0x8A, 0x02, 0xBE, 0x00, 0xB9, 0x00,
0x54, 0x65, 0x28, 0x68, 0x28, 0x54, 0x58, 0x74, 0x05, 0xEE, 0x78, 0xED,
0x72, 0x54, 0x65, 0xD8, 0x96, 0xB3, 0x64, 0x1E, 0x23, 0x04, 0x54, 0xFD,
0x54, 0xC2, 0x23, 0x14, 0x54, 0xDC, 0x54, 0xCF, 0x64, 0x9C, 0x8A, 0x02,
0xBE, 0x00, 0xB9, 0x00, 0x54, 0x65, 0x28, 0x68, 0x28, 0xAB, 0x54, 0x45,
0xDB, 0x96, 0xB3, 0x74, 0x05, 0xEE, 0xA0, 0xED, 0x9A, 0x64, 0x85, 0x23,
0x08, 0x54, 0xDC, 0x64, 0x24, 0xB8, 0x0C, 0xB9, 0x0C, 0xBE, 0x00, 0x54,
0x1A, 0x74, 0xD9, 0x19, 0x1E, 0x54, 0x1A, 0x37, 0x74, 0xD9, 0xBA, 0x04,
0x21, 0xF7, 0x21, 0x20, 0x67, 0x20, 0xEA, 0xCC, 0xF0, 0x54, 0xD6, 0x64,
0xBB, 0x96, 0xDE, 0xB1, 0x10, 0x83, 0x03, 0xFE, 0xF6, 0xE5, 0xB1, 0x20,
0x83, 0x03, 0xFE, 0xF6, 0xEC, 0xB1, 0x40, 0x83, 0xB1, 0x80, 0x83, 0x01,
0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x04, 0x03, 0x03, 0x0C, 0x30,
0xC0, 0x01, 0x0E, 0xF0
};
// Pin assignments from Uno to the 8748
int DB0 = 4; //DB0-DB7 are 8748 pins 12-19
int DB1 = 5;
int DB2 = 6;
int DB3 = 7;
int DB4 = 8;
int DB5 = 9;
int DB6 = 10;
int DB7 = 11;
int P20 = A0; //P20, P21 are 8748 pins 21, 22
int P21 = A1;
// int P23 = A2;
int TEST0 = 2; // 8748 pin 1 //2
int RESET = 3; // 8748 pin 4 //3
int EA_H = A3; // transistor switch for EA high (8748 pin 7)
int VDD_H = A5; // transistor switch for VDD high (8748 pin 26)
int PROG_H = A4; // transistor switch for PROG high (8748 pin 25)
int incomingByte;
boolean programmedFlag = false;
boolean errorFlag = false;
//--------------------------------------------------------------------------------------
void setup() {
Serial.begin(9600); // Actions will be echoed to the monitor. Make sure it is open.
// Setup the Control-Pins
pinMode(P20, OUTPUT);
pinMode(P21, OUTPUT);
pinMode(TEST0, OUTPUT);
pinMode(RESET, OUTPUT);
pinMode(EA_H, OUTPUT);
pinMode(VDD_H, OUTPUT);
pinMode(PROG_H, OUTPUT);
//DB0-7 are bidirectional, so set their mode later.
// Initial state from data sheet
digitalWrite(TEST0, HIGH); // 5V
digitalWrite(RESET, LOW); // 0V
digitalWrite(EA_H, LOW); // EA = 5V
digitalWrite(VDD_H, LOW); // VDD = 5V
digitalWrite(PROG_H, LOW); // PROG floating
Serial.println("D8748H Programmer READY");
Serial.println("Command: press p to program 8748 EPROM");
Serial.println();
}
//--------------------------------------------------------------------------------------
void loop() {
if (Serial.available() > 0) {
incomingByte = Serial.read();
if (incomingByte == 'p') {
if (!programmedFlag) { // prevent accidental attempt to reprogram chip
Program_8748();
programmedFlag = true;
}
}
}
}
//--------------------------------------------------------------------------------------
void Program_8748() {
// Steps are from datasheet programming instructions. Steps 1 and 2 already done in setup().
// Step 3: TEST0 = 0V (select program mode).
digitalWrite(TEST0, LOW);
delay(1); // 8748 needs at least 4 clock cycles (~20 uS) to process each change
// Step 4: EA = 18V (activate program mode),
digitalWrite(EA_H, HIGH);
delay(1);
for (int address = 0; address < progSize; address++) {
// Step 5 (repeats from here for all program bytes): Address applied to BUS and P20-1.
pinMode(DB0, OUTPUT);
pinMode(DB1, OUTPUT);
pinMode(DB2, OUTPUT);
pinMode(DB3, OUTPUT);
pinMode(DB4, OUTPUT);
pinMode(DB5, OUTPUT);
pinMode(DB6, OUTPUT);
pinMode(DB7, OUTPUT);
digitalWrite(DB0, bitRead(address, 0)); // output the address
digitalWrite(DB1, bitRead(address, 1));
digitalWrite(DB2, bitRead(address, 2));
digitalWrite(DB3, bitRead(address, 3));
digitalWrite(DB4, bitRead(address, 4));
digitalWrite(DB5, bitRead(address, 5));
digitalWrite(DB6, bitRead(address, 6));
digitalWrite(DB7, bitRead(address, 7));
digitalWrite(P20, bitRead(address, 8));
digitalWrite(P21, bitRead(address, 9));
delay(1);
// Step 6: RESET = 5V (latch address).
digitalWrite(RESET, HIGH);
delay(1);
// Step 7: Data applied to BUS.
digitalWrite(DB0, bitRead(hexProg[address], 0));
digitalWrite(DB1, bitRead(hexProg[address], 1));
digitalWrite(DB2, bitRead(hexProg[address], 2));
digitalWrite(DB3, bitRead(hexProg[address], 3));
digitalWrite(DB4, bitRead(hexProg[address], 4));
digitalWrite(DB5, bitRead(hexProg[address], 5));
digitalWrite(DB6, bitRead(hexProg[address], 6));
digitalWrite(DB7, bitRead(hexProg[address], 7));
delay(1);
// Step 8: VDD = 21V (programming power).
digitalWrite(VDD_H, HIGH);
// datasheet says no delay needed here.
// Step 9: PROG = float followed by one 50 to 60 ms pulse to 18V.
digitalWrite(PROG_H, HIGH);
delay(55);
digitalWrite(PROG_H, LOW);
// datasheet says no delay needed here.
// Step 10: VDD = 5V.
digitalWrite(VDD_H, LOW);
delay(1);
// Step 11: TEST0 = 5V (verify mode).
digitalWrite(TEST0, HIGH);
delay(1);
// Step 12: Read and verify data on BUS.
byte verifyByte = readByte(address);
if (verifyByte != hexProg[address]) {
errorFlag = true;
Serial.print("ERROR ---> ");
Serial.print("address = ");
Serial.print(address, HEX);
Serial.print(" program byte = ");
Serial.print(hexProg[address], HEX);
Serial.print(" verified byte = ");
Serial.println(verifyByte, HEX);
// break; // jump out of loop
}
// Step 13: TEST0 = 0V.
digitalWrite(TEST0, LOW);
delay(1);
// Step 14: RESET = OV and repeat from step 5.
digitalWrite(RESET, LOW);
delay(1);
} // end loop
// Step 15: Programmer should be at conditions of step 1 when 8748 is removed from socket.
digitalWrite(TEST0, HIGH); // 5V
digitalWrite(RESET, LOW); // 0V
digitalWrite(EA_H, LOW); // EA = 5V
digitalWrite(VDD_H, LOW); // VDD = 5V
digitalWrite(PROG_H, LOW);
if (errorFlag) {
Serial.println("Exited with ERROR!");
} else {
Serial.println("EPROM programmed successfully.");
}
}
//--------------------------------------------------------------------------------------
byte readByte(int address) {
// Returns the EPROM byte at location "address".
byte result;
// make sure EA is high and PROG is floating (they should be anyway)
digitalWrite(EA_H, HIGH);
digitalWrite(PROG_H, LOW);
delay(1);
// put the address on the bus
digitalWrite(DB0, bitRead(address, 0));
digitalWrite(DB1, bitRead(address, 1));
digitalWrite(DB2, bitRead(address, 2));
digitalWrite(DB3, bitRead(address, 3));
digitalWrite(DB4, bitRead(address, 4));
digitalWrite(DB5, bitRead(address, 5));
digitalWrite(DB6, bitRead(address, 6));
digitalWrite(DB7, bitRead(address, 7));
digitalWrite(P20, bitRead(address, 8));
digitalWrite(P21, bitRead(address, 9));
delay(1);
// latch address in 8748
digitalWrite(RESET, HIGH);
delay(1);
// switch pins to input mode
pinMode(DB0, INPUT);
pinMode(DB1, INPUT);
pinMode(DB2, INPUT);
pinMode(DB3, INPUT);
pinMode(DB4, INPUT);
pinMode(DB5, INPUT);
pinMode(DB6, INPUT);
pinMode(DB7, INPUT);
// have 8748 put data on bus
digitalWrite(TEST0, HIGH);
delay(1);
// read the data
result =
digitalRead(DB0) * 1 +
digitalRead(DB1) * 2 +
digitalRead(DB2) * 4 +
digitalRead(DB3) * 8 +
digitalRead(DB4) * 16 +
digitalRead(DB5) * 32 +
digitalRead(DB6) * 64 +
digitalRead(DB7) * 128;
// turn off read mode
digitalWrite(RESET, LOW);
digitalWrite(TEST0, LOW);
delay(1);
// put pins back into output mode
pinMode(DB0, OUTPUT);
pinMode(DB1, OUTPUT);
pinMode(DB2, OUTPUT);
pinMode(DB3, OUTPUT);
pinMode(DB4, OUTPUT);
pinMode(DB5, OUTPUT);
pinMode(DB6, OUTPUT);
pinMode(DB7, OUTPUT);
return result;
}