sketch: read write and verify ATF16V8C

Based on GALmate by Yorck
https://www.ythiee.com/2021/06/06/galmate-hardware/
This commit is contained in:
ole00 2023-03-21 20:48:47 +00:00
parent 1dc2836125
commit f48513f05b

View File

@ -17,11 +17,14 @@
Based on GALBLAST by Manfred Winterhoff Based on GALBLAST by Manfred Winterhoff
http://www.armory.com/%7Erstevew/Public/Pgmrs/GAL/_ClikMe1st.htm http://www.armory.com/%7Erstevew/Public/Pgmrs/GAL/_ClikMe1st.htm
Based on GALmate by Yorck Thiele
https://www.ythiee.com/2021/06/06/galmate-hardware/
Supports: Supports:
* National GAL16V8 * National GAL16V8
* Lattice GAL16V8A, GAL16V8B, GAL16V8D * Lattice GAL16V8A, GAL16V8B, GAL16V8D
* Lattice GAL22V10B * Lattice GAL22V10B
* Atmel ATF16V8B, ATF22V10B, ATF22V10CQZ * Atmel ATF16V8B, ATF16V8C, ATF22V10B, ATF22V10CQZ
Requires: Requires:
* afterburner PC program to upload JED fuse map, erase, read etc. * afterburner PC program to upload JED fuse map, erase, read etc.
@ -119,6 +122,9 @@ typedef enum {
LAST_GAL_TYPE //dummy LAST_GAL_TYPE //dummy
} GALTYPE; } GALTYPE;
#define BIT_NONE 0
#define BIT_ZERO 1
#define BIT_ONE 2
// config bit numbers // config bit numbers
@ -289,6 +295,7 @@ void setup() {
endOfLine = 0; endOfLine = 0;
echoEnabled = 0; echoEnabled = 0;
mapUploaded = 0; mapUploaded = 0;
lineIndex = 0;
setFlagBit(FLAG_BIT_TYPE_CHECK, 1); //do type check setFlagBit(FLAG_BIT_TYPE_CHECK, 1); //do type check
// Serial output from the GAL chip, input for Arduino // Serial output from the GAL chip, input for Arduino
@ -557,6 +564,7 @@ static void turnOff(void)
setVCC(0); // turn off VCC (if controlled) setVCC(0); // turn off VCC (if controlled)
setupGpios(INPUT); setupGpios(INPUT);
delay(100); //ensure VPP is low
} }
// GAL init sequence // GAL init sequence
@ -612,18 +620,21 @@ static void discardBits(short n)
} }
// clock a bit and send it out to GAL SDIN // clock a bit and send it out to GAL SDIN
static void sendBit(char bitValue) static void sendBit(char bitValue, char skipClkLow = 0)
{ {
setSDIN(bitValue); setSDIN(bitValue);
setSCLK(1); setSCLK(1);
setSCLK(0); if (!skipClkLow) {
setSCLK(0);
}
} }
// send n number of bits to GAL // send n number of bits to GAL
static void sendBits(short n, char bitValue) static void sendBits(short n, char bitValue)
{ {
char skipClkLow = flagBits & FLAG_BIT_ATF16V8C;
while (n-- > 0) { while (n-- > 0) {
sendBit(bitValue); sendBit(bitValue, skipClkLow && n == 0);
} }
} }
@ -659,13 +670,17 @@ static void strobe(unsigned short msec)
// 16V8, 20V8 RA0-5 = row address, strobe. // 16V8, 20V8 RA0-5 = row address, strobe.
// 22V10 RA0-5 = 0, send row address (6 bits), strobe. // 22V10 RA0-5 = 0, send row address (6 bits), strobe.
static void strobeRow(char row) // setBit: 0 - do not set bit, 1- set bit value 0, 2 - set bit value 1
static void strobeRow(char row, char setBit = BIT_NONE)
{ {
switch(gal) { switch(gal) {
case GAL16V8: case GAL16V8:
case GAL20V8: case GAL20V8:
case ATF16V8B: case ATF16V8B:
setRow(row); // set RA0-5 to row number setRow(row); // set RA0-5 to row number
if (setBit) {
sendBits(1, setBit - 1);
}
strobe(2); // pulse /STB for 2ms strobe(2); // pulse /STB for 2ms
break; break;
case GAL22V10: case GAL22V10:
@ -744,7 +759,7 @@ void parsePes(char type) {
case ATF16V8B: case ATF16V8B:
case ATF22V10B: case ATF22V10B:
case ATF22V10C: case ATF22V10C:
progtime = 10; progtime = 20;
erasetime = 100; erasetime = 100;
vpp = 48; /* 12.0V */ vpp = 48; /* 12.0V */
break; break;
@ -858,7 +873,7 @@ void printPes(char type) {
//programming info //programming info
if (UNKNOWN != type) { if (UNKNOWN != type) {
Serial.print(F(" VPP=")); Serial.print(F(" VPP=")); //without the front space chars the print causes issues (why?)
Serial.print(vpp >> 2, DEC); Serial.print(vpp >> 2, DEC);
Serial.print(F(".")); Serial.print(F("."));
Serial.print((vpp & 3) * 25, DEC); Serial.print((vpp & 3) * 25, DEC);
@ -890,9 +905,17 @@ static void readGalFuseMap(const unsigned char* cfgArray, char useDelay, char do
unsigned short row, bit; unsigned short row, bit;
unsigned short addr; unsigned short addr;
if (flagBits & FLAG_BIT_ATF16V8C) {
setPV(0);
}
// read fuse rows // read fuse rows
for(row = 0; row < galinfo[gal].rows; row++) { for(row = 0; row < galinfo[gal].rows; row++) {
strobeRow(row); strobeRow(row); //set address of the row
if (flagBits & FLAG_BIT_ATF16V8C) {
setSDIN(0);
setPV(1);
}
for(bit = 0; bit < galinfo[gal].bits; bit++) { for(bit = 0; bit < galinfo[gal].bits; bit++) {
// check the received bit is 1 and if so then set the fuse map // check the received bit is 1 and if so then set the fuse map
if (receiveBit()) { if (receiveBit()) {
@ -905,10 +928,18 @@ static void readGalFuseMap(const unsigned char* cfgArray, char useDelay, char do
if (useDelay) { if (useDelay) {
delay(useDelay); delay(useDelay);
} }
if (flagBits & FLAG_BIT_ATF16V8C) {
setPV(0);
}
} }
// read UES // read UES
strobeRow(galinfo[gal].uesrow); strobeRow(galinfo[gal].uesrow);
if (flagBits & FLAG_BIT_ATF16V8C) {
setSDIN(0);
setPV(1);
}
if (doDiscardBits) { if (doDiscardBits) {
discardBits(doDiscardBits); discardBits(doDiscardBits);
} }
@ -922,10 +953,17 @@ static void readGalFuseMap(const unsigned char* cfgArray, char useDelay, char do
if (useDelay) { if (useDelay) {
delay(useDelay); delay(useDelay);
} }
if (flagBits & FLAG_BIT_ATF16V8C) {
setPV(0);
}
// read CFG // read CFG
if (galinfo[gal].cfgmethod == CFG_STROBE_ROW) { if (galinfo[gal].cfgmethod == CFG_STROBE_ROW) {
strobeRow(galinfo[gal].cfgrow); strobeRow(galinfo[gal].cfgrow);
if (flagBits & FLAG_BIT_ATF16V8C) {
setSDIN(0);
setPV(1);
}
} else { } else {
setRow(galinfo[gal].cfgrow); setRow(galinfo[gal].cfgrow);
strobe(1); strobe(1);
@ -946,9 +984,17 @@ static unsigned short verifyGalFuseMap(const unsigned char* cfgArray, char useDe
char mapBit; // fuse bit stored in RAM char mapBit; // fuse bit stored in RAM
unsigned short errors = 0; unsigned short errors = 0;
if (flagBits & FLAG_BIT_ATF16V8C) {
setPV(0);
}
// read fuse rows // read fuse rows
for(row = 0; row < galinfo[gal].rows; row++) { for(row = 0; row < galinfo[gal].rows; row++) {
strobeRow(row); strobeRow(row);
if (flagBits & FLAG_BIT_ATF16V8C) {
setSDIN(0);
setPV(1);
}
for(bit = 0; bit < galinfo[gal].bits; bit++) { for(bit = 0; bit < galinfo[gal].bits; bit++) {
addr = galinfo[gal].rows; addr = galinfo[gal].rows;
addr *= bit; addr *= bit;
@ -966,10 +1012,17 @@ static unsigned short verifyGalFuseMap(const unsigned char* cfgArray, char useDe
if (useDelay) { if (useDelay) {
delay(useDelay); delay(useDelay);
} }
if (flagBits & FLAG_BIT_ATF16V8C) {
setPV(0);
}
} }
// read UES // read UES
strobeRow(galinfo[gal].uesrow); strobeRow(galinfo[gal].uesrow);
if (flagBits & FLAG_BIT_ATF16V8C) {
setSDIN(0);
setPV(1);
}
if (doDiscardBits) { if (doDiscardBits) {
discardBits(doDiscardBits); discardBits(doDiscardBits);
} }
@ -989,10 +1042,16 @@ static unsigned short verifyGalFuseMap(const unsigned char* cfgArray, char useDe
if (useDelay) { if (useDelay) {
delay(useDelay); delay(useDelay);
} }
if (flagBits & FLAG_BIT_ATF16V8C) {
setPV(0);
}
// read CFG // read CFG
if (galinfo[gal].cfgmethod == CFG_STROBE_ROW) { if (galinfo[gal].cfgmethod == CFG_STROBE_ROW) {
strobeRow(galinfo[gal].cfgrow); strobeRow(galinfo[gal].cfgrow);
if (flagBits & FLAG_BIT_ATF16V8C) {
setSDIN(0);
setPV(1);
}
} else { } else {
setRow(galinfo[gal].cfgrow); setRow(galinfo[gal].cfgrow);
strobe(1); strobe(1);
@ -1077,16 +1136,18 @@ static void writeGalFuseMapV8(const unsigned char* cfgArray) {
unsigned short cfgAddr = galinfo[gal].cfgbase; unsigned short cfgAddr = galinfo[gal].cfgbase;
unsigned char row, rbit; unsigned char row, rbit;
unsigned short addr; unsigned short addr;
unsigned char rbitMax = galinfo[gal].bits;
const unsigned char skipLastClk = (flagBits & FLAG_BIT_ATF16V8C) ? 1 : 0;
setPV(1); setPV(1);
// write fuse rows // write fuse rows
for (row = 0; row < galinfo[gal].rows; row++) { for (row = 0; row < galinfo[gal].rows; row++) {
setRow(row); setRow(row);
for(rbit = 0; rbit < galinfo[gal].bits; rbit++) { for(rbit = 0; rbit < rbitMax; rbit++) {
addr = galinfo[gal].rows; addr = galinfo[gal].rows;
addr *= rbit; addr *= rbit;
addr += row; addr += row;
sendBit(getFuseBit(addr)); sendBit(getFuseBit(addr), rbit == rbitMax - 1 ? skipLastClk : 0);
} }
strobe(progtime); strobe(progtime);
} }
@ -1096,14 +1157,15 @@ static void writeGalFuseMapV8(const unsigned char* cfgArray) {
for (rbit = 0; rbit < 64; rbit++) { for (rbit = 0; rbit < 64; rbit++) {
addr = galinfo[gal].uesfuse; addr = galinfo[gal].uesfuse;
addr += rbit; addr += rbit;
sendBit(getFuseBit(addr)); sendBit(getFuseBit(addr), rbit == 63 ? skipLastClk : 0);
} }
strobe(progtime); strobe(progtime);
// write CFG (all ICs use setRow) // write CFG (all ICs use setRow)
rbitMax = galinfo[gal].cfgbits;
setRow(galinfo[gal].cfgrow); setRow(galinfo[gal].cfgrow);
for(rbit = 0; rbit < galinfo[gal].cfgbits; rbit++) { for(rbit = 0; rbit < rbitMax; rbit++) {
sendBit(getFuseBit(cfgAddr + cfgArray[rbit])); sendBit(getFuseBit(cfgAddr + cfgArray[rbit]), rbit == rbitMax - 1 ? skipLastClk : 0);
} }
strobe(progtime); strobe(progtime);
setPV(0); setPV(0);