mirror of
https://github.com/ole00/afterburner.git
synced 2024-11-26 03:49:18 +00:00
Initial support for ATF750C based on nospam2000 fork
Setup and PES reading works. Based on fork: https://github.com/nospam2000/afterburner By Michael D. - nospam2000
This commit is contained in:
parent
bd19c7c776
commit
b216b16c9a
201
afterburner.ino
201
afterburner.ino
@ -144,6 +144,7 @@
|
||||
#define SGSTHOMSON 0x20
|
||||
#define ATMEL16 'V'
|
||||
#define ATMEL22 '1'
|
||||
#define ATMEL750 'C'
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
@ -161,6 +162,7 @@ typedef enum {
|
||||
ATF20V8B,
|
||||
ATF22V10B,
|
||||
ATF22V10C,
|
||||
ATF750C,
|
||||
LAST_GAL_TYPE //dummy
|
||||
} GALTYPE;
|
||||
|
||||
@ -188,13 +190,24 @@ typedef enum {
|
||||
#define CFG_BASE_26CV 6344
|
||||
#define CFG_BASE_26V 7800
|
||||
#define CFG_BASE_600 8154
|
||||
#define CFG_BASE_750 14364
|
||||
|
||||
#define CFG_STROBE_ROW 0
|
||||
#define CFG_SET_ROW 1
|
||||
#define CFG_STROBE_ROW2 3
|
||||
|
||||
// Atmel power-down row
|
||||
#define CFG_ROW_APD 59
|
||||
|
||||
|
||||
// Naive detection of the board's RAM size - for support of big Fuse map:
|
||||
// PIN_A11 - present on MEGA (8kB) or Leonardo (2.5kB SRAM)
|
||||
// _RENESAS_RA_ - Uno R4 (32kB)
|
||||
#if defined(PIN_A11) || defined(_RENESAS_RA_)
|
||||
#define RAM_BIG
|
||||
#endif
|
||||
|
||||
|
||||
// common CFG fuse address map for cfg16V8 and cfg20V8
|
||||
// the only difference is the starting address: 2048 for cfg16V8 and 2560 for cfg20V8
|
||||
// total size: 82
|
||||
@ -317,6 +330,25 @@ static const unsigned char cfg6002[] PROGMEM =
|
||||
64, 65
|
||||
};
|
||||
|
||||
// TODO: handle those:
|
||||
/*
|
||||
30, // 75: Security?
|
||||
135, // 70: Powerdown
|
||||
136, // 71: PinKeeper
|
||||
137, // 72: reserved1
|
||||
138, // 73: reserved2
|
||||
139, // 74: reserved3
|
||||
*/
|
||||
static const uint8_t cfgV750[] PROGMEM = {
|
||||
0, 3, 6, 9, 12, 15, 18, 21, 24, 27, // S0
|
||||
1, 4, 7, 10, 13, 16, 19, 22, 25, 28, // S1
|
||||
2, 5, 8, 11, 14, 17, 20, 23, 26, 29, // S2
|
||||
31, 35, 39, 43, 47, 51, 55, 59, 63, 67, // S3
|
||||
32, 36, 40, 44, 48, 52, 56, 60, 64, 68, // S4
|
||||
33, 37, 41, 45, 49, 53, 57, 61, 65, 69, // S5
|
||||
34, 38, 42, 46, 50, 54, 58, 62, 66, 70 // S6
|
||||
};
|
||||
|
||||
// UES user electronic signature
|
||||
// PES programmer electronic signature (ATF = text string, others = Vendor/Vpp/timing)
|
||||
// cfg configuration bits for OLMCs
|
||||
@ -347,7 +379,7 @@ typedef struct
|
||||
|
||||
const static galinfo_t galInfoList[] PROGMEM =
|
||||
{
|
||||
// +fuses +bits +uesbytes +cfgbase
|
||||
// +fuses +bits +uesbytes +pesrow +cfgbase
|
||||
// | +pins | +uesrow | +eraserow| +pesbytes | +cfg
|
||||
// +-- type + id0 + id1 | | +rows | | +uesfuse | +eraseallrow +cfgrow | | + cfgbits +cfgmethod +pinout
|
||||
// | | | | | | | | | | | | | | | | | | | |
|
||||
@ -366,12 +398,21 @@ const static galinfo_t galInfoList[] PROGMEM =
|
||||
{ATF20V8B, 0x00, 0x00, 2706, 24, 40, 64, 40, 2568, 8, 63, 62, 58, 8, 60, CFG_BASE_20 , cfgV8AB , sizeof(cfgV8AB) , CFG_STROBE_ROW, PINOUT_20V8 },
|
||||
{ATF22V10B, 0x00, 0x00, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22 , cfgV10 , sizeof(cfgV10) , CFG_SET_ROW , PINOUT_22V10 },
|
||||
{ATF22V10C, 0x00, 0x00, 5892, 24, 44, 132, 44, 5828, 8, 61, 62, 58, 10, 16, CFG_BASE_22 , cfgV10 , sizeof(cfgV10) , CFG_SET_ROW , PINOUT_22V10 },
|
||||
{ATF750C, 0x00, 0x00, 14499, 24, 84, 171, 84,14435, 8, 61, 60,127, 10, 16, CFG_BASE_750 , cfgV750 , sizeof(cfgV750) , CFG_STROBE_ROW2, PINOUT_22V10 }, // TODO: not all numbers are clear
|
||||
};
|
||||
galinfo_t galinfo __attribute__ ((section (".noinit"))); //preserve data between resets
|
||||
|
||||
#ifdef RAM_BIG
|
||||
// for ATF750C
|
||||
// MAXFUSES = (((171 * 84 bits) + uesbits + (10*3 + 1 + 10*4 + 5)) + 7) / 8
|
||||
// (14504 + 7) / 8 = 1813
|
||||
#define MAXFUSES 1813
|
||||
#else
|
||||
// Boards with small RAM (< 2.5kB) do not support ATF750C
|
||||
// MAXFUSES calculated as the biggest required space to hold the fuse bitmap
|
||||
// MAXFUSES = GAL6002 8330 bits = 8330/8 = 1041.25 bytes rounded up to 1042 bytes
|
||||
#define MAXFUSES 1042
|
||||
#endif
|
||||
|
||||
GALTYPE gal __attribute__ ((section (".noinit"))); //the gal device index pointing to galInfoList, value is preserved between resets
|
||||
|
||||
@ -406,6 +447,10 @@ void printHelp(char full) {
|
||||
if (varVppExists) {
|
||||
Serial.println(F(" varVpp "));
|
||||
}
|
||||
#ifdef RAM_BIG
|
||||
Serial.println(F(" RAM-BIG "));
|
||||
#endif
|
||||
|
||||
if (!full) {
|
||||
Serial.println(F("type 'h' for help"));
|
||||
return;
|
||||
@ -487,6 +532,7 @@ static void setPinMux(uint8_t pm) {
|
||||
case GAL26V12:
|
||||
case ATF22V10B:
|
||||
case ATF22V10C:
|
||||
case ATF750C:
|
||||
pinMode(PIN_ZIF10, pm);
|
||||
pinMode(PIN_ZIF11, pm);
|
||||
pinMode(PIN_ZIF13, pm);
|
||||
@ -836,11 +882,15 @@ static void setVPP(char on) {
|
||||
|
||||
// when PES is read the VPP is not determined via PES
|
||||
if (on == READPES) {
|
||||
if (gal == ATF16V8B || gal == ATF20V8B || gal == ATF22V10B || gal == ATF22V10C) {
|
||||
if (gal == ATF16V8B || gal == ATF20V8B || gal == ATF22V10B || gal == ATF22V10C || gal == ATF750C) {
|
||||
v = VPP_10V5;
|
||||
} else {
|
||||
v = VPP_11V5;
|
||||
}
|
||||
#if 0
|
||||
Serial.print(F("VPP index="));
|
||||
Serial.println(v);
|
||||
#endif
|
||||
} else {
|
||||
//safety check
|
||||
if (vpp < 36) {
|
||||
@ -850,12 +900,12 @@ static void setVPP(char on) {
|
||||
vpp = 48; //12V
|
||||
}
|
||||
v = (vpp >> 1) - 18; // 18: 2 * 9V, resolution 0.5V (not 0.25V) hence 'vpp >> 1'
|
||||
#if 0
|
||||
#if 0
|
||||
Serial.print(F("setVPP "));
|
||||
Serial.print(vpp);
|
||||
Serial.print(F(" index="));
|
||||
Serial.println(v);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
varVppSet(on ? v : VPP_5V0);
|
||||
delay(50); //settle the voltage
|
||||
@ -1119,6 +1169,13 @@ static void sendAddress(unsigned char n, unsigned char row)
|
||||
}
|
||||
setSDIN(row & 32); // SDIN = row number bit 0
|
||||
break;
|
||||
case ATF750C:
|
||||
while (n-- > 1) {
|
||||
sendBit(row & 1); // clock in row number bits 0-5
|
||||
row >>= 1;
|
||||
}
|
||||
setSDIN(row & 1); // SDIN = row number bit 6
|
||||
break;
|
||||
default:
|
||||
while (n-- > 0) {
|
||||
sendBit(row & 1); // clock in row number bits 0-5
|
||||
@ -1142,6 +1199,7 @@ static void strobe(unsigned short msec)
|
||||
// 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)
|
||||
{
|
||||
unsigned char nBits = 6;
|
||||
switch(gal) {
|
||||
case GAL16V8:
|
||||
case GAL20V8:
|
||||
@ -1153,6 +1211,9 @@ static void strobeRow(char row, char setBit = BIT_NONE)
|
||||
}
|
||||
strobe(2); // pulse /STB for 2ms
|
||||
break;
|
||||
case ATF750C:
|
||||
nBits = 7;
|
||||
//fall through
|
||||
case GAL18V10:
|
||||
case GAL20RA10:
|
||||
case GAL20XV10:
|
||||
@ -1162,7 +1223,7 @@ static void strobeRow(char row, char setBit = BIT_NONE)
|
||||
case ATF22V10B:
|
||||
case ATF22V10C:
|
||||
setRow(0); // set RA0-5 low
|
||||
sendAddress(6,row); // send row number (6 bits)
|
||||
sendAddress(nBits, row); // send row number (6 or 7 bits)
|
||||
setSTB(0);
|
||||
setSTB(1); // pulse /STB
|
||||
setSDIN(0); // SDIN low
|
||||
@ -1179,6 +1240,20 @@ static void strobeRow(char row, char setBit = BIT_NONE)
|
||||
}
|
||||
}
|
||||
|
||||
static void strobeConfigRow(char row)
|
||||
{
|
||||
switch(gal) {
|
||||
case ATF750C:
|
||||
setRow(0); // set RA0-5 low
|
||||
setRow(galinfo.cfgrow);
|
||||
sendAddress(7, row); // send row number (6 bits)
|
||||
setSDIN(1); // SDIN high
|
||||
setSTB(0);
|
||||
setSTB(1); // pulse /STB
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// read PES: programmer electronic signature (ATF = text string, others = Vendor/Vpp/timing)
|
||||
static void readPes(void) {
|
||||
unsigned short bitmask;
|
||||
@ -1271,7 +1346,7 @@ static unsigned char getDuration(unsigned char index) {
|
||||
}
|
||||
|
||||
static void setGalDefaults(void) {
|
||||
if (gal == ATF16V8B || gal == ATF20V8B || gal == ATF22V10B || gal == ATF22V10C) {
|
||||
if (gal == ATF16V8B || gal == ATF20V8B || gal == ATF22V10B || gal == ATF22V10C || gal == ATF750C) {
|
||||
progtime = 20;
|
||||
erasetime = 100;
|
||||
vpp = 42; /* 10.5V */
|
||||
@ -1299,6 +1374,7 @@ void parsePes(char type) {
|
||||
case ATF20V8B:
|
||||
case ATF22V10B:
|
||||
case ATF22V10C:
|
||||
case ATF750C:
|
||||
progtime = 20;
|
||||
erasetime = 100;
|
||||
vpp = 48; /* 12.0V */
|
||||
@ -1374,7 +1450,7 @@ void printPes(char type) {
|
||||
|
||||
Serial.print(F("PES info: "));
|
||||
//voltage
|
||||
if (pes[3] == ATMEL16 || pes[3] == ATMEL22) {
|
||||
if (pes[3] == ATMEL16 || pes[3] == ATMEL22 || pes[3] == ATMEL750) {
|
||||
//Serial.print(" ");
|
||||
} else {
|
||||
if (pes[1] & 0x10) {
|
||||
@ -1389,6 +1465,7 @@ void printPes(char type) {
|
||||
case LATTICE: Serial.print(F("Lattice ")); break;
|
||||
case NATIONAL: Serial.print(F("National ")); break;
|
||||
case SGSTHOMSON: Serial.print(F("ST Microsystems ")); break;
|
||||
case ATMEL750:
|
||||
case ATMEL16:
|
||||
case ATMEL22: Serial.print(F("Atmel ")); break;
|
||||
default: Serial.print(F("Unknown GAL, "));
|
||||
@ -1410,6 +1487,7 @@ void printPes(char type) {
|
||||
case ATF20V8B: Serial.print(F("ATF20V8B ")); break;
|
||||
case ATF22V10B: Serial.print(F("ATF22V10B ")); break;
|
||||
case ATF22V10C: Serial.print(F("ATF22V10C ")); break;
|
||||
case ATF750C: Serial.print(F("ATF750C ")); break;
|
||||
}
|
||||
|
||||
//programming info
|
||||
@ -1873,6 +1951,13 @@ static void readOrVerifyGal(char verify)
|
||||
readGalFuseMap(cfgV10, 1, (gal == GAL22V10) ? 0 : 68);
|
||||
}
|
||||
break;
|
||||
case ATF750C:
|
||||
//read with delay 1 ms, discard 107 bits on ATF750C
|
||||
if (verify) {
|
||||
i = verifyGalFuseMap(galinfo.cfg, 1, galinfo.bits - 8 * galinfo.uesbytes - 1);
|
||||
} else {
|
||||
readGalFuseMap(galinfo.cfg, 1, galinfo.bits - 8 * galinfo.uesbytes - 1);
|
||||
}
|
||||
}
|
||||
turnOff();
|
||||
|
||||
@ -1993,6 +2078,98 @@ static void writeGalFuseMapV10(const unsigned char* cfgArray, char fillUesStart,
|
||||
}
|
||||
}
|
||||
|
||||
// fuse-map writing function for ATF750C chips
|
||||
static void writeGalFuseMapV750(const unsigned char* cfgArray, char fillUesStart, char useSdin) {
|
||||
unsigned short cfgAddr = galinfo.cfgbase;
|
||||
unsigned char row, bit;
|
||||
unsigned short addr;
|
||||
|
||||
// write fuse rows
|
||||
setRow(0); //RA0-5 low
|
||||
delayMicroseconds(20);
|
||||
for(row = 0; row < galinfo.rows; row++) {
|
||||
for (bit = 0; bit < galinfo.bits; bit++) {
|
||||
addr = (galinfo.bits * row) + bit;
|
||||
sendBit(getFuseBit(addr));
|
||||
}
|
||||
|
||||
sendAddress(7, row);
|
||||
setPV(1);
|
||||
delayMicroseconds(20);
|
||||
strobe(progtime);
|
||||
delayMicroseconds(100);
|
||||
setPV(0);
|
||||
delayMicroseconds(12);
|
||||
}
|
||||
|
||||
// write UES
|
||||
uint8_t fillBitsBegin = galinfo.bits - (8 * galinfo.uesbytes) - 1;
|
||||
|
||||
setRow(0); //RA0-5 low
|
||||
if (fillUesStart) {
|
||||
sendBits(fillBitsBegin, 0);
|
||||
}
|
||||
else {
|
||||
fillBitsBegin = 0;
|
||||
}
|
||||
|
||||
for (bit = 0; bit < (8 * galinfo.uesbytes); bit++) {
|
||||
addr = bit;
|
||||
sendBit(getFuseBit(addr));
|
||||
}
|
||||
|
||||
uint8_t fillBitsEnd = galinfo.bits - (8 * galinfo.uesbytes) - fillBitsBegin;
|
||||
if (fillBitsEnd > 0) {
|
||||
sendBits(fillBitsEnd, 0);
|
||||
}
|
||||
|
||||
row = galinfo.uesrow;
|
||||
sendAddress(7, row);
|
||||
setPV(1);
|
||||
strobe(progtime);
|
||||
setPV(0);
|
||||
delay(progtime);
|
||||
|
||||
uint8_t cfgRowLen = 10; //ATF750C
|
||||
uint8_t cfgStrobeRow = 96; //ATF750C
|
||||
// write CFG
|
||||
uint8_t cfgrowcount = (galinfo.cfgbits + (cfgRowLen - 1)) / cfgRowLen;
|
||||
for(uint8_t i = 0; i < cfgrowcount; i++) {
|
||||
setRow(0);
|
||||
delayMicroseconds(10);
|
||||
setRow(galinfo.cfgrow);
|
||||
|
||||
for(bit = 0; bit < cfgRowLen; bit++) {
|
||||
uint8_t absBit = bit + (i * cfgRowLen);
|
||||
//addr = galinfo.cfgbase - (galinfo[gal].bits * rangeStartRow) + cfgArray[absBit];
|
||||
addr = galinfo.cfgbase + pgm_read_byte(&cfgArray[absBit]);
|
||||
uint8_t v = getFuseBit(addr);
|
||||
sendBit(v);
|
||||
}
|
||||
|
||||
sendAddress(7, i + cfgStrobeRow);
|
||||
delayMicroseconds(10);
|
||||
setPV(1);
|
||||
delayMicroseconds(18);
|
||||
strobe(progtime); // 20ms
|
||||
delayMicroseconds(32);
|
||||
setPV(0);
|
||||
delayMicroseconds(12);
|
||||
setRow(0);
|
||||
delayMicroseconds(12);
|
||||
}
|
||||
if (useSdin) {
|
||||
// disable power-down feature (JEDEC bit #5892)
|
||||
setRow(0);
|
||||
sendAddress(7, 125); //TODO - read the power down fuse bit state from the fuse map and set it only if needed
|
||||
setPV(1);
|
||||
strobe(progtime);
|
||||
setPV(0);
|
||||
delay(progtime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// fuse-map writing function for 600x GAL chips
|
||||
static void writeGalFuseMap600(const unsigned char* cfgArray) {
|
||||
unsigned short cfgAddr = galinfo.cfgbase;
|
||||
@ -2099,7 +2276,9 @@ static void writeGal()
|
||||
case ATF22V10B:
|
||||
case ATF22V10C:
|
||||
writeGalFuseMapV10(cfgV10, (gal == GAL22V10) ? 0 : 1, (gal == ATF22V10C) ? 1 : 0);
|
||||
break;
|
||||
break;
|
||||
case ATF750C:
|
||||
writeGalFuseMapV750(cfgV750, 1, 1);
|
||||
}
|
||||
turnOff();
|
||||
}
|
||||
@ -2162,6 +2341,10 @@ static char checkGalTypeViaPes(void)
|
||||
setFlagBit(FLAG_BIT_ATF16V8C, 1);
|
||||
}
|
||||
}
|
||||
else if (pes[8] == 'F' && pes[7] == 'V' && pes[6] == '7' && pes[5] == '5' && pes[4] == '0' && pes[3] =='C') {
|
||||
// complete string at beginning of row 127: "300C057VF100"
|
||||
type = ATF750C;
|
||||
}
|
||||
else if (pes[2] != 0x00 && pes[2] != 0xFF) {
|
||||
for (type = (sizeof(galInfoList) / sizeof(galinfo_t)) - 1; type; type--) {
|
||||
uint8_t id0 = pgm_read_byte(&galInfoList[type].id0);
|
||||
@ -2377,7 +2560,7 @@ static void printJedec()
|
||||
n = 0;
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (getFuseBit(k + 8 * j + i)) {
|
||||
if (gal == ATF22V10C) {
|
||||
if (gal == ATF22V10C || gal == ATF750C) {
|
||||
n |= 1 << (7 - i); // big-endian
|
||||
}
|
||||
else {
|
||||
|
@ -70,7 +70,8 @@ typedef enum {
|
||||
ATF16V8B,
|
||||
ATF20V8B,
|
||||
ATF22V10B,
|
||||
ATF22V10C
|
||||
ATF22V10C,
|
||||
ATF750C,
|
||||
} Galtype;
|
||||
|
||||
|
||||
@ -109,6 +110,7 @@ galinfo[] = {
|
||||
{ATF20V8B, 0x00, 0x00, "ATF20V8B", 2706, 24, 40, 64, 40, 2568, 8, 63, 59, 58, 8, 60, 82},
|
||||
{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},
|
||||
{ATF750C, 0x00, 0x00, "ATF750C", 14499, 24, 84, 171, 84, 14435, 8, 61, 60, 127, 10, 16, 71},
|
||||
};
|
||||
|
||||
char verbose = 0;
|
||||
@ -127,6 +129,7 @@ char varVppExists = 0;
|
||||
char printSerialWhileWaiting = 0;
|
||||
int calOffset = 0; //no calibration offset is applied
|
||||
char enableSecurity = 0;
|
||||
char bigRam = 0;
|
||||
|
||||
char opRead = 0;
|
||||
char opWrite = 0;
|
||||
@ -510,11 +513,11 @@ static int parseFuseMap(char *ptr) {
|
||||
if (
|
||||
(lastfuse == 0 ||
|
||||
galinfo[i].fuses == lastfuse ||
|
||||
galinfo[i].uesfuse == lastfuse && galinfo[i].uesfuse + 8 * galinfo[i].uesbytes == galinfo[i].fuses)
|
||||
(galinfo[i].uesfuse == lastfuse && galinfo[i].uesfuse + 8 * galinfo[i].uesbytes == galinfo[i].fuses))
|
||||
&&
|
||||
(pins == 0 ||
|
||||
galinfo[i].pins == pins ||
|
||||
galinfo[i].pins == 24 && pins == 28)
|
||||
(galinfo[i].pins == 24 && pins == 28))
|
||||
) {
|
||||
if (gal == 0) {
|
||||
type = i;
|
||||
@ -556,6 +559,11 @@ static char readJedec(void) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char checkForString(char* buf, int start, const char* key) {
|
||||
int labelPos = strstr(buf + start, key) - buf;
|
||||
return (labelPos > 0 && labelPos < 500) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int openSerial(void) {
|
||||
char buf[512] = {0};
|
||||
char devName[256] = {0};
|
||||
@ -589,14 +597,17 @@ static int openSerial(void) {
|
||||
//check we are communicating with Afterburner programmer
|
||||
labelPos = strstr(buf, "AFTerburner v.") - buf;
|
||||
|
||||
bigRam = 0;
|
||||
if (labelPos >= 0 && labelPos < 500 && buf[total - 3] == '>') {
|
||||
// check for new board desgin: variable VPP
|
||||
labelPos = strstr(buf + labelPos, " varVpp ") - buf;
|
||||
if (labelPos > 0 && labelPos < 500) {
|
||||
if (verbose) {
|
||||
printf("variable VPP board detected\n");
|
||||
}
|
||||
varVppExists = 1;
|
||||
varVppExists = checkForString(buf, labelPos, " varVpp ");
|
||||
if (verbose && varVppExists) {
|
||||
printf("variable VPP board detected\n");
|
||||
}
|
||||
// check for Big Ram
|
||||
bigRam = checkForString(buf, labelPos, " RAM-BIG");
|
||||
if (verbose & bigRam) {
|
||||
printf("MCU Big RAM detected\n");
|
||||
}
|
||||
//all OK
|
||||
return 0;
|
||||
@ -724,7 +735,10 @@ static int waitForSerialPrompt(char* buf, int bufSize, int maxDelay) {
|
||||
maxDelay -= 10;
|
||||
#else
|
||||
maxDelay -= 30;
|
||||
#endif
|
||||
#endif
|
||||
if(maxDelay <= 0 && verbose) {
|
||||
printf("waitForSerialPrompt timed out\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
return bufPos;
|
||||
|
Loading…
Reference in New Issue
Block a user