diff --git a/README.md b/README.md index 868de23..9332493 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ Supported GAL chips: * Lattice GAL22V10B, GAL22V10D * National GAL16V8 * Lattice GAL20V8B (no adapter needed) +* Lattice GAL20XV10B **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. diff --git a/afterburner.ino b/afterburner.ino index ac93950..1d8d6f9 100644 --- a/afterburner.ino +++ b/afterburner.ino @@ -145,6 +145,7 @@ typedef enum { UNKNOWN, GAL16V8, GAL20V8, + GAL20XV10, GAL22V10, ATF16V8B, ATF22V10B, @@ -158,9 +159,10 @@ typedef enum { // config bit numbers -#define CFG_BASE_16 2048 -#define CFG_BASE_20 2560 -#define CFG_BASE_22 5808 +#define CFG_BASE_16 2048 +#define CFG_BASE_20 2560 +#define CFG_BASE_20XV 1600 +#define CFG_BASE_22 5808 #define CFG_STROBE_ROW 0 #define CFG_SET_ROW 1 @@ -196,6 +198,22 @@ static const unsigned char cfgV8AB[]= 4,5,6,7, }; +// common CFG fuse address map for cfg20XV10 +// starting address: 1600 +// total size 31 +static const unsigned char cfgXV10[]= +{ + 30, + 28, 29, + 20, 21, 22, + 10, 11, 12, 13, 14, + 0, 1, 2, 3, 4, + 27, 26, + 23, 24, 25, + 19, 18, 17, 16, 15, + 9, 8, 7, 6, 5 +}; + // common CFG fuse address map for cfg22V10 // starting address: 5808 // total size 20 @@ -204,7 +222,6 @@ 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, }; - // UES user electronic signature // PES programmer electronic signature (ATF = text string, others = Vendor/Vpp/timing) // cfg configuration bits for OLMCs @@ -238,12 +255,13 @@ galinfo[]= // +-- type + id0 + id1 | | +rows | | +uesfuse | +eraseallrow +cfgrow | | + cfgbits +cfgmethod // | | | | | | | | | | | | | | | | | | | {UNKNOWN, 0x00, 0x00, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, NULL, 0 , 0}, - {GAL16V8, 0x00, 0x1A, 2194, 20, 32, 64, 32, 2056, 8, 63, 62, 58, 8, 60, CFG_BASE_16, 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}, - {GAL22V10, 0x48, 0x49, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22, cfgV10, sizeof(cfgV10) , 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}, - {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 }, + {GAL16V8, 0x00, 0x1A, 2194, 20, 32, 64, 32, 2056, 8, 63, 62, 58, 8, 60, CFG_BASE_16 , 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 }, + {GAL22V10, 0x48, 0x49, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22 , cfgV10, sizeof(cfgV10) , 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}, + {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 }, }; // MAXFUSES calculated as the biggest required space to hold the fuse bitmap + UES bitmap + CFG bitmap @@ -341,6 +359,7 @@ static void setPinMux(uint8_t pm) { break; + case GAL20XV10: case GAL22V10: case ATF22V10B: case ATF22V10C: @@ -720,7 +739,7 @@ static void setPV(char on) { const unsigned short b = galinfo[gal].cfgbase; uint8_t pin = PIN_ZIF23; - if (b == CFG_BASE_22) { + if (b == CFG_BASE_22 || b == CFG_BASE_20XV) { pin = PIN_ZIF3; } else if (b == CFG_BASE_20) { @@ -766,7 +785,7 @@ static void setRow(char row) if (row & 0x10) srval |= PIN_ZIF6; //RA4 if (row & 0x20) srval |= PIN_ZIF7; //RA5 } else - if (b == CFG_BASE_22) { + if (b == CFG_BASE_22 || b == CFG_BASE_20XV) { if (row & 0x1) srval |= PIN_ZIF4; //RA0 if (row & 0x2) srval |= PIN_ZIF5; //RA1 if (row & 0x4) srval |= PIN_ZIF6; //RA2 @@ -799,7 +818,7 @@ static char getSDOUT(void) const unsigned short b = galinfo[gal].cfgbase; uint8_t pin = PIN_ZIF16; - if (b == CFG_BASE_22) { + if (b == CFG_BASE_22 || b == CFG_BASE_20XV) { pin = PIN_ZIF14; } else if (b == CFG_BASE_20) { @@ -945,6 +964,7 @@ static void strobeRow(char row, char setBit = BIT_NONE) } strobe(2); // pulse /STB for 2ms break; + case GAL20XV10: case GAL22V10: case ATF22V10B: case ATF22V10C: @@ -1155,6 +1175,7 @@ void printPes(char type) { switch (type) { case GAL16V8: Serial.print(F("GAL16V8 ")); break; case GAL20V8: Serial.print(F("GAL20V8 ")); break; + case GAL20XV10: Serial.print(F("GAL20XV10 ")); break; case GAL22V10: Serial.print(F("GAL22V10 ")); break; case ATF16V8B: Serial.print(0 == (flagBits & FLAG_BIT_ATF16V8C) ? F("ATF16V8B "): F("ATF16V8C ")); break; case ATF22V10B: Serial.print(F("ATF22V10B ")); break; @@ -1199,7 +1220,6 @@ static void readGalFuseMap(const unsigned char* cfgArray, char useDelay, char do setPV(0); } - // read fuse rows for(row = 0; row < galinfo[gal].rows; row++) { strobeRow(row); //set address of the row if (flagBits & FLAG_BIT_ATF16V8C) { @@ -1233,7 +1253,7 @@ static void readGalFuseMap(const unsigned char* cfgArray, char useDelay, char do if (doDiscardBits) { discardBits(doDiscardBits); } - for(bit = 0; bit < 64; bit++) { + for(bit = 0; bit < galinfo[gal].uesbytes * 8; bit++) { if (receiveBit()) { addr = galinfo[gal].uesfuse; addr += bit; @@ -1441,14 +1461,21 @@ static void readOrVerifyGal(char verify) } break; + case GAL20XV10: case GAL22V10: case ATF22V10B: case ATF22V10C: //read with delay 1 ms, discard 68 cfg bits on ATFxx - if (verify) { - i = verifyGalFuseMap(cfgV10, 1, (gal == GAL22V10) ? 0 : 68); + bool isGAL = (gal == GAL20XV10 || gal == GAL22V10); + if (gal == GAL20XV10) { + cfgArray = (unsigned char*) cfgXV10; } else { - readGalFuseMap(cfgV10, 1, (gal == GAL22V10) ? 0 : 68); + cfgArray = (unsigned char*) cfgV10; + } + if (verify) { + i = verifyGalFuseMap(cfgArray, 1, isGAL ? 0 : 68); + } else { + readGalFuseMap(cfgArray, 1, isGAL ? 0 : 68); } break; } @@ -1532,7 +1559,7 @@ static void writeGalFuseMapV10(const unsigned char* cfgArray, char fillUesStart, if (fillUesStart) { sendBits(68, 1); } - for (bit = 0; bit < 64; bit++) { + for (bit = 0; bit < galinfo[gal].uesbytes * 8; bit++) { addr = galinfo[gal].uesfuse; addr += bit; sendBit(getFuseBit(addr)); @@ -1590,10 +1617,17 @@ static void writeGal() writeGalFuseMapV8(cfgV8AB); break; + case GAL20XV10: case GAL22V10: case ATF22V10B: case ATF22V10C: - writeGalFuseMapV10(cfgV10, (gal == GAL22V10) ? 0 : 1, (gal == ATF22V10C) ? 1 : 0); + bool isGAL = (gal == GAL22V10); + if (gal == GAL20XV10) { + cfgArray = (unsigned char*) cfgXV10; + } else { + cfgArray = (unsigned char*) cfgV10; + } + writeGalFuseMapV10(cfgArray, isGAL ? 0 : 1, (gal == ATF22V10C) ? 1 : 0); break; } turnOff(); @@ -1765,6 +1799,7 @@ static void printGalName() { switch (gal) { case GAL16V8: Serial.println(F("GAL16V8")); break; case GAL20V8: Serial.println(F("GAL20V8")); break; + case GAL20XV10: Serial.println(F("GAL20XV10")); break; case GAL22V10: Serial.println(F("GAL22V10")); break; case ATF16V8B: if (flagBits & FLAG_BIT_ATF16V8C) { @@ -1861,7 +1896,7 @@ static void printJedec() Serial.print(F("L")); printFormatedNumberDec4(k); Serial.print(F(" ")); - + for(j = 0; j < 8 * galinfo[gal].uesbytes; j++) { if (getFuseBit(k++)) { Serial.print(F("1")); diff --git a/src_pc/afterburner.c b/src_pc/afterburner.c index 4201e29..051237e 100644 --- a/src_pc/afterburner.c +++ b/src_pc/afterburner.c @@ -57,6 +57,7 @@ typedef enum { UNKNOWN, GAL16V8, GAL20V8, + GAL20XV10, GAL22V10, ATF16V8B, ATF22V10B, @@ -87,6 +88,7 @@ galinfo[] = { {UNKNOWN, 0x00, 0x00, "unknown", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0}, {GAL16V8, 0x00, 0x1A, "GAL16V8", 2194, 20, 32, 64, 32, 2056, 8, 63, 54, 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}, {GAL22V10, 0x48, 0x49, "GAL22V10", 5892, 24, 44, 132, 44, 5828, 8, 61, 60, 58, 10, 16, 20}, {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}, @@ -127,6 +129,14 @@ char flagEraseAll = 0; static int waitForSerialPrompt(char* buf, int bufSize, int maxDelay); static char sendGenericCommand(const char* command, const char* errorText, int maxDelay, char printResult); +static void printGalTypes() { + for (int i = 1; i < sizeof(galinfo) / sizeof(galinfo[0]); i++) { + if (i > 1) { + printf(" "); + } + printf("%s", galinfo[i].name); + } +} static void printHelp() { printf("Afterburner " VERSION " a GAL programming tool for Arduino based programmer\n"); @@ -144,7 +154,9 @@ static void printHelp() { printf(" m : measure variable VPP on new board designs. Ensure the GAL is NOT inserted.\n"); printf("options:\n"); printf(" -v : verbose mode\n"); - printf(" -t : the GAL type. use GAL16V8 GAL20V8 GAL22V10 ATF16V8B ATF22V10B ATF22V10C\n"); + printf(" -t : the GAL type. use "); + printGalTypes(); + printf("\n"); printf(" -f : JEDEC fuse map file\n"); printf(" -d : name of the serial device. Default is: %s\n", DEFAULT_SERIAL_DEVICE_NAME); printf(" serial params are: 38400, 8N1\n"); @@ -169,7 +181,6 @@ static void printHelp() { printf(" Atmel ATF16V8B, AFT16V8C, ATF22V10C: 10V \n"); } - static int8_t verifyArgs(char* type) { if (!opRead && !opWrite && !opErase && !opInfo && !opVerify && !opTestVPP && !opCalibrateVPP && !opMeasureVPP && !opWritePes) { printHelp(); @@ -196,27 +207,17 @@ static int8_t verifyArgs(char* type) { printf("Error: missing GAL type. Use -t to specify.\n"); return -1; } else if (0 != type) { - if (strcmp("GAL16V8", type) == 0) { - gal = GAL16V8; - } - if (strcmp("GAL20V8", type) == 0) { - gal = GAL20V8; - } - if (strcmp("GAL22V10", type) == 0) { - gal = GAL22V10; - } - if (strcmp("ATF16V8B", type) == 0) { - gal = ATF16V8B; - } - if (strcmp("ATF22V10B", type) == 0) { - gal = ATF22V10B; - } - if (strcmp("ATF22V10C", type) == 0) { - gal = ATF22V10C; + for (int i = 1; i < sizeof(galinfo) / sizeof(galinfo[0]); i++) { + if (strcmp(type, galinfo[i].name) == 0) { + gal = galinfo[i].type; + break; + } } if (UNKNOWN == gal) { - printf("Error: unknow GAL type. Types: GAL16V8 GAL20V8 GAL22V10 ATF16V8B ATF22V10B ATF22V10C\n"); + printf("Error: unknown GAL type. Types: "); + printGalTypes(); + printf("\n"); return -1; } }