arduino_eprom27_programmer/sketch/sketch.ino

380 lines
9.4 KiB
C++

#define TRUE 1
#define FALSE 0
/* 74HC595 control (address lines) */
#define shiftLatchPin A1
#define shiftClockPin A2
#define shiftDataPin A0
#define addressPinA10 13
/* Data pins */
#define dataB0 2
#define dataB1 3
#define dataB2 4
#define dataB3 5
#define dataB4 6
#define dataB5 7
#define dataB6 8
#define dataB7 10
/* Chip control */
#define chipEnable A3
#define outputEnable A4
#define powerEnable A5 // For 27C16 and 27C32
#define readVoltageEnable 13 // For 27C16
#define programVoltageEnableC16 9 // For 27C16
#define programVoltageEnableC32 12 // For 27C32 and 27C512
#define programVoltageEnableOther 11 // For other
/* Voltage control (for programming chips) */
#define voltageControl A6
#define rTop 10000.0
#define rBottom 1500.0
//#define MESSAGES
typedef enum chipType {
NONE = 0,
C16 = 1,
C32 = 2,
C64 = 3,
C128 = 4,
C256 = 5,
C512 = 6
} Chip;
typedef enum mode {
WAIT,
READ,
WRITE,
VOLTAGE
} Modes;
void write_mode (void);
void read_mode (void);
void set_address (uint16_t address);
uint8_t get_data (void);
void set_data (uint8_t data);
uint8_t read_byte (uint16_t address);
void write_byte (uint16_t address, uint8_t data);
float get_voltage (void);
void program_voltage_set (bool state);
uint16_t gen_address (uint16_t address);
void select_chip (chipType new_chip);
chipType chip = NONE;
Modes mode = WAIT;
uint8_t log_enable = FALSE;
uint16_t start_address = 0x0000;
uint16_t end_address = 0x0000;
#define BUF_LEN 16
uint8_t buf[BUF_LEN];
void message(const char* mes){
if (log_enable)
Serial.println(mes);
}
void setup() {
// 74HC595 (*2)
pinMode(shiftLatchPin, OUTPUT);
pinMode(shiftClockPin, OUTPUT);
pinMode(shiftDataPin, OUTPUT);
pinMode(addressPinA10, OUTPUT);
// Chip control
pinMode(chipEnable, OUTPUT);
pinMode(outputEnable, OUTPUT);
pinMode(powerEnable, OUTPUT);
pinMode(readVoltageEnable, OUTPUT);
pinMode(programVoltageEnableC16, OUTPUT);
pinMode(programVoltageEnableC32, OUTPUT);
pinMode(programVoltageEnableOther, OUTPUT);
digitalWrite(outputEnable, HIGH);
digitalWrite(powerEnable, HIGH);
digitalWrite(readVoltageEnable, HIGH);
digitalWrite(programVoltageEnableC16, LOW);
digitalWrite(programVoltageEnableC32, LOW);
digitalWrite(programVoltageEnableOther, LOW);
digitalWrite(chipEnable, LOW);
// Data pins
read_mode();
Serial.begin(115200);
Serial.println("Arduino 27 Series programmer");
}
void loop() {
switch (mode) {
case READ:
if (chip == NONE) {
mode = WAIT;
break;
}
message("Read mode.");
read_mode();
if (chip == C16) digitalWrite(readVoltageEnable, LOW);
digitalWrite(chipEnable, LOW);
digitalWrite(outputEnable, LOW);
for (uint16_t i = start_address; i <= end_address; i++) {
uint8_t data = read_byte(i);
Serial.write(&data, sizeof(data));
if (i == end_address) break; // Защита от переполнения uint16
}
digitalWrite(outputEnable, HIGH);
digitalWrite(chipEnable, HIGH);
if (chip == C16) digitalWrite(readVoltageEnable, HIGH);
mode = WAIT;
break;
case WRITE:
if (chip == NONE) {
mode = WAIT;
break;
}
message("Write mode");
/*for (int i = start_address; i <= end_address; i++) {
Serial.println(i, HEX);
write_byte(i, 0x89);
}*/
for (uint16_t i = start_address; i <= end_address; i += BUF_LEN) {
Serial.print("Write block ");
Serial.println(i);
uint8_t count = Serial.readBytes((char*)buf, BUF_LEN);
if (count != BUF_LEN) {
Serial.print("Error on block");
Serial.println(i);
Serial.print("Received ");
Serial.println(count);
break;
}
for (uint16_t j = 0; j < BUF_LEN; j++) {
// Write byte
write_mode();
program_voltage_set(true);
write_byte((i + j), buf[j]);
program_voltage_set(false);
// Verify byte
read_mode();
if (chip == C16) digitalWrite(readVoltageEnable, LOW);
digitalWrite(chipEnable, LOW);
digitalWrite(outputEnable, LOW);
uint8_t verify = get_data();
digitalWrite(outputEnable, HIGH);
digitalWrite(chipEnable, HIGH);
if (chip == C16) digitalWrite(readVoltageEnable, HIGH);
if (buf[j] != virify){
Serial.print("Error on address ");
Serial.println(i + j);
mode = WAIT;
}
}
Serial.print("Complete block ");
Serial.println(i);
if (i == end_address) break;
}
message("Write success.");
mode = WAIT;
break;
case VOLTAGE:
Serial.print("Programming voltage: ");
Serial.println(get_voltage(), 1);
mode = WAIT;
break;
default:
if (chip == NONE) message("Chip not selected!");
message("Wait commands...");
while (Serial.available()) Serial.read();
do {} while (Serial.available() == 0);
char incomingByte = Serial.read();
while (Serial.available()) Serial.read();
switch (incomingByte) {
case 'r': mode = READ; break;
case 'w': mode = WRITE; break;
case 'v': mode = VOLTAGE; break;
case 'a': select_chip(C16); break;
case 'b': select_chip(C32); break;
case 'c': select_chip(C64); break;
case 'd': select_chip(C128); break;
case 'e': select_chip(C256); break;
case 'f': select_chip(C512); break;
}
}
}
void select_chip (chipType new_chip) {
digitalWrite(powerEnable, HIGH);
switch (new_chip) {
case C16:
digitalWrite(powerEnable, LOW);
chip = new_chip;
end_address = 0x07ff;
message("Select 27C16 chip.");
break;
case C32:
digitalWrite(powerEnable, LOW);
chip = new_chip;
end_address = 0x0fff;
message("Select 27C32 chip.");
break;
case C64:
chip = new_chip;
end_address = 0x1fff;
message("Select 27C64 chip.");
break;
case C128:
chip = new_chip;
end_address = 0x3fff;
message("Select 27C128 chip.");
break;
case C256:
chip = new_chip;
end_address = 0x7fff;
message("Select 27C256 chip.");
break;
case C512:
chip = C512;
end_address = 0xffff;
message("Select 27C512 chip.");
break;
default:
chip = NONE;
end_address = 0x0000;
message("Chip not selected!");
}
}
void program_voltage_set (bool state) {
switch (chip) {
case C16:
digitalWrite(programVoltageEnableC16, state);
break;
case C32:
case C512:
digitalWrite(programVoltageEnableC32, state);
break;
case C64:
case C128:
case C256:
default:
digitalWrite(programVoltageEnableOther, state);
}
}
void write_mode (void) {
pinMode(dataB0, OUTPUT);
pinMode(dataB1, OUTPUT);
pinMode(dataB2, OUTPUT);
pinMode(dataB3, OUTPUT);
pinMode(dataB4, OUTPUT);
pinMode(dataB5, OUTPUT);
pinMode(dataB6, OUTPUT);
pinMode(dataB7, OUTPUT);
}
void read_mode (void) {
pinMode(dataB0, INPUT_PULLUP);
pinMode(dataB1, INPUT_PULLUP);
pinMode(dataB2, INPUT_PULLUP);
pinMode(dataB3, INPUT_PULLUP);
pinMode(dataB4, INPUT_PULLUP);
pinMode(dataB5, INPUT_PULLUP);
pinMode(dataB6, INPUT_PULLUP);
pinMode(dataB7, INPUT_PULLUP);
}
uint16_t gen_address (uint16_t address) {
byte high = highByte(address);
byte low = lowByte(address);
switch (chip) {
case C16:
break;
if (mode == READ) {
high |= 1 << 3; // A11 (C32+) is Vpp for C16 (5v for read)
}
break;
case C64:
case C128:
if (mode == READ) {
high |= 1 << 6; // A14 (C256 and C512) is ~PGM for C64 and C128
}
break;
case C32:
case C256:
case C512:
default:
break;
}
return (high << 8) | low;
}
void set_address (uint16_t address) {
address = gen_address(address);
digitalWrite(shiftLatchPin, LOW);
byte registerTwo = highByte(address);
byte registerOne = lowByte(address);
shiftOut(shiftDataPin, shiftClockPin, MSBFIRST, registerTwo);
shiftOut(shiftDataPin, shiftClockPin, MSBFIRST, registerOne);
digitalWrite(shiftLatchPin, HIGH);
}
uint8_t get_data (void) {
uint8_t data = 0;
data |= digitalRead(dataB0) << 0;
data |= digitalRead(dataB1) << 1;
data |= digitalRead(dataB2) << 2;
data |= digitalRead(dataB3) << 3;
data |= digitalRead(dataB4) << 4;
data |= digitalRead(dataB5) << 5;
data |= digitalRead(dataB6) << 6;
data |= digitalRead(dataB7) << 7;
return data;
}
void set_data (uint8_t data) {
digitalWrite(dataB0, (data & (1 << 0)));
digitalWrite(dataB1, (data & (1 << 1)));
digitalWrite(dataB2, (data & (1 << 2)));
digitalWrite(dataB3, (data & (1 << 3)));
digitalWrite(dataB4, (data & (1 << 4)));
digitalWrite(dataB5, (data & (1 << 5)));
digitalWrite(dataB6, (data & (1 << 6)));
digitalWrite(dataB7, (data & (1 << 7)));
}
uint8_t read_byte (uint16_t address) {
set_address(address);
return get_data();
}
void write_byte (uint16_t address, uint8_t data) {
set_address(address);
set_data(data);
switch (chip) {
case C16:
digitalWrite(chipEnable, HIGH);
delay(15);
digitalWrite(chipEnable, LOW);
break;
case C32:
case C64:
case C128:
case C256:
case C512:
default:
digitalWrite(chipEnable, LOW);
delayMicroseconds(110);
digitalWrite(chipEnable, HIGH);
break;
}
}
float get_voltage (void) {
float vADC = (analogRead(voltageControl) / 1024.) * 5.;
float current = vADC / rBottom;
return (current * (rTop + rBottom));
}