// PROM Programmer:
// This code programs the LOW nibble of "ROM" data to the 74S571 PROM.
// The "ROM" data is in the source code.
// A factory PROM is all LOWs and the Programmer writes HIGHs on bit at a time.
// The programmer has pull up resistors on VPP and /CS for safety.
// After the PROM has been programmed the LED will blink slowly if successful (1s on/1s off).
// If if unsuccessful the the LED will blink quickly (0.1s on/0.1s off).
//
// Programmer connections:
// D0 <-> TX
// D1 <-> RX
// D2 <-> PROM A0
// D3 <-> PROM A1
// D4 <-> PROM A2
// D5 <-> PROM A3
// D6 <-> PROM A4
// D7 <-> PROM A5
// D8 <-> PROM D0
// D9 <-> PROM D1
// D10 <-> PROM D2
// D11 <-> PROM D3
// D12 <-> PROM A6
// D13 <-> D13 (LED)
// A0 <-> PROM Sense D0
// A1 <-> PROM Sense D1
// A2 <-> PROM Sense D2
// A3 <-> PROM Sense D3
// A4 <-> PROM VPP (MUST STAY HIGH FOR 5V)
// A5 <-> PROM /CS (ACTIVE LOW)
// A6 <-> A6 (NANO ONLY - ANALOG READ ONLY)
// A7 <-> A7 (NANO ONLY - ANALOG READ ONLY)
// Set bytes (nibbles) to read
const int bytes=128;
#include <avr/pgmspace.h>
// Here is the "ROM" data (only the low nibble is used)
const byte PROGMEM ROM[bytes] = {
0XDD, 0XFF, 0X8D, 0X9D, 0XDD, 0X00, 0X7D, 0X8D,
0X9D, 0XA7, 0XB8, 0XC9, 0X2A, 0X3B, 0X4C, 0X0A,
0X1B, 0X00, 0X1C, 0X00, 0XDD, 0XFF, 0X1D, 0XDD,
0X0F, 0XED, 0XDD, 0X0A, 0X5D, 0XDD, 0XF9, 0X0D,
0XDD, 0XFF, 0X1D, 0X1D, 0X00, 0XDD, 0X20, 0XED,
0X05, 0X50, 0X00, 0XDD, 0X1D, 0XED, 0X07, 0X12,
0X11, 0X51, 0X02, 0X11, 0X05, 0X71, 0XA7, 0X08,
0X13, 0X11, 0X51, 0X03, 0X11, 0X05, 0X81, 0XB8,
0X09, 0X14, 0X11, 0X51, 0X04, 0X11, 0X05, 0X91,
0XC9, 0XDD, 0X09, 0XFD, 0X21, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00,
0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00, 0X00
};
void ReadPROM(byte bytes)
{
byte Data;
byte Addr;
// Make sure controls are set for read
PORTC|= B00010000; // Set VPP HIGH
PORTC&= B11010000; // Set /CS LOW and D0-3 LOW
for (Addr=0;Addr<bytes;Addr++) {
// Set Address
PORTD=(PORTD&B00000011)|(Addr<<2);
PORTB=(PORTB&B11101111)|((Addr>>2)&B00010000);
delayMicroseconds(5); // Wait for data to settle (>3 us)
// Read the PROM
Data=PINC&B00001111;
if (Addr%16==0) {
Serial.println();
if (Addr==0) {
Serial.print("00:");
} else {
Serial.print(Addr,HEX);
Serial.print(":");
}
}
Serial.print(" ");
Serial.print(Data,HEX);
delay(5); // enough time for 4 characters per loop
}
// Make sure controls are set to off
PORTC|= B00110000; // Set VPP HIGH (5V) and /CS HIGH (deselected)
}
void setup() {
// INITIALISE PORTS
// PortC XX/VSSSS
// XXCP3210
// XXSP
PORTC|= B00110000; // Set VPP and /CS HIGH
DDRC &= B11110000; // Set S0-3 as inputs
DDRC |= B00110000; // Set VPP and /CS as outputs
// Bit 76543210
// PortD AAAAAART
// 543210XX
DDRD |= B11111100; // Set A0-5 as outputs
PORTD&= B00000011; // Set A0-5 LOW
// PortB XXLADDDD
// XXE63210
// XXD
DDRB |= B00111111; // Set LED, A6 and D3-0 as outputs
PORTB&= B11000000; // Set LED, A6 and D3-0 LOW
// Set Serial
Serial.begin(9600);
}
int Delay=1000;
void loop() {
byte CPort;
byte Data;
byte Addr;
byte Nibble=0;
byte BitNo;
byte Pass;
byte Verify;
char Ans;
delay(100);
Serial.println("Welcome to the 74S571 PROM Programmer.");
delay(100);
Serial.println("Please power up the PROM Programmer now.");
delay(100); // Wait for output buffer to clear
Serial.print("First read the PROM (y/n)?"); // Message
while (Serial.available()) Serial.read(); // Flush input buffer
while (!Serial.available()); // Wait for response
Ans=Serial.read(); // Get answer
if ((Ans=='y')||(Ans=='Y')) {
// Read PROM
ReadPROM(bytes);
delay(100);
Serial.println();
Serial.println("PROM read done.");
} else {
delay(100);
Serial.println();
Serial.println("PROM read aborted.");
}
// PROM Programmer
delay(100);
Serial.println();
Serial.print("Ready to program the PROM (y/n)?");
while (Serial.available()) Serial.read();
while (!Serial.available());
Ans=Serial.read();
if ((Ans=='y')||(Ans=='Y')) {
delay(100);
Serial.println();
Serial.print("Write high or low nimble of ROM data (h/l)?");
while (Serial.available()) Serial.read();
while (!Serial.available());
Ans=Serial.read();
if ((Ans=='H')||(Ans=='h')) Nibble=4;
// Make sure controls are set off (VPP and /CS HIGH)
PORTC|=B00110000;
for (Addr=0;Addr<bytes;Addr++) {
// Read the data to be programmed
Data=pgm_read_byte(ROM+Addr);
PORTD=(PORTD&B00000011)|(Addr<<2);
PORTB=(PORTB&B11101111)|((Addr>>2)&B00010000);
delayMicroseconds(1);
for (BitNo=Nibble;BitNo<Nibble+4;BitNo++) {
if (((Data>>BitNo)&B00000001)==1) {
// Set Data bit
PORTB=(PORTB&B11110000)|(B00000001<<(BitNo-Nibble));
delayMicroseconds(1);
// Write bit cycle
for (Verify=0;Verify<2;Verify++) {
// Write the bit
for (Pass=0;Pass<10;Pass++) {
PORTC&=B11101111; // Bring up VPP to 10.5v (active low)
delayMicroseconds(1);
PORTC&=B11011111; // Select chip (active low)
delayMicroseconds(10);
PORTC|=B00100000; // Unselect chip
PORTC|=B00010000; // Bring down VPP to 5v
delayMicroseconds(33); // Maximum duty cycle is 25%
}
// Verify
PORTB&=B11110000; // Set D0-3 LOW (off)
PORTC&=B11011111; // Make /CS low (select)
delayMicroseconds(5); // Wait for data to settle
// Read the PROM
CPort=PINC;
if ((Data&(B00000001<<BitNo+Nibble))==(CPort&(B00000001<<BitNo+Nibble))) break;
}
// Post verify bit write
PORTB=(PORTB&B11110000)|(B00000001<<(BitNo-Nibble));
delayMicroseconds(1);
for (Pass=0;Pass<5;Pass++) {
PORTC&=B11101111; // Bring up VPP to 10.5v (active low)
delayMicroseconds(1);
PORTC&=B11011111; // Select chip (active low)
delayMicroseconds(10);
PORTC|=B00100000; // Unselect chip
PORTC|=B00010000; // Bring down VPP to 5v
delayMicroseconds(33); // Maximum duty cycle is 25%
}
}
}
}
// Check Read PROM
delay(100);
Serial.println();
Serial.print("Post programmed PROM read");
ReadPROM(bytes);
// Make sure controls are set to off
PORTC|= B00110000; // VPP HIGH (5V) and /CS HIGH (deselected)
delay(100);
Serial.println();
Serial.println("PROM write done.");
} else {
delay(100);
Serial.println();
Serial.print("PROM write aborted.");
}
delay(100);
Serial.println();
Serial.println("PROM Programmer done.");
while(true) {
digitalWrite(13,HIGH);
delay(Delay);
digitalWrite(13,LOW);
delay(Delay);
}
}