mirror of
https://github.com/ole00/afterburner.git
synced 2024-11-22 21:32:09 +00:00
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:
parent
1dc2836125
commit
f48513f05b
@ -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);
|
||||||
|
Loading…
Reference in New Issue
Block a user