1616*
1717*
1818* Change log:
19+ * 04/15/22: - added support "configuration word 2" programm/erase, added support for PIC12(L)F1822/PIC16(L)F1823. Bump version to 1.9
1920* 11/05/20: - added support for PIC16F688
2021* 11/06/18: - added support for PIC12F683
2122* 09/28/18: - added functon prototype for matchString for compliation with IDE 1.8.7; bump version to 1.8
@@ -107,6 +108,7 @@ unsigned long pc = 0; // Current program counter.
107108unsigned long programEnd = 0x07FF ;
108109unsigned long configStart = 0x2000 ;
109110unsigned long configEnd = 0x2007 ;
111+ unsigned long configSize = 8 ;
110112unsigned long dataStart = 0x2100 ;
111113unsigned long dataEnd = 0x217F ;
112114unsigned long reservedStart = 0x0800 ;
@@ -117,7 +119,7 @@ byte dataFlashType = EEPROM;
117119byte hpp_progEntryMode = MCLR_first;
118120
119121// Program version
120- const char s_Version[] = " 1.8 " ;
122+ const char s_Version[] = " 1.9 " ;
121123
122124// List of devices that are currently supported and their properties.
123125// Note: most of these are based on published information and have not
@@ -138,8 +140,16 @@ const char s_pic16f627a[] PROGMEM = "pic16f627a";
138140const char s_pic16f628[] PROGMEM = " pic16f628" ;
139141const char s_pic16f628a[] PROGMEM = " pic16f628a" ;
140142const char s_pic16f648a[] PROGMEM = " pic16f648a" ;
143+ const char s_pic16f631[] PROGMEM = " pic16f631" ;
144+ const char s_pic16f635[] PROGMEM = " pic16f635" ;
145+ const char s_pic16f636[] PROGMEM = " pic16f636/9" ;
146+ const char s_pic16f677[] PROGMEM = " pic16f677" ;
147+ const char s_pic16f683[] PROGMEM = " pic16f683" ;
141148const char s_pic16f684[] PROGMEM = " pic16f684" ;
149+ const char s_pic16f685[] PROGMEM = " pic16f685" ;
150+ const char s_pic16f687[] PROGMEM = " pic16f687" ;
142151const char s_pic16f688[] PROGMEM = " pic16f688" ;
152+ const char s_pic16f689[] PROGMEM = " pic16f689" ;
143153const char s_pic16f690[] PROGMEM = " pic16f690" ;
144154const char s_pic16f877[] PROGMEM = " pic16f877" ;
145155const char s_pic16f877a[] PROGMEM = " pic16f877a" ;
@@ -148,6 +158,10 @@ const char s_pic16f883[] PROGMEM = "pic16f883";
148158const char s_pic16f884[] PROGMEM = " pic16f884" ;
149159const char s_pic16f886[] PROGMEM = " pic16f886" ;
150160const char s_pic16f887[] PROGMEM = " pic16f887" ;
161+ const char s_pic12f1822[] PROGMEM = " pic12f1822" ;
162+ const char s_pic12lf1822[] PROGMEM = " pic12lf1822" ;
163+ const char s_pic16f1823[] PROGMEM = " pic16f1823" ;
164+ const char s_pic16lf1823[] PROGMEM = " pic16lf1823" ;
151165
152166struct deviceInfo {
153167 const char PROGMEM *name; // User-readable name of the device.
@@ -169,7 +183,7 @@ struct deviceInfo const devices[] PROGMEM = {
169183 // http://ww1.microchip.com/downloads/en/DeviceDoc/40001204J.pdf
170184 {s_pic12f629, 0x0F80 , 1024 , 0x2000 , 0x2100 , 8 , 128 , 1 , 0x3E00 , FLASH4 , EEPROM , MCLR_first},
171185 {s_pic12f675, 0x0FC0 , 1024 , 0x2000 , 0x2100 , 8 , 128 , 1 , 0x3E00 , FLASH4 , EEPROM , MCLR_first},
172- {s_pic12f683, 0x0460 , 2048 , 0x2000 , 0x2100 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
186+ {s_pic12f683, 0x0460 , 2048 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
173187 {s_pic16f630, 0x10C0 , 1024 , 0x2000 , 0x2100 , 8 , 128 , 1 , 0x3E00 , FLASH4 , EEPROM , MCLR_first},
174188 {s_pic16f676, 0x10E0 , 1024 , 0x2000 , 0x2100 , 8 , 128 , 1 , 0x3E00 , FLASH4 , EEPROM , MCLR_first},
175189
@@ -189,14 +203,18 @@ struct deviceInfo const devices[] PROGMEM = {
189203 {s_pic16f628a, 0x1060 , 2048 , 0x2000 , 0x2100 , 8 , 128 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
190204 {s_pic16f648a, 0x1100 , 4096 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
191205
192- // http://ww1.microchip.com/downloads/en/devicedoc/41202C.pdf
206+ // https://ww1.microchip.com/downloads/en/DeviceDoc/40001204J.pdf
207+ {s_pic16f631, 0x1420 , 1024 , 0x2000 , 0x2100 , 8 , 128 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
208+ {s_pic16f635, 0x0FA0 , 1024 , 0x2000 , 0x2100 , 9 , 128 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
209+ {s_pic16f636, 0x10A0 , 2048 , 0x2000 , 0x2100 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
210+ {s_pic16f677, 0x1440 , 2048 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
211+ {s_pic16f683, 0x0460 , 2048 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
193212 {s_pic16f684, 0x1080 , 2048 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
194-
195- // http://ww1.microchip.com/downloads/en/DeviceDoc/41203E.pdf
213+ {s_pic16f685, 0x04A0 , 4096 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
214+ {s_pic16f687, 0x1320 , 2048 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
196215 {s_pic16f688, 0x1180 , 4096 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
197-
198- // http://ww1.microchip.com/downloads/en/DeviceDoc/41262A.pdf
199- {s_pic16f690, 0x1400 , 4096 , 0x2000 , 0x2100 , 9 , 256 , 1 , 0 , FLASH4 , EEPROM , MCLR_first},
216+ {s_pic16f689, 0x1340 , 4096 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
217+ {s_pic16f690, 0x1400 , 4096 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
200218
201219 // http://ww1.microchip.com/downloads/en/DeviceDoc/39025f.pdf
202220 {s_pic16f877, 0x09A0 , 8192 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
@@ -210,6 +228,12 @@ struct deviceInfo const devices[] PROGMEM = {
210228 {s_pic16f884, 0x2040 , 4096 , 0x2000 , 0x2100 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
211229 {s_pic16f886, 0x2060 , 8192 , 0x2000 , 0x2100 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
212230 {s_pic16f887, 0x2080 , 8192 , 0x2000 , 0x2100 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
231+
232+ // http://ww1.microchip.com/downloads/en/DeviceDoc/41390B.pdf
233+ {s_pic12f1822, 0x2700 , 2048 , 0x8000 , 0x1E000 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
234+ {s_pic12lf1822, 0x2800 , 2048 , 0x8000 , 0x1E000 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
235+ {s_pic16f1823, 0x2720 , 2048 , 0x8000 , 0x1E000 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
236+ {s_pic16lf1823, 0x2820 , 2048 , 0x8000 , 0x1E000 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
213237 {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
214238};
215239
@@ -317,6 +341,7 @@ void initDevice(const struct deviceInfo *dev) {
317341 programEnd = pgm_read_dword (&(dev->programSize )) - 1 ;
318342 configStart = pgm_read_dword (&(dev->configStart ));
319343 configEnd = configStart + pgm_read_word (&(dev->configSize )) - 1 ;
344+ configSize = pgm_read_word (&(dev->configSize ));
320345 dataStart = pgm_read_dword (&(dev->dataStart ));
321346 dataEnd = dataStart + pgm_read_word (&(dev->dataSize )) - 1 ;
322347 reservedStart = programEnd - pgm_read_word (&(dev->reservedWords )) + 1 ;
@@ -363,7 +388,8 @@ void initDevice(const struct deviceInfo *dev) {
363388#define DEV_USERID2 2
364389#define DEV_USERID3 3
365390#define DEV_ID 6
366- #define DEV_CONFIG_WORD 7
391+ #define DEV_CONFIG_WORD1 7
392+ #define DEV_CONFIG_WORD2 8
367393
368394
369395// DEVICE command.
@@ -376,7 +402,9 @@ void cmdDevice(const char *args) {
376402 unsigned int userid2 = readConfigWord (DEV_USERID2 );
377403 unsigned int userid3 = readConfigWord (DEV_USERID3 );
378404 unsigned int deviceId = readConfigWord (DEV_ID );
379- unsigned int configWord = readConfigWord (DEV_CONFIG_WORD );
405+ unsigned int configWord1 = readConfigWord (DEV_CONFIG_WORD1 );
406+ unsigned int configWord2 = readConfigWord (DEV_CONFIG_WORD2 );
407+
380408 // If the device ID is all-zeroes or all-ones, then it could mean
381409 // one of the following:
382410 //
@@ -401,12 +429,16 @@ void cmdDevice(const char *args) {
401429 userid2 = readConfigWord (DEV_USERID2 );
402430 userid3 = readConfigWord (DEV_USERID3 );
403431 deviceId = readConfigWord (DEV_ID );
404- configWord = readConfigWord (DEV_CONFIG_WORD );
432+ configWord1 = readConfigWord (DEV_CONFIG_WORD1 );
433+ configWord2 = readConfigWord (DEV_CONFIG_WORD2 );
405434
406435 if (deviceId == 0 || deviceId == 0x3FFF ) {
407436 // now we explore case 5...
408437 hpp_progEntryMode = MCLR_first; // swith order, might be another type
409- unsigned int word = userid0 | userid1 | userid2 | userid3 | configWord;
438+ unsigned int word = userid0 | userid1 | userid2 | userid3 | configWord1;
439+ if (configSize == 9 ) {
440+ word |= configWord2;
441+ }
410442 unsigned int addr = 0 ;
411443 while (!word && addr < 16 ) {
412444 word |= readWord (addr);
@@ -454,7 +486,10 @@ void cmdDevice(const char *args) {
454486 dataFlashType = EEPROM ;
455487 }
456488 Serial.print (" ConfigWord: " );
457- printHex4 (configWord);
489+ printHex4 (configWord1);
490+ if (configSize == 9 ) {
491+ printHex4 (configWord2);
492+ }
458493 Serial.println ();
459494 Serial.println (" ." );
460495 // Don't need programming mode once the details have been read.
@@ -854,7 +889,8 @@ void cmdErase(const char *args) {
854889 bool preserve = !matchString (s_noPreserve, args, len);
855890 // Preserve reserved words if necessary.
856891 unsigned int *reserved = 0 ;
857- unsigned int configWord = 0x3FFF ;
892+ unsigned int configWord1 = 0x3FFF ;
893+ unsigned int configWord2 = 0x3FFF ;
858894 if (preserve && reservedStart <= reservedEnd) {
859895 size_t size = ((size_t )(reservedEnd - reservedStart + 1 ))
860896 * sizeof (unsigned int );
@@ -875,8 +911,12 @@ void cmdErase(const char *args) {
875911 }
876912 if (configSave != 0 && preserve) {
877913 // Some of the bits in the configuration word must also be saved.
878- configWord &= ~configSave;
879- configWord |= readWord (configStart + DEV_CONFIG_WORD ) & configSave;
914+ configWord1 &= ~configSave;
915+ configWord1 |= readWord (configStart + DEV_CONFIG_WORD1 ) & configSave;
916+ if (configSize == 9 ) {
917+ configWord2 &= ~configSave;
918+ configWord2 |= readWord (configStart + DEV_CONFIG_WORD2 ) & configSave;
919+ }
880920 }
881921 // Perform the memory type specific erase sequence.
882922 switch (progFlashType) {
@@ -936,9 +976,14 @@ void cmdErase(const char *args) {
936976 // Forcibly write 0x3FFF over the configuration words as erase
937977 // sometimes won't reset the words (e.g. PIC16F628A). If the
938978 // write fails, then leave the words as-is - don't report the failure.
939- for (unsigned long configAddr = configStart + DEV_CONFIG_WORD ;
979+ for (unsigned long configAddr = configStart + DEV_CONFIG_WORD1 ;
940980 configAddr <= configEnd; ++configAddr)
941- writeWordForced (configAddr, configWord);
981+ writeWordForced (configAddr, configWord1);
982+ if (configSize == 9 ) {
983+ for (unsigned long configAddr = configStart + DEV_CONFIG_WORD2 ;
984+ configAddr <= configEnd; ++configAddr)
985+ writeWordForced (configAddr, configWord2);
986+ }
942987 // Done.
943988 Serial.println (" OK" );
944989}
@@ -1369,7 +1414,7 @@ bool writeWord(unsigned long addr, unsigned int word) {
13691414 beginProgramCycle (addr, true );
13701415 readBack = sendReadCommand (CMD_READ_DATA_MEMORY );
13711416 readBack = (readBack >> 1 ) & 0x00FF ;
1372- } else if (!configSave || addr != (configStart + DEV_CONFIG_WORD )) {
1417+ } else if (!configSave || ( addr != (configStart + DEV_CONFIG_WORD1 ) || addr != (configStart + DEV_CONFIG_WORD2 ) )) {
13731418 word &= 0x3FFF ;
13741419 sendWriteCommand (CMD_LOAD_PROGRAM_MEMORY , word << 1 );
13751420 beginProgramCycle (addr, false );
0 commit comments