mirror of
https://github.com/ole00/afterburner.git
synced 2024-06-29 05:29:35 +00:00
commit
37c5cbd12b
|
@ -29,6 +29,8 @@ Supported GAL chips:
|
||||||
* ST Microsystems GAL16V8
|
* ST Microsystems GAL16V8
|
||||||
* Lattice GAL20V8B (no adapter needed)
|
* Lattice GAL20V8B (no adapter needed)
|
||||||
* Lattice GAL20XV10B
|
* Lattice GAL20XV10B
|
||||||
|
* Lattice GAL6001B
|
||||||
|
* Lattice GAL6002B
|
||||||
|
|
||||||
**This is a new Afterburner design with variable programming voltage control and with single ZIF socket for 20 and 24 pin GAL chips.**
|
**This is a new Afterburner design with variable programming voltage control and with single ZIF socket for 20 and 24 pin GAL chips.**
|
||||||
The PC software is backward compatible with the older Afterburner desgin/boards.
|
The PC software is backward compatible with the older Afterburner desgin/boards.
|
||||||
|
|
400
afterburner.ino
400
afterburner.ino
|
@ -147,6 +147,8 @@ typedef enum {
|
||||||
GAL20V8,
|
GAL20V8,
|
||||||
GAL20XV10,
|
GAL20XV10,
|
||||||
GAL22V10,
|
GAL22V10,
|
||||||
|
GAL6001,
|
||||||
|
GAL6002,
|
||||||
ATF16V8B,
|
ATF16V8B,
|
||||||
ATF22V10B,
|
ATF22V10B,
|
||||||
ATF22V10C,
|
ATF22V10C,
|
||||||
|
@ -163,6 +165,7 @@ typedef enum {
|
||||||
#define CFG_BASE_20 2560
|
#define CFG_BASE_20 2560
|
||||||
#define CFG_BASE_20XV 1600
|
#define CFG_BASE_20XV 1600
|
||||||
#define CFG_BASE_22 5808
|
#define CFG_BASE_22 5808
|
||||||
|
#define CFG_BASE_600 8154
|
||||||
|
|
||||||
#define CFG_STROBE_ROW 0
|
#define CFG_STROBE_ROW 0
|
||||||
#define CFG_SET_ROW 1
|
#define CFG_SET_ROW 1
|
||||||
|
@ -222,6 +225,42 @@ static const unsigned char cfgV10[]=
|
||||||
1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14,17,16,19,18,
|
1,0,3,2,5,4,7,6,9,8,11,10,13,12,15,14,17,16,19,18,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// common CFG fuse address map for cfg6001
|
||||||
|
// starting address: 8154
|
||||||
|
// total size 68
|
||||||
|
static const unsigned char cfg6001[]=
|
||||||
|
{
|
||||||
|
67, 66,
|
||||||
|
25, 29, 33, 37, 41, 45, 49, 53, 57, 61,
|
||||||
|
60, 56, 52, 48, 44, 40, 36, 32, 28, 24,
|
||||||
|
62, 63, 58, 59, 54, 55, 50, 51, 46, 47,
|
||||||
|
42, 43, 38, 39, 34, 35, 30, 31, 26, 27,
|
||||||
|
2, 5, 8, 11, 14, 17, 20, 23,
|
||||||
|
0, 3, 6, 9, 12, 15, 18, 21,
|
||||||
|
22, 19, 16, 13, 10, 7, 4, 1,
|
||||||
|
64, 65
|
||||||
|
};
|
||||||
|
|
||||||
|
// common CFG fuse address map for cfg6002
|
||||||
|
// starting address: 8154
|
||||||
|
// total size 104
|
||||||
|
static const unsigned char cfg6002[]=
|
||||||
|
{
|
||||||
|
103, 102,
|
||||||
|
25, 29, 33, 37, 41, 45, 49, 53, 57, 61,
|
||||||
|
60, 56, 52, 48, 44, 40, 36, 32, 28, 24,
|
||||||
|
62, 63, 58, 59, 54, 55, 50, 51, 46, 47,
|
||||||
|
42, 43, 38, 39, 34, 35, 30, 31, 26, 27,
|
||||||
|
101, 100, 99, 98, 97, 96, 95, 94, 93,
|
||||||
|
92, 91, 90, 89, 88, 87, 86, 85, 84,
|
||||||
|
66, 67, 68, 69, 70, 71, 72, 73, 74,
|
||||||
|
75, 76, 77, 78, 79, 80, 81, 82, 83,
|
||||||
|
2, 5, 8, 11, 14, 17, 20, 23,
|
||||||
|
0, 3, 6, 9, 12, 15, 18, 21,
|
||||||
|
22, 19, 16, 13, 10, 7, 4, 1,
|
||||||
|
64, 65
|
||||||
|
};
|
||||||
|
|
||||||
// UES user electronic signature
|
// UES user electronic signature
|
||||||
// PES programmer electronic signature (ATF = text string, others = Vendor/Vpp/timing)
|
// PES programmer electronic signature (ATF = text string, others = Vendor/Vpp/timing)
|
||||||
// cfg configuration bits for OLMCs
|
// cfg configuration bits for OLMCs
|
||||||
|
@ -259,16 +298,16 @@ galinfo[]=
|
||||||
{GAL20V8, 0x20, 0x3A, 2706, 24, 40, 64, 40, 2568, 8, 63, 62, 58, 8, 60, CFG_BASE_20 , cfgV8AB, sizeof(cfgV8AB) , CFG_STROBE_ROW},
|
{GAL20V8, 0x20, 0x3A, 2706, 24, 40, 64, 40, 2568, 8, 63, 62, 58, 8, 60, CFG_BASE_20 , cfgV8AB, sizeof(cfgV8AB) , CFG_STROBE_ROW},
|
||||||
{GAL20XV10, 0x65, 0x66, 1671, 24, 40, 40, 44, 1631, 5, 61, 60, 58, 5, 16, CFG_BASE_20XV, cfgXV10, sizeof(cfgXV10) , CFG_SET_ROW },
|
{GAL20XV10, 0x65, 0x66, 1671, 24, 40, 40, 44, 1631, 5, 61, 60, 58, 5, 16, CFG_BASE_20XV, cfgXV10, sizeof(cfgXV10) , CFG_SET_ROW },
|
||||||
{GAL22V10, 0x48, 0x49, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22 , cfgV10, sizeof(cfgV10) , CFG_SET_ROW },
|
{GAL22V10, 0x48, 0x49, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22 , cfgV10, sizeof(cfgV10) , CFG_SET_ROW },
|
||||||
|
{GAL6001, 0x40, 0x41, 8294, 24, 78, 75, 97, 8222, 9, 63, 62, 96, 8, 8, CFG_BASE_600 , cfg6001, sizeof(cfg6001) , CFG_SET_ROW },
|
||||||
|
{GAL6002, 0x44, 0x44, 8330, 24, 78, 75, 97, 8258, 9, 63, 62, 96, 8, 8, CFG_BASE_600 , cfg6002, sizeof(cfg6002) , CFG_SET_ROW },
|
||||||
{ATF16V8B, 0x00, 0x00, 2194, 20, 32, 64, 32, 2056, 8, 63, 62, 58, 8, 60, CFG_BASE_16 , cfgV8AB, sizeof(cfgV8AB) , CFG_STROBE_ROW},
|
{ATF16V8B, 0x00, 0x00, 2194, 20, 32, 64, 32, 2056, 8, 63, 62, 58, 8, 60, CFG_BASE_16 , cfgV8AB, sizeof(cfgV8AB) , CFG_STROBE_ROW},
|
||||||
{ATF22V10B, 0x00, 0x00, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22 , cfgV10, sizeof(cfgV10) , CFG_SET_ROW },
|
{ATF22V10B, 0x00, 0x00, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22 , cfgV10, sizeof(cfgV10) , CFG_SET_ROW },
|
||||||
{ATF22V10C, 0x00, 0x00, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22 , cfgV10, sizeof(cfgV10) , CFG_SET_ROW },
|
{ATF22V10C, 0x00, 0x00, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22 , cfgV10, sizeof(cfgV10) , CFG_SET_ROW },
|
||||||
};
|
};
|
||||||
|
|
||||||
// MAXFUSES calculated as the biggest required space to hold the fuse bitmap + UES bitmap + CFG bitmap
|
// MAXFUSES calculated as the biggest required space to hold the fuse bitmap
|
||||||
// MAXFUSES = ((132 * 44 bits) / 8) + uesbytes + ((20 + 1) / 8) // +1 is the power-down extra fuse
|
// MAXFUSES = GAL6002 8330 bits = 8330/8 = 1041.25 bytes rounded up to 1042 bytes
|
||||||
// 726 + 8 + 3
|
#define MAXFUSES 1042
|
||||||
#define MAXFUSES 737
|
|
||||||
|
|
||||||
|
|
||||||
GALTYPE gal __attribute__ ((section (".noinit"))); //the gal device index pointing to galinfo, value is preserved between resets
|
GALTYPE gal __attribute__ ((section (".noinit"))); //the gal device index pointing to galinfo, value is preserved between resets
|
||||||
|
|
||||||
|
@ -277,7 +316,7 @@ static uint8_t vpp = 0;
|
||||||
|
|
||||||
char echoEnabled;
|
char echoEnabled;
|
||||||
unsigned char pes[12];
|
unsigned char pes[12];
|
||||||
char line[64];
|
char line[128];
|
||||||
short lineIndex;
|
short lineIndex;
|
||||||
char endOfLine;
|
char endOfLine;
|
||||||
char mapUploaded;
|
char mapUploaded;
|
||||||
|
@ -376,8 +415,27 @@ static void setPinMux(uint8_t pm) {
|
||||||
digitalWrite(PIN_ZIF15, LOW);
|
digitalWrite(PIN_ZIF15, LOW);
|
||||||
digitalWrite(PIN_ZIF16, LOW);
|
digitalWrite(PIN_ZIF16, LOW);
|
||||||
digitalWrite(PIN_ZIF22, LOW);
|
digitalWrite(PIN_ZIF22, LOW);
|
||||||
|
digitalWrite(PIN_ZIF23, LOW);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GAL6001:
|
||||||
|
case GAL6002:
|
||||||
|
pinMode(PIN_ZIF10, pm);
|
||||||
|
pinMode(PIN_ZIF11, pm);
|
||||||
|
pinMode(PIN_ZIF13, pm);
|
||||||
|
pinMode(PIN_ZIF14, INPUT_PULLUP); //DOUT
|
||||||
|
pinMode(PIN_ZIF15, pm);
|
||||||
|
pinMode(PIN_ZIF16, pm);
|
||||||
|
// ensure ZIF10 GND pull is disabled
|
||||||
|
digitalWrite(PIN_ZIF_GND_CTRL, LOW);
|
||||||
|
|
||||||
|
//pull down unused pins
|
||||||
|
digitalWrite(PIN_ZIF3, LOW);
|
||||||
|
digitalWrite(PIN_ZIF15, LOW);
|
||||||
|
digitalWrite(PIN_ZIF16, LOW);
|
||||||
digitalWrite(PIN_ZIF22, LOW);
|
digitalWrite(PIN_ZIF22, LOW);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -785,7 +843,7 @@ static void setRow(char row)
|
||||||
if (row & 0x10) srval |= PIN_ZIF6; //RA4
|
if (row & 0x10) srval |= PIN_ZIF6; //RA4
|
||||||
if (row & 0x20) srval |= PIN_ZIF7; //RA5
|
if (row & 0x20) srval |= PIN_ZIF7; //RA5
|
||||||
} else
|
} else
|
||||||
if (b == CFG_BASE_22 || b == CFG_BASE_20XV) {
|
if (b == CFG_BASE_22 || b == CFG_BASE_20XV || b == CFG_BASE_600) {
|
||||||
if (row & 0x1) srval |= PIN_ZIF4; //RA0
|
if (row & 0x1) srval |= PIN_ZIF4; //RA0
|
||||||
if (row & 0x2) srval |= PIN_ZIF5; //RA1
|
if (row & 0x2) srval |= PIN_ZIF5; //RA1
|
||||||
if (row & 0x4) srval |= PIN_ZIF6; //RA2
|
if (row & 0x4) srval |= PIN_ZIF6; //RA2
|
||||||
|
@ -818,7 +876,7 @@ static char getSDOUT(void)
|
||||||
const unsigned short b = galinfo[gal].cfgbase;
|
const unsigned short b = galinfo[gal].cfgbase;
|
||||||
uint8_t pin = PIN_ZIF16;
|
uint8_t pin = PIN_ZIF16;
|
||||||
|
|
||||||
if (b == CFG_BASE_22 || b == CFG_BASE_20XV) {
|
if (b == CFG_BASE_22 || b == CFG_BASE_20XV || b == CFG_BASE_600) {
|
||||||
pin = PIN_ZIF14;
|
pin = PIN_ZIF14;
|
||||||
} else
|
} else
|
||||||
if (b == CFG_BASE_20) {
|
if (b == CFG_BASE_20) {
|
||||||
|
@ -973,6 +1031,16 @@ static void strobeRow(char row, char setBit = BIT_NONE)
|
||||||
setSTB(0);
|
setSTB(0);
|
||||||
setSTB(1); // pulse /STB
|
setSTB(1); // pulse /STB
|
||||||
setSDIN(0); // SDIN low
|
setSDIN(0); // SDIN low
|
||||||
|
break;
|
||||||
|
case GAL6001:
|
||||||
|
case GAL6002:
|
||||||
|
setRow(0);
|
||||||
|
sendBits(95, 0);
|
||||||
|
sendBit(1);
|
||||||
|
sendAddress(7, row);
|
||||||
|
sendBits(16, 0);
|
||||||
|
strobe(2); // pulse /STB for 2ms
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -994,6 +1062,10 @@ static void readPes(void) {
|
||||||
setPV(1); //Required for ATF16V8C
|
setPV(1); //Required for ATF16V8C
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (gal == GAL6001 || gal == GAL6002) {
|
||||||
|
discardBits(20);
|
||||||
|
}
|
||||||
|
|
||||||
for(byteIndex = 0; byteIndex < galinfo[gal].pesbytes; byteIndex++) {
|
for(byteIndex = 0; byteIndex < galinfo[gal].pesbytes; byteIndex++) {
|
||||||
unsigned char value = 0;
|
unsigned char value = 0;
|
||||||
|
|
||||||
|
@ -1021,12 +1093,32 @@ static void writePes(void) {
|
||||||
|
|
||||||
setPV(1);
|
setPV(1);
|
||||||
|
|
||||||
|
switch(gal) {
|
||||||
|
GAL6001:
|
||||||
|
GAL6002:
|
||||||
|
setRow(0);
|
||||||
|
sendBits(20, 0);
|
||||||
|
for (rbit = 0; rbit < 64; rbit++) {
|
||||||
|
b = pes[rbit >> 3];
|
||||||
|
p = b & (1 << (rbit & 0b111));
|
||||||
|
sendBit(p);
|
||||||
|
}
|
||||||
|
sendBits(11, 0);
|
||||||
|
sendBit(1);
|
||||||
|
sendAddress(7, galinfo[gal].pesrow);
|
||||||
|
sendBits(16, 0);
|
||||||
|
setSDIN(0);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
setRow(galinfo[gal].pesrow);
|
setRow(galinfo[gal].pesrow);
|
||||||
for (rbit = 0; rbit < 64; rbit++) {
|
for (rbit = 0; rbit < 64; rbit++) {
|
||||||
b = pes[rbit >> 3];
|
b = pes[rbit >> 3];
|
||||||
p = b & (1 << (rbit & 0b111));
|
p = b & (1 << (rbit & 0b111));
|
||||||
sendBit(p);
|
sendBit(p);
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
strobe(progtime);
|
strobe(progtime);
|
||||||
|
|
||||||
turnOff();
|
turnOff();
|
||||||
|
@ -1096,6 +1188,11 @@ void parsePes(char type) {
|
||||||
case GAL16V8:
|
case GAL16V8:
|
||||||
case GAL20V8:
|
case GAL20V8:
|
||||||
erasetime=100;
|
erasetime=100;
|
||||||
|
goto more;
|
||||||
|
case GAL6001:
|
||||||
|
case GAL6002:
|
||||||
|
erasetime=50;
|
||||||
|
more:
|
||||||
switch(algo) {
|
switch(algo) {
|
||||||
case 0:
|
case 0:
|
||||||
vpp = 63; // 15.75V
|
vpp = 63; // 15.75V
|
||||||
|
@ -1177,6 +1274,8 @@ void printPes(char type) {
|
||||||
case GAL20V8: Serial.print(F("GAL20V8 ")); break;
|
case GAL20V8: Serial.print(F("GAL20V8 ")); break;
|
||||||
case GAL20XV10: Serial.print(F("GAL20XV10 ")); break;
|
case GAL20XV10: Serial.print(F("GAL20XV10 ")); break;
|
||||||
case GAL22V10: Serial.print(F("GAL22V10 ")); break;
|
case GAL22V10: Serial.print(F("GAL22V10 ")); break;
|
||||||
|
case GAL6001: Serial.print(F("GAL6001 ")); break;
|
||||||
|
case GAL6002: Serial.print(F("GAL6002 ")); break;
|
||||||
case ATF16V8B: Serial.print(0 == (flagBits & FLAG_BIT_ATF16V8C) ? F("ATF16V8B "): F("ATF16V8C ")); break;
|
case ATF16V8B: Serial.print(0 == (flagBits & FLAG_BIT_ATF16V8C) ? F("ATF16V8B "): F("ATF16V8C ")); break;
|
||||||
case ATF22V10B: Serial.print(F("ATF22V10B ")); break;
|
case ATF22V10B: Serial.print(F("ATF22V10B ")); break;
|
||||||
case ATF22V10C: Serial.print(F("ATF22V10C ")); break;
|
case ATF22V10C: Serial.print(F("ATF22V10C ")); break;
|
||||||
|
@ -1210,6 +1309,12 @@ static char getFuseBit(unsigned short bitPos) {
|
||||||
return (fusemap[bitPos >> 3] & (1 << (bitPos & 7))) ? 1 : 0;
|
return (fusemap[bitPos >> 3] & (1 << (bitPos & 7))) ? 1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setFuseBitVal(unsigned short bitPos, char val) {
|
||||||
|
if (val) {
|
||||||
|
setFuseBit(bitPos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// generic fuse-map reading, fuse-map bits are stored in fusemap array
|
// generic fuse-map reading, fuse-map bits are stored in fusemap array
|
||||||
static void readGalFuseMap(const unsigned char* cfgArray, char useDelay, char doDiscardBits) {
|
static void readGalFuseMap(const unsigned char* cfgArray, char useDelay, char doDiscardBits) {
|
||||||
unsigned short cfgAddr = galinfo[gal].cfgbase;
|
unsigned short cfgAddr = galinfo[gal].cfgbase;
|
||||||
|
@ -1300,6 +1405,48 @@ static void readGalFuseMap(const unsigned char* cfgArray, char useDelay, char do
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void readGalFuseMap600(const unsigned char* cfgArray) {
|
||||||
|
unsigned short row, bit;
|
||||||
|
unsigned short addr;
|
||||||
|
|
||||||
|
for (row = 0; row < 78; row++)
|
||||||
|
{
|
||||||
|
strobeRow(row);
|
||||||
|
discardBits(20);
|
||||||
|
for (bit = 0; bit < 11; bit++)
|
||||||
|
setFuseBitVal(7296 + 78 * bit + row, receiveBit());
|
||||||
|
for (bit = 0; bit < 64; bit++)
|
||||||
|
setFuseBitVal(114 * bit + row, receiveBit());
|
||||||
|
discardBits(24);
|
||||||
|
}
|
||||||
|
for (row = 0; row < 64; row++)
|
||||||
|
{
|
||||||
|
sendBits(31, 0);
|
||||||
|
for (bit = 0; bit < 64; bit++)
|
||||||
|
sendBit(bit != row);
|
||||||
|
sendBits(24, 0);
|
||||||
|
setSDIN(0);
|
||||||
|
strobe(2);
|
||||||
|
for (bit = 0; bit < 20; bit++)
|
||||||
|
setFuseBitVal(78 + 114 * row + bit, receiveBit());
|
||||||
|
discardBits(83);
|
||||||
|
for (bit = 0; bit < 16; bit++)
|
||||||
|
setFuseBitVal(98 + 114 * row + bit, receiveBit());
|
||||||
|
}
|
||||||
|
// UES
|
||||||
|
strobeRow(galinfo[gal].uesrow);
|
||||||
|
discardBits(20);
|
||||||
|
addr = galinfo[gal].uesfuse;
|
||||||
|
for (bit = 0; bit < 72; bit++)
|
||||||
|
setFuseBitVal(addr + bit, receiveBit());
|
||||||
|
// CFG
|
||||||
|
setRow(galinfo[gal].cfgrow);
|
||||||
|
strobe(2);
|
||||||
|
addr = galinfo[gal].cfgbase;
|
||||||
|
for (bit = 0; bit < galinfo[gal].cfgbits; bit++)
|
||||||
|
setFuseBitVal(addr + cfgArray[bit], receiveBit());
|
||||||
|
}
|
||||||
|
|
||||||
// generic fuse-map verification, fuse map bits are compared against read bits
|
// generic fuse-map verification, fuse map bits are compared against read bits
|
||||||
static unsigned short verifyGalFuseMap(const unsigned char* cfgArray, char useDelay, char doDiscardBits) {
|
static unsigned short verifyGalFuseMap(const unsigned char* cfgArray, char useDelay, char doDiscardBits) {
|
||||||
unsigned short cfgAddr = galinfo[gal].cfgbase;
|
unsigned short cfgAddr = galinfo[gal].cfgbase;
|
||||||
|
@ -1420,6 +1567,107 @@ static unsigned short verifyGalFuseMap(const unsigned char* cfgArray, char useDe
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned short verifyGalFuseMap600(const unsigned char* cfgArray) {
|
||||||
|
unsigned short row, bit;
|
||||||
|
unsigned short addr;
|
||||||
|
char fuseBit; // fuse bit received from GAL
|
||||||
|
char mapBit; // fuse bit stored in RAM
|
||||||
|
unsigned short errors = 0;
|
||||||
|
|
||||||
|
for (row = 0; row < 78; row++)
|
||||||
|
{
|
||||||
|
strobeRow(row);
|
||||||
|
discardBits(20);
|
||||||
|
for (bit = 0; bit < 11; bit++) {
|
||||||
|
mapBit = getFuseBit(7296 + 78 * bit + row);
|
||||||
|
fuseBit = receiveBit();
|
||||||
|
if (mapBit != fuseBit) {
|
||||||
|
#ifdef DEBUG_VERIFY
|
||||||
|
Serial.print(F("f a="));
|
||||||
|
Serial.println(7296 + 78 * bit + row, DEC);
|
||||||
|
#endif
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (bit = 0; bit < 64; bit++) {
|
||||||
|
mapBit = getFuseBit(114 * bit + row);
|
||||||
|
fuseBit = receiveBit();
|
||||||
|
if (mapBit != fuseBit) {
|
||||||
|
#ifdef DEBUG_VERIFY
|
||||||
|
Serial.print(F("f a="));
|
||||||
|
Serial.println(114 * bit + row, DEC);
|
||||||
|
#endif
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
discardBits(24);
|
||||||
|
}
|
||||||
|
for (row = 0; row < 64; row++)
|
||||||
|
{
|
||||||
|
sendBits(31, 0);
|
||||||
|
for (bit = 0; bit < 64; bit++)
|
||||||
|
sendBit(bit != row);
|
||||||
|
sendBits(24, 0);
|
||||||
|
setSDIN(0);
|
||||||
|
strobe(2);
|
||||||
|
for (bit = 0; bit < 20; bit++) {
|
||||||
|
mapBit = getFuseBit(78 + 114 * row + bit);
|
||||||
|
fuseBit = receiveBit();
|
||||||
|
if (mapBit != fuseBit) {
|
||||||
|
#ifdef DEBUG_VERIFY
|
||||||
|
Serial.print(F("f a="));
|
||||||
|
Serial.println(78 + 114 * row + bit, DEC);
|
||||||
|
#endif
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
discardBits(83);
|
||||||
|
for (bit = 0; bit < 16; bit++) {
|
||||||
|
mapBit = getFuseBit(98 + 114 * row + bit);
|
||||||
|
fuseBit = receiveBit();
|
||||||
|
if (mapBit != fuseBit) {
|
||||||
|
#ifdef DEBUG_VERIFY
|
||||||
|
Serial.print(F("f a="));
|
||||||
|
Serial.println(98 + 114 * row + bit, DEC);
|
||||||
|
#endif
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// UES
|
||||||
|
strobeRow(galinfo[gal].uesrow);
|
||||||
|
discardBits(20);
|
||||||
|
addr = galinfo[gal].uesfuse;
|
||||||
|
for (bit = 0; bit < 72; bit++) {
|
||||||
|
mapBit = getFuseBit(addr + bit);
|
||||||
|
fuseBit = receiveBit();
|
||||||
|
if (mapBit != fuseBit) {
|
||||||
|
#ifdef DEBUG_VERIFY
|
||||||
|
Serial.print(F("f a="));
|
||||||
|
Serial.println(addr + bit, DEC);
|
||||||
|
#endif
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// CFG
|
||||||
|
setRow(galinfo[gal].cfgrow);
|
||||||
|
strobe(2);
|
||||||
|
addr = galinfo[gal].cfgbase;
|
||||||
|
for (bit = 0; bit < galinfo[gal].cfgbits; bit++) {
|
||||||
|
mapBit = getFuseBit(addr + cfgArray[bit]);
|
||||||
|
fuseBit = receiveBit();
|
||||||
|
if (mapBit != fuseBit) {
|
||||||
|
#ifdef DEBUG_VERIFY
|
||||||
|
Serial.print(F("f a="));
|
||||||
|
Serial.println(addr + cfgArray[bit], DEC);
|
||||||
|
#endif
|
||||||
|
errors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
|
||||||
// main fuse-map reading and verification function
|
// main fuse-map reading and verification function
|
||||||
// READING: reads fuse rows, UES, CFG from GAL and stores into fusemap bit array RAM.
|
// READING: reads fuse rows, UES, CFG from GAL and stores into fusemap bit array RAM.
|
||||||
// VERIFY: reads fuse rows, UES, CFG from GAL and compares with fusemap bit array in RAM.
|
// VERIFY: reads fuse rows, UES, CFG from GAL and compares with fusemap bit array in RAM.
|
||||||
|
@ -1461,6 +1709,17 @@ static void readOrVerifyGal(char verify)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GAL6001:
|
||||||
|
case GAL6002:
|
||||||
|
cfgArray = (gal == GAL6001) ? (unsigned char*) cfg6001 : (unsigned char*) cfg6002;
|
||||||
|
//read without delay, no discard
|
||||||
|
if (verify) {
|
||||||
|
i = verifyGalFuseMap600(cfgArray);
|
||||||
|
} else {
|
||||||
|
readGalFuseMap600(cfgArray);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case GAL20XV10:
|
case GAL20XV10:
|
||||||
case GAL22V10:
|
case GAL22V10:
|
||||||
case ATF22V10B:
|
case ATF22V10B:
|
||||||
|
@ -1594,6 +1853,68 @@ static void writeGalFuseMapV10(const unsigned char* cfgArray, char fillUesStart,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// fuse-map writing function for 600x GAL chips
|
||||||
|
static void writeGalFuseMap600(const unsigned char* cfgArray) {
|
||||||
|
unsigned short cfgAddr = galinfo[gal].cfgbase;
|
||||||
|
unsigned char row, bit;
|
||||||
|
unsigned short addr;
|
||||||
|
|
||||||
|
setRow(0);
|
||||||
|
for (row = 0; row < 78; row++)
|
||||||
|
{
|
||||||
|
sendBits(20, 0);
|
||||||
|
for (bit = 0; bit < 11; bit++)
|
||||||
|
sendBit(getFuseBit(7296 + 78 * bit + row));
|
||||||
|
for (bit = 0; bit < 64; bit++)
|
||||||
|
sendBit(getFuseBit(114 * bit + row));
|
||||||
|
sendBit(1);
|
||||||
|
sendAddress(7, row);
|
||||||
|
sendBits(16, 0);
|
||||||
|
setSDIN(0);
|
||||||
|
setPV(1);
|
||||||
|
strobe(progtime);
|
||||||
|
setPV(0);
|
||||||
|
}
|
||||||
|
for (row = 0; row < 64; row++)
|
||||||
|
{
|
||||||
|
for (bit = 0; bit < 20; bit++)
|
||||||
|
sendBit(getFuseBit(78 + 114 * row + bit));
|
||||||
|
sendBits(11, 0);
|
||||||
|
for (bit = 0; bit < 64; bit++)
|
||||||
|
sendBit(bit != row);
|
||||||
|
sendBits(8, 0);
|
||||||
|
for (bit = 0; bit < 16; bit++)
|
||||||
|
sendBit(getFuseBit(98 + 114 * row + bit));
|
||||||
|
setSDIN(0);
|
||||||
|
setPV(1);
|
||||||
|
strobe(progtime);
|
||||||
|
setPV(0);
|
||||||
|
}
|
||||||
|
// UES
|
||||||
|
sendBits(20, 0);
|
||||||
|
addr = galinfo[gal].uesfuse;
|
||||||
|
for (bit = 0; bit < 72; bit++)
|
||||||
|
sendBit(getFuseBit(addr + bit));
|
||||||
|
sendBits(3, 0);
|
||||||
|
sendBit(1);
|
||||||
|
sendAddress(7, galinfo[gal].uesrow);
|
||||||
|
sendBits(16, 0);
|
||||||
|
setSDIN(0);
|
||||||
|
setPV(1);
|
||||||
|
strobe(progtime);
|
||||||
|
setPV(0);
|
||||||
|
// CFG
|
||||||
|
setRow(galinfo[gal].cfgrow);
|
||||||
|
for (bit = 0; bit < galinfo[gal].cfgbits; bit++)
|
||||||
|
{
|
||||||
|
sendBit(getFuseBit(cfgAddr + cfgArray[bit]));
|
||||||
|
}
|
||||||
|
setSDIN(0);
|
||||||
|
setPV(1);
|
||||||
|
strobe(progtime);
|
||||||
|
setPV(0);
|
||||||
|
}
|
||||||
|
|
||||||
// main fuse-map writing function
|
// main fuse-map writing function
|
||||||
static void writeGal()
|
static void writeGal()
|
||||||
{
|
{
|
||||||
|
@ -1617,6 +1938,14 @@ static void writeGal()
|
||||||
writeGalFuseMapV8(cfgV8AB);
|
writeGalFuseMapV8(cfgV8AB);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case GAL6001:
|
||||||
|
writeGalFuseMap600(cfg6001);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GAL6002:
|
||||||
|
writeGalFuseMap600(cfg6002);
|
||||||
|
break;
|
||||||
|
|
||||||
case GAL20XV10:
|
case GAL20XV10:
|
||||||
case GAL22V10:
|
case GAL22V10:
|
||||||
case ATF22V10B:
|
case ATF22V10B:
|
||||||
|
@ -1803,6 +2132,8 @@ static void printGalName() {
|
||||||
case GAL20V8: Serial.println(F("GAL20V8")); break;
|
case GAL20V8: Serial.println(F("GAL20V8")); break;
|
||||||
case GAL20XV10: Serial.println(F("GAL20XV10")); break;
|
case GAL20XV10: Serial.println(F("GAL20XV10")); break;
|
||||||
case GAL22V10: Serial.println(F("GAL22V10")); break;
|
case GAL22V10: Serial.println(F("GAL22V10")); break;
|
||||||
|
case GAL6001: Serial.println(F("GAL6001")); break;
|
||||||
|
case GAL6002: Serial.println(F("GAL6002")); break;
|
||||||
case ATF16V8B:
|
case ATF16V8B:
|
||||||
if (flagBits & FLAG_BIT_ATF16V8C) {
|
if (flagBits & FLAG_BIT_ATF16V8C) {
|
||||||
Serial.println(F("ATF16V8C"));
|
Serial.println(F("ATF16V8C"));
|
||||||
|
@ -1816,6 +2147,35 @@ static void printGalName() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static unsigned printJedecBlock(unsigned short k, unsigned short bits, unsigned short rows) {
|
||||||
|
unsigned short i, j, n;
|
||||||
|
unsigned char unused;
|
||||||
|
|
||||||
|
for (i = 0; i < bits; i++)
|
||||||
|
{
|
||||||
|
n = 0;
|
||||||
|
unused = 1;
|
||||||
|
line[n++] = 'L';
|
||||||
|
n = addFormatedNumberDec4(k, n);
|
||||||
|
line[n++] = ' ';
|
||||||
|
for (j = 0; j < rows; j++, k++)
|
||||||
|
{
|
||||||
|
if (getFuseBit(k)) {
|
||||||
|
unused = 0;
|
||||||
|
line[n++] = '1';
|
||||||
|
} else {
|
||||||
|
line[n++] = '0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
line[n++] = '*';
|
||||||
|
line[n++] = 0;
|
||||||
|
if (!unused) {
|
||||||
|
Serial.println(line);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return k;
|
||||||
|
}
|
||||||
|
|
||||||
// prints the contents of fuse-map array in the form of JEDEC text file
|
// prints the contents of fuse-map array in the form of JEDEC text file
|
||||||
static void printJedec()
|
static void printJedec()
|
||||||
{
|
{
|
||||||
|
@ -1829,25 +2189,12 @@ static void printJedec()
|
||||||
Serial.print(F("*QF")); Serial.print(galinfo[gal].fuses + apdFuse, DEC);
|
Serial.print(F("*QF")); Serial.print(galinfo[gal].fuses + apdFuse, DEC);
|
||||||
Serial.println(F("*QV0*F0*G0*X0*"));
|
Serial.println(F("*QV0*F0*G0*X0*"));
|
||||||
|
|
||||||
for( i = k = 0; i < galinfo[gal].bits; i++) {
|
k = 0;
|
||||||
unused = 1;
|
if (gal == GAL6001 || gal == GAL6002) {
|
||||||
n = 0;
|
k = printJedecBlock(k, 64, 114);
|
||||||
line[n++] = 'L';
|
k = printJedecBlock(k, 11, 78);
|
||||||
n = addFormatedNumberDec4(k, n);
|
|
||||||
line[n++] = ' ';
|
|
||||||
for(j= 0; j < galinfo[gal].rows; j++, k++) {
|
|
||||||
if (getFuseBit(k)) {
|
|
||||||
unused = 0;
|
|
||||||
line[n++] = '1';
|
|
||||||
} else {
|
} else {
|
||||||
line[n++] = '0';
|
k = printJedecBlock(k, galinfo[gal].bits, galinfo[gal].rows);
|
||||||
}
|
|
||||||
}
|
|
||||||
line[n++] = '*';
|
|
||||||
line[n++] = 0;
|
|
||||||
if (!unused) {
|
|
||||||
Serial.println(line);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( k < galinfo[gal].uesfuse) {
|
if( k < galinfo[gal].uesfuse) {
|
||||||
|
@ -1946,7 +2293,6 @@ static void printJedec()
|
||||||
Serial.println(F("*"));
|
Serial.println(F("*"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// helper print function to save RAM space
|
// helper print function to save RAM space
|
||||||
static void printNoFusesError() {
|
static void printNoFusesError() {
|
||||||
Serial.println(F("ER fuse map not uploaded"));
|
Serial.println(F("ER fuse map not uploaded"));
|
||||||
|
|
|
@ -59,6 +59,8 @@ typedef enum {
|
||||||
GAL20V8,
|
GAL20V8,
|
||||||
GAL20XV10,
|
GAL20XV10,
|
||||||
GAL22V10,
|
GAL22V10,
|
||||||
|
GAL6001,
|
||||||
|
GAL6002,
|
||||||
ATF16V8B,
|
ATF16V8B,
|
||||||
ATF22V10B,
|
ATF22V10B,
|
||||||
ATF22V10C
|
ATF22V10C
|
||||||
|
@ -90,6 +92,8 @@ galinfo[] = {
|
||||||
{GAL20V8, 0x20, 0x3A, "GAL20V8", 2706, 24, 40, 64, 40, 2568, 8, 63, 59, 58, 8, 60, 82},
|
{GAL20V8, 0x20, 0x3A, "GAL20V8", 2706, 24, 40, 64, 40, 2568, 8, 63, 59, 58, 8, 60, 82},
|
||||||
{GAL20XV10, 0x65, 0x66, "GAL20XV10", 1671, 24, 40, 40, 44, 1631, 5, 61, 60, 58, 5, 16, 31},
|
{GAL20XV10, 0x65, 0x66, "GAL20XV10", 1671, 24, 40, 40, 44, 1631, 5, 61, 60, 58, 5, 16, 31},
|
||||||
{GAL22V10, 0x48, 0x49, "GAL22V10", 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, 20},
|
{GAL22V10, 0x48, 0x49, "GAL22V10", 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, 20},
|
||||||
|
{GAL6001, 0x40, 0x41, "GAL6001", 8294, 24, 78, 75, 97, 8222, 9, 63, 62, 96, 8, 8, 68},
|
||||||
|
{GAL6002, 0x44, 0x44, "GAL6002", 8330, 24, 78, 75, 97, 8258, 9, 63, 62, 96, 8, 8, 104},
|
||||||
{ATF16V8B, 0x00, 0x00, "ATF16V8B", 2194, 20, 32, 64, 32, 2056, 8, 63, 54, 58, 8, 60, 82},
|
{ATF16V8B, 0x00, 0x00, "ATF16V8B", 2194, 20, 32, 64, 32, 2056, 8, 63, 54, 58, 8, 60, 82},
|
||||||
{ATF22V10B, 0x00, 0x00, "ATF22V10B", 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, 20},
|
{ATF22V10B, 0x00, 0x00, "ATF22V10B", 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, 20},
|
||||||
{ATF22V10C, 0x00, 0x00, "ATF22V10C", 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, 20},
|
{ATF22V10C, 0x00, 0x00, "ATF22V10C", 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, 20},
|
||||||
|
@ -774,6 +778,9 @@ static char upload() {
|
||||||
//fuse map
|
//fuse map
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
fuseSet = 0;
|
fuseSet = 0;
|
||||||
|
|
||||||
|
printf("Uploading fuse map...\n");
|
||||||
|
printf("\e[?25l");
|
||||||
for (i = 0; i < totalFuses;) {
|
for (i = 0; i < totalFuses;) {
|
||||||
unsigned char f = 0;
|
unsigned char f = 0;
|
||||||
if (i % 32 == 0) {
|
if (i % 32 == 0) {
|
||||||
|
@ -802,7 +809,12 @@ static char upload() {
|
||||||
sprintf(line, "%02X", f);
|
sprintf(line, "%02X", f);
|
||||||
strcat(buf, line);
|
strcat(buf, line);
|
||||||
|
|
||||||
|
printf("%4d/%4d |", i + 1, totalFuses);
|
||||||
|
int done = ((i + 1) * 40) / totalFuses;
|
||||||
|
printf("%.*s%*s|\r", done, "########################################", 40 - done, "");
|
||||||
}
|
}
|
||||||
|
printf("%4d/%4d |########################################|\n", totalFuses, totalFuses);
|
||||||
|
printf("\e[?25h");
|
||||||
|
|
||||||
// send last unfinished fuse line
|
// send last unfinished fuse line
|
||||||
if (i % 32 && fuseSet) {
|
if (i % 32 && fuseSet) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user