mirror of
https://github.com/ole00/afterburner.git
synced 2024-06-30 12:29:48 +00:00
Sketch: added support for new board design (v 3.0)
New features: * unified socket for 20 pin and 24 devices (including GAL20V8) * variable VPP via digi pot * VPP measurement via A0 ADC (used for VPP calibration)
This commit is contained in:
parent
48982f241a
commit
4db4108d4a
117
aftb_mcp4131.h
Normal file
117
aftb_mcp4131.h
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
//MCP4131 digital pot - bitbanged control
|
||||||
|
|
||||||
|
//set default pins
|
||||||
|
#ifndef POT_CS
|
||||||
|
#define POT_CS A3
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef POT_CLK
|
||||||
|
#define POT_CLK A4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef POT_DAT
|
||||||
|
#define POT_DAT A5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef POT_DEFAULT_VALUE
|
||||||
|
#define POT_DEFAULT_VALUE 0x40
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef POT_WIPER_ENABLED
|
||||||
|
#define POT_WIPER_ENABLED 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ADDR_WIPER 0
|
||||||
|
#define ADDR_WIPER0 0
|
||||||
|
#define ADDR_WIPER1 1
|
||||||
|
#define ADDR_TCON 4
|
||||||
|
#define ADDR_STAT 5
|
||||||
|
#define CMD_READ (0b11 << 10)
|
||||||
|
|
||||||
|
#define mcp4131_disableWiper() mcp4131_write(ADDR_TCON, 0b111111101)
|
||||||
|
#define mcp4131_enableWiper() mcp4131_write(ADDR_TCON, 0b111111111)
|
||||||
|
#define mcp4131_read(A) mcp4131_reg((A),0,1)
|
||||||
|
#define mcp4131_write(A,V) mcp4131_reg((A),(V),0)
|
||||||
|
|
||||||
|
// read or write the mcp4131 register
|
||||||
|
static uint16_t mcp4131_reg(uint8_t address, uint16_t value, uint8_t read_reg) {
|
||||||
|
int8_t i;
|
||||||
|
uint16_t r = address;
|
||||||
|
|
||||||
|
r <<= 12;
|
||||||
|
if (read_reg) {
|
||||||
|
r |= CMD_READ;
|
||||||
|
} else {
|
||||||
|
r |= value & 0x1FF; // clamp value to 9 bits
|
||||||
|
}
|
||||||
|
|
||||||
|
//setup Clock and and Data (SPI mode 0,0)
|
||||||
|
digitalWrite(POT_CLK, 0);
|
||||||
|
digitalWrite(POT_DAT, 0);
|
||||||
|
delayMicroseconds(50);
|
||||||
|
//activate IC
|
||||||
|
digitalWrite(POT_CS, 0);
|
||||||
|
|
||||||
|
i = 15;
|
||||||
|
while (i >= 0) {
|
||||||
|
//write address and command (bits 15 to 10)
|
||||||
|
if ((!read_reg) || i > 9) {
|
||||||
|
uint16_t mask = (1 << i);
|
||||||
|
digitalWrite(POT_DAT, (r & mask) ? 1 : 0);
|
||||||
|
}
|
||||||
|
digitalWrite(POT_CLK, 1); //rise the clock
|
||||||
|
//only when reading reg
|
||||||
|
if (read_reg) {
|
||||||
|
//switch the DAT pin to Input
|
||||||
|
if (i == 10) {
|
||||||
|
pinMode(POT_DAT, INPUT);
|
||||||
|
}
|
||||||
|
//read bits 9 to 0
|
||||||
|
if (i < 10) {
|
||||||
|
r |= (digitalRead(POT_DAT) << i); //read after rising edge
|
||||||
|
}
|
||||||
|
}
|
||||||
|
digitalWrite(POT_CLK, 0); //fall the clock
|
||||||
|
i--;
|
||||||
|
}
|
||||||
|
if (read_reg) {
|
||||||
|
pinMode(POT_DAT, OUTPUT);
|
||||||
|
}
|
||||||
|
|
||||||
|
//disable IC
|
||||||
|
digitalWrite(POT_CS, 1);
|
||||||
|
return r & 0x1FF; //clamp value to 9 bits
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mcp4131_init(void) {
|
||||||
|
pinMode(POT_CS, OUTPUT);
|
||||||
|
pinMode(POT_CLK, OUTPUT);
|
||||||
|
pinMode(POT_DAT, OUTPUT);
|
||||||
|
|
||||||
|
digitalWrite(POT_CS, 1); //unselect the POT's SPI bus
|
||||||
|
}
|
||||||
|
|
||||||
|
// initialisation and detection
|
||||||
|
// returns 1 if POT is detected, 0 otherwise
|
||||||
|
static uint8_t mcp4131_detect(void) {
|
||||||
|
uint16_t r;
|
||||||
|
mcp4131_disableWiper();
|
||||||
|
|
||||||
|
//note checking is done while the wiper is disabled - no resistance is applied
|
||||||
|
mcp4131_write(ADDR_WIPER, 0b1010);
|
||||||
|
r = mcp4131_read(ADDR_WIPER);
|
||||||
|
if (r != 0b1010) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
mcp4131_write(ADDR_WIPER, 0b101);
|
||||||
|
r = mcp4131_read(ADDR_WIPER);
|
||||||
|
if (r != 0b101) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
mcp4131_write(ADDR_WIPER, POT_DEFAULT_VALUE);
|
||||||
|
#if POT_WIPER_ENABLED
|
||||||
|
mcp4131_enableWiper();
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
317
aftb_vpp.h
Normal file
317
aftb_vpp.h
Normal file
|
@ -0,0 +1,317 @@
|
||||||
|
/*
|
||||||
|
* Variable voltage functions for Afterburner GAL project.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <EEPROM.h>
|
||||||
|
|
||||||
|
// ensure mcp4131 pot uses the right pins
|
||||||
|
#define POT_CS A3
|
||||||
|
#define POT_CLK A4
|
||||||
|
#define POT_DAT A5
|
||||||
|
#define VPP A0
|
||||||
|
|
||||||
|
#include "aftb_mcp4131.h"
|
||||||
|
#ifndef FAIL
|
||||||
|
#define FAIL 0
|
||||||
|
#define OK 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ABS(X) ((X) < 0 ? -(X) : (X));
|
||||||
|
#define VPP_5V0 0xFF
|
||||||
|
#define VPP_9V0 0
|
||||||
|
#define VPP_9V5 1
|
||||||
|
#define VPP_10V0 2
|
||||||
|
#define VPP_10V5 3
|
||||||
|
#define VPP_11V0 4
|
||||||
|
#define VPP_11V5 5
|
||||||
|
#define VPP_12V0 6
|
||||||
|
#define VPP_12V5 7
|
||||||
|
#define VPP_13V0 8
|
||||||
|
#define VPP_13V5 9
|
||||||
|
#define VPP_14V0 10
|
||||||
|
#define VPP_14V5 11
|
||||||
|
#define VPP_15V0 12
|
||||||
|
#define VPP_15V5 13
|
||||||
|
#define VPP_16V0 14
|
||||||
|
#define VPP_16V5 15
|
||||||
|
|
||||||
|
#define MAX_WIPER 16
|
||||||
|
|
||||||
|
#define VPP_VERBOSE 0
|
||||||
|
|
||||||
|
//pot wiper indices for the voltages
|
||||||
|
uint8_t vppWiper[MAX_WIPER] = {0};
|
||||||
|
|
||||||
|
// VPP must ramp-up to prevent voltage spikes and possibly resting arduino
|
||||||
|
#define varVppSetMax() varVppSetVppIndex(0x40); \
|
||||||
|
varVppSetVppIndex(0x70); \
|
||||||
|
varVppSetVppIndex(0x7c); \
|
||||||
|
varVppSetVppIndex(0x7e); \
|
||||||
|
varVppSetVppIndex(0x80);
|
||||||
|
#define varVppSetMin() varVppSetVppIndex(0x0);
|
||||||
|
|
||||||
|
uint8_t wiperStat = 0; //enabled / disabled
|
||||||
|
int8_t calOffset = 0; // VPP calibration offset: value 10 is 0.1V, value -10 is -0.1V
|
||||||
|
|
||||||
|
static void varVppReadCalib(void) {
|
||||||
|
uint8_t i;
|
||||||
|
//calibration not found
|
||||||
|
if (EEPROM.read(0) != 0xAF || EEPROM.read(1) != 0xCA) {
|
||||||
|
vppWiper[0] = 0;
|
||||||
|
Serial.println(F("No calibration data in EEPROM"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
calOffset = (int8_t) EEPROM.read(2);
|
||||||
|
for (i = 0; i < MAX_WIPER; i++) {
|
||||||
|
vppWiper[i] = EEPROM.read(i + 3);
|
||||||
|
#if 0
|
||||||
|
Serial.print(F("Calib "));
|
||||||
|
Serial.print(i);
|
||||||
|
Serial.print(F(":"));
|
||||||
|
Serial.println(vppWiper[i]);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// internal use only - set the wiper value on the digital pot
|
||||||
|
static void varVppSetVppIndex(uint8_t value) {
|
||||||
|
uint8_t i;
|
||||||
|
|
||||||
|
#if VPP_VERBOSE
|
||||||
|
Serial.print(F("varSetVppIndex "));
|
||||||
|
Serial.println(value);
|
||||||
|
#endif
|
||||||
|
mcp4131_write(ADDR_WIPER, value);
|
||||||
|
#if VPP_PARANOID
|
||||||
|
i = mcp4131_read(ADDR_WIPER);
|
||||||
|
if (i != value) {
|
||||||
|
Serial.print(F("Error writing POT value. Expected:"));
|
||||||
|
Serial.print(value);
|
||||||
|
Serial.print(F(" Actual:"));
|
||||||
|
Serial.println(i);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (value == 0) {
|
||||||
|
mcp4131_disableWiper();
|
||||||
|
wiperStat = 0;
|
||||||
|
} else if (wiperStat == 0) {
|
||||||
|
mcp4131_enableWiper();
|
||||||
|
wiperStat = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//use by the app code - set the variable voltage
|
||||||
|
static void varVppSet(uint8_t value) {
|
||||||
|
uint8_t v;
|
||||||
|
int8_t inc;
|
||||||
|
int8_t incMin;
|
||||||
|
if (value == VPP_5V0 || value >= MAX_WIPER) {
|
||||||
|
varVppSetVppIndex(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#if VPP_VERBOSE
|
||||||
|
Serial.print(F("varSetVpp "));
|
||||||
|
Serial.print(value);
|
||||||
|
Serial.print(F(":"));
|
||||||
|
Serial.println(vppWiper[value]);
|
||||||
|
#endif
|
||||||
|
//ramp up to prevent massive voltage overshoots
|
||||||
|
v = vppWiper[value] / 2;
|
||||||
|
v -= 2;
|
||||||
|
inc = 16;
|
||||||
|
incMin = 2;
|
||||||
|
if (value > VPP_13V0) {
|
||||||
|
incMin = 1;
|
||||||
|
}
|
||||||
|
while (v < vppWiper[value]) {
|
||||||
|
varVppSetVppIndex(v);
|
||||||
|
v+= inc + (inc / 2);
|
||||||
|
inc -= inc / 2;
|
||||||
|
if (inc < incMin) {
|
||||||
|
inc = incMin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
varVppSetVppIndex(vppWiper[value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SAMPLE_CNT 14
|
||||||
|
static int16_t varVppMeasureVpp(int8_t printValue) {
|
||||||
|
int8_t i = 0;
|
||||||
|
uint16_t r1 = 0;
|
||||||
|
|
||||||
|
while (i++ < SAMPLE_CNT) {
|
||||||
|
r1 += analogRead(VPP);
|
||||||
|
}
|
||||||
|
r1+= 5;
|
||||||
|
r1 /= 8;
|
||||||
|
r1 += calOffset;
|
||||||
|
if (printValue) {
|
||||||
|
uint8_t a = r1%100;
|
||||||
|
Serial.print(r1/100);
|
||||||
|
Serial.print(F("."));
|
||||||
|
if (a < 10) {
|
||||||
|
Serial.print(F("0"));
|
||||||
|
}
|
||||||
|
Serial.println(a);
|
||||||
|
}
|
||||||
|
return r1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns 1 on Success, 0 on Failure
|
||||||
|
static uint8_t varVppCalibrateVpp(void) {
|
||||||
|
uint8_t vppIndex = 0;
|
||||||
|
uint8_t i = 1;
|
||||||
|
int16_t v = 900; //starting at 9.00 V
|
||||||
|
int16_t r1 = 0;
|
||||||
|
int16_t r2;
|
||||||
|
int16_t minDif = 5000;
|
||||||
|
|
||||||
|
Serial.print(F("VPP calib. offset: "));
|
||||||
|
Serial.println(calOffset);
|
||||||
|
|
||||||
|
varVppSetVppIndex(1);
|
||||||
|
delay(300); //settle voltage
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
while (i <= 0x80) {
|
||||||
|
int16_t d1,d2;
|
||||||
|
varVppSetVppIndex(i);
|
||||||
|
delay(50); //let the voltage settle
|
||||||
|
#if VPP_VERBOSE
|
||||||
|
Serial.print(i);
|
||||||
|
Serial.print(F(") "));
|
||||||
|
#endif
|
||||||
|
r2 = varVppMeasureVpp(0);
|
||||||
|
d1 = r1 - v;
|
||||||
|
d2 = r2 - v;
|
||||||
|
d1 = ABS(d1);
|
||||||
|
d2 = ABS(d2);
|
||||||
|
|
||||||
|
if (r2 <= 100) { // less than 1V ? Failure
|
||||||
|
r1 = FAIL;
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d2 < minDif) {
|
||||||
|
minDif = d2;
|
||||||
|
vppWiper[vppIndex] = i;
|
||||||
|
//check last value / voltage
|
||||||
|
if (i == 0x80) {
|
||||||
|
if (v >= 1620 && v <= 1670) {
|
||||||
|
#if 1 || VPP_VERBOSE
|
||||||
|
Serial.println(F("*Index for VPP 1650 is 128"));
|
||||||
|
#endif
|
||||||
|
r1 = OK;
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
r1 = FAIL;
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
i--;
|
||||||
|
minDif = 5000;
|
||||||
|
#if 1 || VPP_VERBOSE
|
||||||
|
Serial.print(F("*Index for VPP "));
|
||||||
|
Serial.print(v);
|
||||||
|
Serial.print(F(" is "));
|
||||||
|
Serial.println(i);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
r1 = r2;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
vppIndex++;
|
||||||
|
#if VPP_VERBOSE
|
||||||
|
Serial.print(F("vppIndex "));
|
||||||
|
Serial.println(vppIndex);
|
||||||
|
#endif
|
||||||
|
if (vppIndex >= MAX_WIPER) {
|
||||||
|
r1 = OK;
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
v += 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret:
|
||||||
|
varVppSet(VPP_5V0);
|
||||||
|
return r1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void varVppStoreWiperCalib() {
|
||||||
|
uint8_t i = 0;
|
||||||
|
//sanity check
|
||||||
|
if (vppWiper[0] == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//write Afterburner calibration header
|
||||||
|
EEPROM.update(0, 0xAF);
|
||||||
|
EEPROM.update(1, 0xCA);
|
||||||
|
EEPROM.update(2, (uint8_t) calOffset);
|
||||||
|
while (i < MAX_WIPER) {
|
||||||
|
EEPROM.update(3 + i, vppWiper[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return 1 on success (variable VPP functionality present), 0 on failure (VPP not detected on board)
|
||||||
|
static int8_t varVppInit(void) {
|
||||||
|
analogReference(EXTERNAL); //use 3V3 external reference
|
||||||
|
|
||||||
|
wiperStat = 0; //wiper disabled
|
||||||
|
mcp4131_init();
|
||||||
|
if (mcp4131_detect()) {
|
||||||
|
#if VPP_VERBOSE
|
||||||
|
Serial.println(F("POT found"));
|
||||||
|
#endif
|
||||||
|
return OK;
|
||||||
|
} else {
|
||||||
|
#if VPP_VERBOSE
|
||||||
|
Serial.println(F("POT not found"));
|
||||||
|
#endif
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//return 1 on success (VPP calibration appears correct), 0 on failure
|
||||||
|
static int8_t varVppCheckCalibration(void) {
|
||||||
|
int16_t v;
|
||||||
|
|
||||||
|
varVppReadCalib();
|
||||||
|
if (vppWiper[0] == 0) {
|
||||||
|
Serial.println(F("I: VPP not calibrated"));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// This shoots the VPP to 9V - in theory no GALs should have an issue with that voltage.
|
||||||
|
// Also, the On switch should be turned off, preventing VPP to reach the GAL pins.
|
||||||
|
// check actual voltage
|
||||||
|
varVppSet(VPP_9V0);
|
||||||
|
delay(200); //Settle voltage
|
||||||
|
v = varVppMeasureVpp(0);
|
||||||
|
varVppSet(VPP_5V0); //set VPP back to 5V
|
||||||
|
// lower voltages have a good resolution, so we can have a tight voltage check bounds
|
||||||
|
if (v < 890 || v > 910) {
|
||||||
|
Serial.print(F("ER: VPP voltage check of 9V failed. Expected 900, measured "));
|
||||||
|
Serial.println(v);
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int8_t varVppCalibrate(void) {
|
||||||
|
if (varVppCalibrateVpp()) {
|
||||||
|
varVppStoreWiperCalib();
|
||||||
|
} else {
|
||||||
|
Serial.println(F("ER: Wiper calibration failed"));
|
||||||
|
return FAIL;
|
||||||
|
}
|
||||||
|
return OK;
|
||||||
|
}
|
||||||
|
|
390
afterburner.ino
390
afterburner.ino
|
@ -34,7 +34,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define VERSION "0.4.2"
|
#define VERSION "0.5.0"
|
||||||
|
|
||||||
//#define DEBUG_PES
|
//#define DEBUG_PES
|
||||||
//#define DEBUG_VERIFY
|
//#define DEBUG_VERIFY
|
||||||
|
@ -58,8 +58,32 @@
|
||||||
#define PIN_RA5 6
|
#define PIN_RA5 6
|
||||||
#define PIN_SCLK 7
|
#define PIN_SCLK 7
|
||||||
|
|
||||||
|
// pin multiplex: ZIF_PIN <----> ARDUINO PIN or Shift register pin (0b1xxx)
|
||||||
|
#define PIN_ZIF3 2
|
||||||
|
#define PIN_ZIF4 0b1
|
||||||
|
#define PIN_ZIF5 0b1000
|
||||||
|
#define PIN_ZIF6 0b100
|
||||||
|
#define PIN_ZIF7 0b10
|
||||||
|
#define PIN_ZIF8 5
|
||||||
|
#define PIN_ZIF9 6
|
||||||
|
#define PIN_ZIF10 7
|
||||||
|
#define PIN_ZIF11 8
|
||||||
|
#define PIN_ZIF13 12
|
||||||
|
#define PIN_ZIF14 11
|
||||||
|
#define PIN_ZIF15 10
|
||||||
|
#define PIN_ZIF16 9
|
||||||
|
#define PIN_ZIF21 0b10000
|
||||||
|
#define PIN_ZIF22 4
|
||||||
|
#define PIN_ZIF23 3
|
||||||
|
#define PIN_ZIF_GND_CTRL 13
|
||||||
|
|
||||||
|
//A0: VPP sense
|
||||||
|
//A3: DIGI_POT CS
|
||||||
|
#define PIN_SHR_EN A1
|
||||||
|
#define PIN_SHR_CS A2
|
||||||
|
//clk and dat is shared SPI bus
|
||||||
|
#define PIN_SHR_CLK A4
|
||||||
|
#define PIN_SHR_DAT A5
|
||||||
|
|
||||||
#define COMMAND_NONE 0
|
#define COMMAND_NONE 0
|
||||||
#define COMMAND_UNKNOWN 1
|
#define COMMAND_UNKNOWN 1
|
||||||
|
@ -83,6 +107,9 @@
|
||||||
#define COMMAND_ENABLE_SECURITY 's'
|
#define COMMAND_ENABLE_SECURITY 's'
|
||||||
#define COMMAND_ENABLE_APD 'z'
|
#define COMMAND_ENABLE_APD 'z'
|
||||||
#define COMMAND_DISABLE_APD 'Z'
|
#define COMMAND_DISABLE_APD 'Z'
|
||||||
|
#define COMMAND_MEASURE_VPP 'm'
|
||||||
|
#define COMMAND_CALIBRATE_VPP 'b'
|
||||||
|
#define COMMAND_CALIBRATION_OFFSET 'B'
|
||||||
|
|
||||||
#define READGAL 0
|
#define READGAL 0
|
||||||
#define VERIFYGAL 1
|
#define VERIFYGAL 1
|
||||||
|
@ -227,7 +254,8 @@ galinfo[]=
|
||||||
|
|
||||||
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
|
||||||
|
|
||||||
static short security = 0, erasetime = 100, progtime = 100, vpp = 0;
|
static short erasetime = 100, progtime = 100;
|
||||||
|
static uint8_t vpp = 0;
|
||||||
|
|
||||||
char echoEnabled;
|
char echoEnabled;
|
||||||
unsigned char pes[12];
|
unsigned char pes[12];
|
||||||
|
@ -239,7 +267,7 @@ char isUploading;
|
||||||
char uploadError;
|
char uploadError;
|
||||||
unsigned char fusemap[MAXFUSES];
|
unsigned char fusemap[MAXFUSES];
|
||||||
unsigned char flagBits;
|
unsigned char flagBits;
|
||||||
|
char varVppExists;
|
||||||
|
|
||||||
static void setFuseBit(unsigned short bitPos);
|
static void setFuseBit(unsigned short bitPos);
|
||||||
static unsigned short checkSum(unsigned short n);
|
static unsigned short checkSum(unsigned short n);
|
||||||
|
@ -247,9 +275,15 @@ static char checkGalTypeViaPes(void);
|
||||||
static void turnOff(void);
|
static void turnOff(void);
|
||||||
static void printFormatedNumberHex2(unsigned char num) ;
|
static void printFormatedNumberHex2(unsigned char num) ;
|
||||||
|
|
||||||
|
#include "aftb_vpp.h"
|
||||||
|
|
||||||
// print some help on the serial console
|
// print some help on the serial console
|
||||||
void printHelp(char full) {
|
void printHelp(char full) {
|
||||||
Serial.println(F("AFTerburner v." VERSION));
|
Serial.println(F("AFTerburner v." VERSION));
|
||||||
|
// indication for PC software that the new board desgin is used
|
||||||
|
if (varVppExists) {
|
||||||
|
Serial.println(F(" varVpp "));
|
||||||
|
}
|
||||||
if (!full) {
|
if (!full) {
|
||||||
Serial.println(F("type 'h' for help"));
|
Serial.println(F("type 'h' for help"));
|
||||||
return;
|
return;
|
||||||
|
@ -263,7 +297,9 @@ void printHelp(char full) {
|
||||||
Serial.println(F(" w - write uploaded fuses"));
|
Serial.println(F(" w - write uploaded fuses"));
|
||||||
Serial.println(F(" v - verify fuses"));
|
Serial.println(F(" v - verify fuses"));
|
||||||
Serial.println(F(" c - erase chip"));
|
Serial.println(F(" c - erase chip"));
|
||||||
Serial.println(F(" t - test VPP"));
|
Serial.println(F(" t - test & set VPP"));
|
||||||
|
Serial.println(F(" b - calibrate VPP"));
|
||||||
|
Serial.println(F(" m - measure VPP"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setFlagBit(uint8_t flag, uint8_t value) {
|
static void setFlagBit(uint8_t flag, uint8_t value) {
|
||||||
|
@ -274,6 +310,56 @@ static void setFlagBit(uint8_t flag, uint8_t value) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setPinMux(uint8_t pm) {
|
||||||
|
switch (gal) {
|
||||||
|
case GAL16V8:
|
||||||
|
case ATF16V8B:
|
||||||
|
pinMode(PIN_ZIF10, INPUT); //GND via MOSFET
|
||||||
|
pinMode(PIN_ZIF11, INPUT);
|
||||||
|
pinMode(PIN_ZIF13, INPUT);
|
||||||
|
pinMode(PIN_ZIF14, INPUT);
|
||||||
|
pinMode(PIN_ZIF16, INPUT_PULLUP); //DOUT
|
||||||
|
// ensure ZIF10 is Grounded via transistor
|
||||||
|
digitalWrite(PIN_ZIF_GND_CTRL, pm == OUTPUT ? HIGH: LOW);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GAL20V8:
|
||||||
|
pinMode(PIN_ZIF10, pm);
|
||||||
|
pinMode(PIN_ZIF11, pm);
|
||||||
|
pinMode(PIN_ZIF13, pm);
|
||||||
|
pinMode(PIN_ZIF14, pm);
|
||||||
|
pinMode(PIN_ZIF15, INPUT_PULLUP); //DOUT
|
||||||
|
pinMode(PIN_ZIF16, pm);
|
||||||
|
// ensure ZIF10 GND pull is disabled
|
||||||
|
digitalWrite(PIN_ZIF_GND_CTRL, LOW);
|
||||||
|
|
||||||
|
//pull down unused pins
|
||||||
|
digitalWrite(PIN_ZIF14, LOW);
|
||||||
|
digitalWrite(PIN_ZIF16, LOW);
|
||||||
|
digitalWrite(PIN_ZIF23, LOW);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GAL22V10:
|
||||||
|
case ATF22V10B:
|
||||||
|
case ATF22V10C:
|
||||||
|
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_ZIF15, LOW);
|
||||||
|
digitalWrite(PIN_ZIF16, LOW);
|
||||||
|
digitalWrite(PIN_ZIF22, LOW);
|
||||||
|
digitalWrite(PIN_ZIF22, LOW);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void setupGpios(uint8_t pm) {
|
static void setupGpios(uint8_t pm) {
|
||||||
|
|
||||||
|
@ -291,6 +377,35 @@ static void setupGpios(uint8_t pm) {
|
||||||
pinMode(PIN_SCLK, pm);
|
pinMode(PIN_SCLK, pm);
|
||||||
|
|
||||||
pinMode(PIN_VPP, pm);
|
pinMode(PIN_VPP, pm);
|
||||||
|
if (varVppExists) {
|
||||||
|
pinMode(PIN_ZIF_GND_CTRL, OUTPUT);
|
||||||
|
//disconnect shift register pins (High Z) when pm == Input
|
||||||
|
digitalWrite(PIN_SHR_EN, pm == INPUT ? HIGH : LOW);
|
||||||
|
setPinMux(pm);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SHR_SET_BIT(X) digitalWrite(PIN_SHR_CLK, 0); \
|
||||||
|
digitalWrite(PIN_SHR_DAT, (X) ? HIGH : LOW); \
|
||||||
|
digitalWrite(PIN_SHR_CLK, 1)
|
||||||
|
|
||||||
|
static void setShiftReg(uint8_t val) {
|
||||||
|
//assume CS is high
|
||||||
|
|
||||||
|
//ensure CLK is high (might be set low by other SPI devices)
|
||||||
|
digitalWrite(PIN_SHR_CLK, 1);
|
||||||
|
|
||||||
|
// set CS low
|
||||||
|
digitalWrite(PIN_SHR_CS, 0);
|
||||||
|
SHR_SET_BIT(val & 0b10000000);
|
||||||
|
SHR_SET_BIT(val & 0b1000000);
|
||||||
|
SHR_SET_BIT(val & 0b100000);
|
||||||
|
SHR_SET_BIT(val & 0b10000);
|
||||||
|
SHR_SET_BIT(val & 0b1000);
|
||||||
|
SHR_SET_BIT(val & 0b100);
|
||||||
|
SHR_SET_BIT(val & 0b10);
|
||||||
|
SHR_SET_BIT(val & 0b1);
|
||||||
|
digitalWrite(PIN_SHR_CS, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup the Arduino board
|
// setup the Arduino board
|
||||||
|
@ -304,6 +419,12 @@ void setup() {
|
||||||
lineIndex = 0;
|
lineIndex = 0;
|
||||||
setFlagBit(FLAG_BIT_TYPE_CHECK, 1); //do type check
|
setFlagBit(FLAG_BIT_TYPE_CHECK, 1); //do type check
|
||||||
|
|
||||||
|
//check & initialise variable voltage (old / new board design)
|
||||||
|
varVppExists = varVppInit();
|
||||||
|
|
||||||
|
// shift register
|
||||||
|
pinMode(PIN_SHR_EN, OUTPUT);
|
||||||
|
|
||||||
// Serial output from the GAL chip, input for Arduino
|
// Serial output from the GAL chip, input for Arduino
|
||||||
pinMode(PIN_SDOUT, INPUT);
|
pinMode(PIN_SDOUT, INPUT);
|
||||||
|
|
||||||
|
@ -312,6 +433,17 @@ void setup() {
|
||||||
setupGpios(INPUT);
|
setupGpios(INPUT);
|
||||||
|
|
||||||
printHelp(0);
|
printHelp(0);
|
||||||
|
|
||||||
|
if (varVppExists) {
|
||||||
|
// reads the calibration values
|
||||||
|
if (varVppCheckCalibration()) {
|
||||||
|
Serial.println(F("I: VPP calib. OK"));
|
||||||
|
}
|
||||||
|
// set shift reg Chip select
|
||||||
|
pinMode(PIN_SHR_CS, OUTPUT);
|
||||||
|
digitalWrite(PIN_SHR_CS, 1); //unselect the POT's SPI bus
|
||||||
|
}
|
||||||
|
|
||||||
Serial.println(">");
|
Serial.println(">");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,7 +491,8 @@ char handleTerminalCommands() {
|
||||||
} else if (lineIndex > 2) {
|
} else if (lineIndex > 2) {
|
||||||
c = line[0];
|
c = line[0];
|
||||||
if (!isUploading || c != '#') {
|
if (!isUploading || c != '#') {
|
||||||
if (c != COMMAND_SET_GAL_TYPE) {
|
// prevent 2 character commands from being flagged as invalid
|
||||||
|
if (!(c == COMMAND_SET_GAL_TYPE || c == COMMAND_CALIBRATION_OFFSET)) {
|
||||||
c = COMMAND_UNKNOWN;
|
c = COMMAND_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -488,6 +621,9 @@ void parseUploadLine() {
|
||||||
unsigned short cs = checkSum(galinfo[gal].fuses + apdFuse);
|
unsigned short cs = checkSum(galinfo[gal].fuses + apdFuse);
|
||||||
if (cs == val) {
|
if (cs == val) {
|
||||||
Serial.println(F("OK checksum matches"));
|
Serial.println(F("OK checksum matches"));
|
||||||
|
// Conditioning jed files might not have any fuse set, so as long as
|
||||||
|
// they supply empty checksum (C0000) the upload is OK.
|
||||||
|
mapUploaded = 1;
|
||||||
} else {
|
} else {
|
||||||
uploadError = 1;
|
uploadError = 1;
|
||||||
Serial.print(F("ER checksum:"));
|
Serial.print(F("ER checksum:"));
|
||||||
|
@ -525,6 +661,38 @@ static void setVCC(char on) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setVPP(char on) {
|
static void setVPP(char on) {
|
||||||
|
// new board desgin
|
||||||
|
if (varVppExists) {
|
||||||
|
uint8_t v = VPP_11V0;
|
||||||
|
|
||||||
|
// when PES is read the VPP is not determined via PES
|
||||||
|
if (on == READPES) {
|
||||||
|
if (gal == ATF16V8B || gal == ATF22V10B || gal == ATF22V10B) {
|
||||||
|
v = VPP_10V0;
|
||||||
|
} else {
|
||||||
|
v = VPP_11V5;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//safety check
|
||||||
|
if (vpp < 36) {
|
||||||
|
vpp = 36; //9V
|
||||||
|
} else
|
||||||
|
if (vpp > 66) {
|
||||||
|
vpp = 40; //12V
|
||||||
|
}
|
||||||
|
v = (vpp >> 1) - 18; // 18: 2 * 9V, resolution 0.5V (not 0.25V) hence 'vpp >> 1'
|
||||||
|
#if 0
|
||||||
|
Serial.print(F("setVPP "));
|
||||||
|
Serial.print(vpp);
|
||||||
|
Serial.print(F(" index="));
|
||||||
|
Serial.println(v);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
varVppSet(on ? v : VPP_5V0);
|
||||||
|
delay(50); //settle the voltage
|
||||||
|
}
|
||||||
|
// old board design
|
||||||
|
else {
|
||||||
//programming voltage is controlled by VPP_PIN,
|
//programming voltage is controlled by VPP_PIN,
|
||||||
//but the programming voltage must be set manually by user turning a Pot
|
//but the programming voltage must be set manually by user turning a Pot
|
||||||
digitalWrite(PIN_VPP, on ? 1 : 0);
|
digitalWrite(PIN_VPP, on ? 1 : 0);
|
||||||
|
@ -532,41 +700,114 @@ static void setVPP(char on) {
|
||||||
//Serial.print(F("VPP set to:"));
|
//Serial.print(F("VPP set to:"));
|
||||||
//Serial.println( on ? "12V": "5V");
|
//Serial.println( on ? "12V": "5V");
|
||||||
delay(10);
|
delay(10);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void setSTB(char on) {
|
static void setSTB(char on) {
|
||||||
|
if (varVppExists) {
|
||||||
|
const unsigned short b = galinfo[gal].cfgbase;
|
||||||
|
const uint8_t pin = (b == CFG_BASE_16) ? PIN_ZIF15 : PIN_ZIF13;
|
||||||
|
digitalWrite(pin, on ? 1:0);
|
||||||
|
} else {
|
||||||
digitalWrite(PIN_STROBE, on ? 1:0);
|
digitalWrite(PIN_STROBE, on ? 1:0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setPV(char on) {
|
static void setPV(char on) {
|
||||||
|
if (varVppExists) {
|
||||||
|
const unsigned short b = galinfo[gal].cfgbase;
|
||||||
|
uint8_t pin = PIN_ZIF23;
|
||||||
|
|
||||||
|
if (b == CFG_BASE_22) {
|
||||||
|
pin = PIN_ZIF3;
|
||||||
|
} else
|
||||||
|
if (b == CFG_BASE_20) {
|
||||||
|
pin = PIN_ZIF22;
|
||||||
|
}
|
||||||
|
digitalWrite(pin, on ? 1:0);
|
||||||
|
} else {
|
||||||
digitalWrite(PIN_PV, on ? 1:0);
|
digitalWrite(PIN_PV, on ? 1:0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setSDIN(char on) {
|
static void setSDIN(char on) {
|
||||||
|
if (varVppExists) {
|
||||||
|
const unsigned short b = galinfo[gal].cfgbase;
|
||||||
|
const uint8_t pin = (b == CFG_BASE_16) ? PIN_ZIF9 : PIN_ZIF11;
|
||||||
|
digitalWrite(pin, on ? 1:0);
|
||||||
|
} else {
|
||||||
digitalWrite(PIN_SDIN, on ? 1:0);
|
digitalWrite(PIN_SDIN, on ? 1:0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setSCLK(char on){
|
static void setSCLK(char on){
|
||||||
|
if (varVppExists) {
|
||||||
|
const unsigned short b = galinfo[gal].cfgbase;
|
||||||
|
uint8_t pin = (b == CFG_BASE_16) ? PIN_ZIF8 : PIN_ZIF10;
|
||||||
|
digitalWrite(pin, on ? 1:0);
|
||||||
|
} else {
|
||||||
digitalWrite(PIN_SCLK, on ? 1:0);
|
digitalWrite(PIN_SCLK, on ? 1:0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// output row address (RA0-5)
|
// output row address (RA0-5)
|
||||||
static void setRow(char row)
|
static void setRow(char row)
|
||||||
{
|
{
|
||||||
|
if (varVppExists) {
|
||||||
|
uint8_t srval = 0;
|
||||||
|
const unsigned short b = galinfo[gal].cfgbase;
|
||||||
|
if (b == CFG_BASE_16) {
|
||||||
|
digitalWrite(PIN_ZIF22, (row & 0x1)); //RA0
|
||||||
|
digitalWrite(PIN_ZIF3 , (row & 0x2)); //RA1
|
||||||
|
if (row & 0x4) srval |= PIN_ZIF4; //RA2
|
||||||
|
if (row & 0x8) srval |= PIN_ZIF5; //RA3
|
||||||
|
if (row & 0x10) srval |= PIN_ZIF6; //RA4
|
||||||
|
if (row & 0x20) srval |= PIN_ZIF7; //RA5
|
||||||
|
} else
|
||||||
|
if (b == CFG_BASE_22) {
|
||||||
|
if (row & 0x1) srval |= PIN_ZIF4; //RA0
|
||||||
|
if (row & 0x2) srval |= PIN_ZIF5; //RA1
|
||||||
|
if (row & 0x4) srval |= PIN_ZIF6; //RA2
|
||||||
|
if (row & 0x8) srval |= PIN_ZIF7; //RA3
|
||||||
|
digitalWrite(PIN_ZIF8, (row & 0x10)); //RA4
|
||||||
|
digitalWrite(PIN_ZIF9, (row & 0x20)); //RA5
|
||||||
|
} else { //CGF_BASE_20
|
||||||
|
if (row & 0x1) srval |= PIN_ZIF21; //RA0
|
||||||
|
digitalWrite(PIN_ZIF3 , (row & 0x2)); //RA1
|
||||||
|
if (row & 0x4) srval |= PIN_ZIF4; //RA2
|
||||||
|
if (row & 0x8) srval |= PIN_ZIF5; //RA3
|
||||||
|
digitalWrite(PIN_ZIF8, (row & 0x10)); //RA4
|
||||||
|
digitalWrite(PIN_ZIF9, (row & 0x20)); //RA5
|
||||||
|
}
|
||||||
|
setShiftReg(srval);
|
||||||
|
} else {
|
||||||
digitalWrite(PIN_RA0, (row & 0x1));
|
digitalWrite(PIN_RA0, (row & 0x1));
|
||||||
digitalWrite(PIN_RA1, ((row & 0x2) ? 1:0));
|
digitalWrite(PIN_RA1, ((row & 0x2) ? 1:0));
|
||||||
digitalWrite(PIN_RA2, ((row & 0x4) ? 1:0));
|
digitalWrite(PIN_RA2, ((row & 0x4) ? 1:0));
|
||||||
digitalWrite(PIN_RA3, ((row & 0x8) ? 1:0));
|
digitalWrite(PIN_RA3, ((row & 0x8) ? 1:0));
|
||||||
digitalWrite(PIN_RA4, ((row & 0x10) ? 1:0));
|
digitalWrite(PIN_RA4, ((row & 0x10) ? 1:0));
|
||||||
digitalWrite(PIN_RA5, ((row & 0x20) ? 1:0));
|
digitalWrite(PIN_RA5, ((row & 0x20) ? 1:0));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// serial data out form the GAL chip -> received by Arduino
|
// serial data out form the GAL chip -> received by Arduino
|
||||||
static char getSDOUT(void)
|
static char getSDOUT(void)
|
||||||
{
|
{
|
||||||
|
if (varVppExists) {
|
||||||
|
const unsigned short b = galinfo[gal].cfgbase;
|
||||||
|
uint8_t pin = PIN_ZIF16;
|
||||||
|
|
||||||
|
if (b == CFG_BASE_22) {
|
||||||
|
pin = PIN_ZIF14;
|
||||||
|
} else
|
||||||
|
if (b == CFG_BASE_20) {
|
||||||
|
pin = PIN_ZIF15;
|
||||||
|
}
|
||||||
|
return digitalRead(pin) != 0;
|
||||||
|
} else {
|
||||||
return digitalRead(PIN_SDOUT) != 0;
|
return digitalRead(PIN_SDOUT) != 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GAL finish sequence
|
// GAL finish sequence
|
||||||
|
@ -589,6 +830,9 @@ static void turnOff(void)
|
||||||
static void turnOn(char mode) {
|
static void turnOn(char mode) {
|
||||||
setupGpios(OUTPUT);
|
setupGpios(OUTPUT);
|
||||||
|
|
||||||
|
if (mode == READPES) {
|
||||||
|
mode = 2;
|
||||||
|
} else
|
||||||
if (
|
if (
|
||||||
mode == WRITEGAL ||
|
mode == WRITEGAL ||
|
||||||
mode == ERASEGAL ||
|
mode == ERASEGAL ||
|
||||||
|
@ -596,7 +840,6 @@ static void turnOn(char mode) {
|
||||||
mode == BURNSECURITY ||
|
mode == BURNSECURITY ||
|
||||||
mode == WRITEPES ||
|
mode == WRITEPES ||
|
||||||
mode == VPPTEST ||
|
mode == VPPTEST ||
|
||||||
mode == READPES ||
|
|
||||||
mode == READGAL
|
mode == READGAL
|
||||||
) {
|
) {
|
||||||
mode = 1;
|
mode = 1;
|
||||||
|
@ -712,7 +955,6 @@ static void strobeRow(char row, char setBit = BIT_NONE)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// read PES: programmer electronic signature (ATF = text string, others = Vendor/Vpp/timing)
|
// read PES: programmer electronic signature (ATF = text string, others = Vendor/Vpp/timing)
|
||||||
static void readPes(void) {
|
static void readPes(void) {
|
||||||
unsigned short bitmask;
|
unsigned short bitmask;
|
||||||
|
@ -790,6 +1032,18 @@ static unsigned char getDuration(unsigned char index) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void setGalDefaults(void) {
|
||||||
|
if (gal == ATF16V8B || gal == ATF22V10B || gal == ATF22V10C) {
|
||||||
|
progtime = 20;
|
||||||
|
erasetime = 100;
|
||||||
|
vpp = 40; /* 10V */
|
||||||
|
} else {
|
||||||
|
progtime = 80;
|
||||||
|
erasetime = 80;
|
||||||
|
vpp = 44; /* 11V */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void parsePes(char type) {
|
void parsePes(char type) {
|
||||||
unsigned char algo;
|
unsigned char algo;
|
||||||
|
|
||||||
|
@ -797,6 +1051,11 @@ void parsePes(char type) {
|
||||||
type = gal;
|
type = gal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG_PES
|
||||||
|
Serial.print(F("Parse pes. gal="));
|
||||||
|
Serial.println(type, DEC);
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case ATF16V8B:
|
case ATF16V8B:
|
||||||
case ATF22V10B:
|
case ATF22V10B:
|
||||||
|
@ -866,18 +1125,6 @@ void parsePes(char type) {
|
||||||
vpp -= 8; // -2V
|
vpp -= 8; // -2V
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setGalDefaults(void) {
|
|
||||||
if (gal == ATF16V8B || gal == ATF22V10B || gal == ATF22V10C) {
|
|
||||||
progtime = 20;
|
|
||||||
erasetime = 100;
|
|
||||||
vpp = 40; /* 10V */
|
|
||||||
} else {
|
|
||||||
progtime = 80;
|
|
||||||
erasetime = 80;
|
|
||||||
vpp = 44; /* 11V */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// print PES information
|
// print PES information
|
||||||
void printPes(char type) {
|
void printPes(char type) {
|
||||||
|
|
||||||
|
@ -1670,6 +1917,32 @@ static void printNoFusesError() {
|
||||||
static void testVoltage(int seconds) {
|
static void testVoltage(int seconds) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
// New board design: set VPP to 16.5V and measure values
|
||||||
|
// on analogue pin A1
|
||||||
|
if (varVppExists) {
|
||||||
|
int16_t v;
|
||||||
|
uint8_t okCnt = 0;
|
||||||
|
|
||||||
|
varVppSetMax();
|
||||||
|
for (i = 0 ; i < seconds; i++) {
|
||||||
|
delay(1000);
|
||||||
|
v = varVppMeasureVpp(1); //measure and print
|
||||||
|
if (v >= 1640 && v <= 1664) {
|
||||||
|
okCnt++;
|
||||||
|
// stop early if the VPP is set correctly (still allow time for POT fine-tuning)
|
||||||
|
if (okCnt > 3) {
|
||||||
|
Serial.println(F("VPP OK"));
|
||||||
|
i = seconds;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
okCnt = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
varVppSet(VPP_5V0);
|
||||||
|
}
|
||||||
|
// Legacy board design: set the VPP_EN pin "On" and check
|
||||||
|
// with multimeter the desired VPP voltage specific for GAL chip.
|
||||||
|
else {
|
||||||
pinMode(PIN_VPP, OUTPUT);
|
pinMode(PIN_VPP, OUTPUT);
|
||||||
setVPP(1);
|
setVPP(1);
|
||||||
for (i = 0 ; i < seconds; i++) {
|
for (i = 0 ; i < seconds; i++) {
|
||||||
|
@ -1677,6 +1950,7 @@ static void testVoltage(int seconds) {
|
||||||
}
|
}
|
||||||
setVPP(0);
|
setVPP(0);
|
||||||
pinMode(PIN_VPP, INPUT);
|
pinMode(PIN_VPP, INPUT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1691,6 +1965,49 @@ static char doTypeCheck(void) {
|
||||||
return testProperGAL();
|
return testProperGAL();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void measureVpp(uint8_t index) {
|
||||||
|
varVppSet(index);
|
||||||
|
delay(150);
|
||||||
|
varVppMeasureVpp(1); //print measured value
|
||||||
|
delay(5000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void measureVppValues(void) {
|
||||||
|
if (!varVppExists) {
|
||||||
|
Serial.println(F("ER variable VPP not supported"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Serial.print(F("VPP calib. offset: "));
|
||||||
|
Serial.println(calOffset);
|
||||||
|
|
||||||
|
Serial.print(F("VPP: 4.2 - 5.0V : "));
|
||||||
|
measureVpp(VPP_5V0);
|
||||||
|
|
||||||
|
Serial.print(F("VPP: 9.0V : "));
|
||||||
|
measureVpp(VPP_9V0);
|
||||||
|
|
||||||
|
Serial.print(F("VPP: 12.0V : "));
|
||||||
|
measureVpp(VPP_12V0);
|
||||||
|
|
||||||
|
Serial.print(F("VPP: 14.0V : "));
|
||||||
|
measureVpp(VPP_14V0);
|
||||||
|
|
||||||
|
Serial.print(F("VPP: 16.0V : "));
|
||||||
|
measureVpp(VPP_16V0);
|
||||||
|
|
||||||
|
varVppSet(VPP_5V0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void calibrateVpp(void) {
|
||||||
|
if (!varVppExists) {
|
||||||
|
Serial.println(F("ER variable VPP not supported"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (varVppCalibrate()) {
|
||||||
|
Serial.println(F("Calibration OK"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Arduino main loop
|
// Arduino main loop
|
||||||
void loop() {
|
void loop() {
|
||||||
|
|
||||||
|
@ -1773,7 +2090,7 @@ void loop() {
|
||||||
if (mapUploaded) {
|
if (mapUploaded) {
|
||||||
if (doTypeCheck()) {
|
if (doTypeCheck()) {
|
||||||
writeGal();
|
writeGal();
|
||||||
//TODO security
|
//security is handled by COMMAND_ENABLE_SECURITY command
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printNoFusesError();
|
printNoFusesError();
|
||||||
|
@ -1835,8 +2152,35 @@ void loop() {
|
||||||
setFlagBit(FLAG_BIT_TYPE_CHECK, 1);
|
setFlagBit(FLAG_BIT_TYPE_CHECK, 1);
|
||||||
} break;
|
} break;
|
||||||
case COMMAND_DISABLE_CHECK_TYPE: {
|
case COMMAND_DISABLE_CHECK_TYPE: {
|
||||||
|
int i = 0;
|
||||||
|
while(i < 12){
|
||||||
|
pes[i++] = 0;
|
||||||
|
}
|
||||||
setFlagBit(FLAG_BIT_TYPE_CHECK, 0);
|
setFlagBit(FLAG_BIT_TYPE_CHECK, 0);
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
case COMMAND_MEASURE_VPP: {
|
||||||
|
measureVppValues();
|
||||||
|
} break;
|
||||||
|
|
||||||
|
// calibration offset helps to offset the resistor tolerances in voltage dividers and also
|
||||||
|
// small differences in analog ref which is ~3.3 V derived from LDO.
|
||||||
|
case COMMAND_CALIBRATION_OFFSET: {
|
||||||
|
int8_t offset = line[1] - '0';
|
||||||
|
if (offset >=0 && offset < 9) {
|
||||||
|
//0:-0.2V 1:-1.5V 2: -0.1V 3: -0.05V 4: 0V 5: 0.05V 6: 0.1V 7: 0.15V 8: 0.20V 9:0.25V
|
||||||
|
calOffset = (offset - 4) * 5;
|
||||||
|
Serial.print(F("Using cal offset: "));
|
||||||
|
Serial.println(calOffset);
|
||||||
|
} else {
|
||||||
|
Serial.println(F("ER: cal offset failed"));
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case COMMAND_CALIBRATE_VPP: {
|
||||||
|
calibrateVpp();
|
||||||
|
} break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
if (command != COMMAND_NONE) {
|
if (command != COMMAND_NONE) {
|
||||||
Serial.print(F("ER Unknown command: "));
|
Serial.print(F("ER Unknown command: "));
|
||||||
|
|
Loading…
Reference in New Issue
Block a user