From c8090a49e6e8c6e2886a8c3c81400988ed099987 Mon Sep 17 00:00:00 2001 From: "Peter S. May" Date: Wed, 11 Jun 2014 08:15:56 -0400 Subject: [PATCH] * Added macros to make experimenting with other interface hardware easier. * `RAISE_VPP()`, `RAISE_VDD()`, `LOWER_VPP()`, `LOWER_VDD()` call their `digitalWrite()` counterparts. * `VDD_ON` and `VDD_OFF` complement to `MCLR_VPP` and `MCLR_RESET` as a means to change Vdd from active-high to active-low. * Previous behavior remains the default. * Added `VPP_BEFORE_VDD` define. When true (default), Vpp is raised before Vdd when entering program mode (this is the current behavior). When false, Vdd is raised before Vpp instead. * I needed to set this to false for my 16F88, probably due to an internal oscillator setting that needed to be cleared. --- ProgramEEPROM/ProgramEEPROM.pde | 17 ++++++++---- ProgramPIC/ProgramPIC.pde | 46 ++++++++++++++++++++++++--------- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/ProgramEEPROM/ProgramEEPROM.pde b/ProgramEEPROM/ProgramEEPROM.pde index b508817..8c94445 100644 --- a/ProgramEEPROM/ProgramEEPROM.pde +++ b/ProgramEEPROM/ProgramEEPROM.pde @@ -26,6 +26,13 @@ #define MCLR_RESET HIGH // PIN_MCLR state to reset the PIC #define MCLR_VPP LOW // PIN_MCLR state to apply 13v to MCLR/VPP pin +#define VDD_OFF LOW // PIN_VDD state to lower target VDD +#define VDD_ON HIGH // PIN_VDD state to raise target VDD + +#define LOWER_VPP() { digitalWrite(PIN_MCLR, MCLR_RESET); } +#define RAISE_VPP() { digitalWrite(PIN_MCLR, MCLR_VPP); } +#define LOWER_VDD() { digitalWrite(PIN_VDD, VDD_OFF); } +#define RAISE_VDD() { digitalWrite(PIN_VDD, VDD_ON); } // All delays are in microseconds. #define DELAY_SETTLE 50 // Delay for lines to settle for power off/on @@ -147,8 +154,8 @@ void setup() // Hold the chip in the powered down/reset state until we are ready for it. pinMode(PIN_MCLR, OUTPUT); pinMode(PIN_VDD, OUTPUT); - digitalWrite(PIN_MCLR, MCLR_RESET); - digitalWrite(PIN_VDD, LOW); + LOWER_VPP(); + LOWER_VDD(); // Initially set the CLOCK and DATA lines to be outputs in the high state. pinMode(PIN_CLOCK, OUTPUT); @@ -847,7 +854,7 @@ void enterProgramMode() return; // Lower VDD, which will power off the chip just in case. - digitalWrite(PIN_VDD, LOW); + LOWER_VDD(); // Make sure that CLOCK and DATA are high. pinMode(PIN_CLOCK, OUTPUT); @@ -859,7 +866,7 @@ void enterProgramMode() delayMicroseconds(DELAY_SETTLE); // Raise VDD. - digitalWrite(PIN_VDD, HIGH); + RAISE_VDD(); delayMicroseconds(DELAY_SETTLE); // Now in program mode, address not set yet. @@ -874,7 +881,7 @@ void exitProgramMode() return; // Lower VDD. - digitalWrite(PIN_VDD, LOW); + LOWER_VDD(); // Return the CLOCK and DATA lines to the pulled-high state. pinMode(PIN_CLOCK, OUTPUT); diff --git a/ProgramPIC/ProgramPIC.pde b/ProgramPIC/ProgramPIC.pde index d7db755..e8499b0 100644 --- a/ProgramPIC/ProgramPIC.pde +++ b/ProgramPIC/ProgramPIC.pde @@ -27,6 +27,19 @@ #define MCLR_RESET HIGH // PIN_MCLR state to reset the PIC #define MCLR_VPP LOW // PIN_MCLR state to apply 13v to MCLR/VPP pin +#define VDD_OFF LOW // PIN_VDD state to lower target VDD +#define VDD_ON HIGH // PIN_VDD state to raise target VDD + +#define LOWER_VPP() { digitalWrite(PIN_MCLR, MCLR_RESET); } +#define RAISE_VPP() { digitalWrite(PIN_MCLR, MCLR_VPP); } +#define LOWER_VDD() { digitalWrite(PIN_VDD, VDD_OFF); } +#define RAISE_VDD() { digitalWrite(PIN_VDD, VDD_ON); } + +// The default is true, but false is reportedly necessary for some devices, and +// for some other devices if the CP bit is enabled. Meanwhile, a device with an +// enabled internal oscillator may be trickier to program Vdd-first. If one +// doesn't work, why not try the other? +#define VPP_BEFORE_VDD true // All delays are in microseconds. #define DELAY_SETTLE 50 // Delay for lines to settle for reset @@ -171,8 +184,8 @@ void setup() // Hold the PIC in the powered down/reset state until we are ready for it. pinMode(PIN_MCLR, OUTPUT); pinMode(PIN_VDD, OUTPUT); - digitalWrite(PIN_MCLR, MCLR_RESET); - digitalWrite(PIN_VDD, LOW); + LOWER_VPP(); + LOWER_VDD(); // Clock and data are floating until the first PIC command. pinMode(PIN_CLOCK, INPUT); @@ -1080,8 +1093,8 @@ void enterProgramMode() // Lower MCLR, VDD, DATA, and CLOCK initially. This will put the // PIC into the powered-off, reset state just in case. - digitalWrite(PIN_MCLR, MCLR_RESET); - digitalWrite(PIN_VDD, LOW); + LOWER_VPP(); + LOWER_VDD(); digitalWrite(PIN_DATA, LOW); digitalWrite(PIN_CLOCK, LOW); @@ -1092,12 +1105,21 @@ void enterProgramMode() pinMode(PIN_DATA, OUTPUT); pinMode(PIN_CLOCK, OUTPUT); - // Raise MCLR, then VDD. - digitalWrite(PIN_MCLR, MCLR_VPP); - delayMicroseconds(DELAY_TPPDP); - digitalWrite(PIN_VDD, HIGH); - delayMicroseconds(DELAY_THLD0); - + if (VPP_BEFORE_VDD) { + // Raise MCLR, then VDD. + RAISE_VPP(); + delayMicroseconds(DELAY_TPPDP); + RAISE_VDD(); + delayMicroseconds(DELAY_THLD0); + } + else { + // Raise VDD, then MCLR. + RAISE_VDD(); + delayMicroseconds(DELAY_THLD0); + RAISE_VPP(); + delayMicroseconds(DELAY_TPPDP); + } + // Now in program mode, starting at the first word of program memory. state = STATE_PROGRAM; pc = 0; @@ -1111,8 +1133,8 @@ void exitProgramMode() return; // Lower MCLR, VDD, DATA, and CLOCK. - digitalWrite(PIN_MCLR, MCLR_RESET); - digitalWrite(PIN_VDD, LOW); + LOWER_VPP(); + LOWER_VDD(); digitalWrite(PIN_DATA, LOW); digitalWrite(PIN_CLOCK, LOW);