1616*
1717*
1818* Change log:
19+ * 04/15/22: - fix some chips by replacing configWord where only one configWord support,
20+ added support "configuration word 2" programm/erase, added a lot of chips from datasheet,
21+ added support for mid-range PIC12(L)F1822/PIC16(L)F1823. Bump version to 1.9
1922* 11/05/20: - added support for PIC16F688
2023* 11/06/18: - added support for PIC12F683
2124* 09/28/18: - added functon prototype for matchString for compliation with IDE 1.8.7; bump version to 1.8
@@ -107,6 +110,7 @@ unsigned long pc = 0; // Current program counter.
107110unsigned long programEnd = 0x07FF ;
108111unsigned long configStart = 0x2000 ;
109112unsigned long configEnd = 0x2007 ;
113+ unsigned long configSize = 8 ;
110114unsigned long dataStart = 0x2100 ;
111115unsigned long dataEnd = 0x217F ;
112116unsigned long reservedStart = 0x0800 ;
@@ -117,7 +121,7 @@ byte dataFlashType = EEPROM;
117121byte hpp_progEntryMode = MCLR_first;
118122
119123// Program version
120- const char s_Version[] = " 1.8 " ;
124+ const char s_Version[] = " 1.9 " ;
121125
122126// List of devices that are currently supported and their properties.
123127// Note: most of these are based on published information and have not
@@ -126,7 +130,6 @@ const char s_Version[] = "1.8";
126130// Please note that device names and device data are forced out into PROGMEM.
127131const char s_pic12f629[] PROGMEM = " pic12f629" ;
128132const char s_pic12f675[] PROGMEM = " pic12f675" ;
129- const char s_pic12f683[] PROGMEM = " pic12f683" ;
130133const char s_pic16f630[] PROGMEM = " pic16f630" ;
131134const char s_pic16f676[] PROGMEM = " pic16f676" ;
132135const char s_pic16f84[] PROGMEM = " pic16f84" ;
@@ -138,8 +141,16 @@ const char s_pic16f627a[] PROGMEM = "pic16f627a";
138141const char s_pic16f628[] PROGMEM = " pic16f628" ;
139142const char s_pic16f628a[] PROGMEM = " pic16f628a" ;
140143const char s_pic16f648a[] PROGMEM = " pic16f648a" ;
144+ const char s_pic16f631[] PROGMEM = " pic16f631" ;
145+ const char s_pic16f635[] PROGMEM = " pic16f635" ;
146+ const char s_pic16f636[] PROGMEM = " pic16f636/9" ;
147+ const char s_pic16f677[] PROGMEM = " pic16f677" ;
148+ const char s_pic16f683[] PROGMEM = " pic16f683" ;
141149const char s_pic16f684[] PROGMEM = " pic16f684" ;
150+ const char s_pic16f685[] PROGMEM = " pic16f685" ;
151+ const char s_pic16f687[] PROGMEM = " pic16f687" ;
142152const char s_pic16f688[] PROGMEM = " pic16f688" ;
153+ const char s_pic16f689[] PROGMEM = " pic16f689" ;
143154const char s_pic16f690[] PROGMEM = " pic16f690" ;
144155const char s_pic16f877[] PROGMEM = " pic16f877" ;
145156const char s_pic16f877a[] PROGMEM = " pic16f877a" ;
@@ -148,6 +159,10 @@ const char s_pic16f883[] PROGMEM = "pic16f883";
148159const char s_pic16f884[] PROGMEM = " pic16f884" ;
149160const char s_pic16f886[] PROGMEM = " pic16f886" ;
150161const char s_pic16f887[] PROGMEM = " pic16f887" ;
162+ const char s_pic12f1822[] PROGMEM = " pic12f1822" ;
163+ const char s_pic12lf1822[] PROGMEM = " pic12lf1822" ;
164+ const char s_pic16f1823[] PROGMEM = " pic16f1823" ;
165+ const char s_pic16lf1823[] PROGMEM = " pic16lf1823" ;
151166
152167struct deviceInfo {
153168 const char PROGMEM *name; // User-readable name of the device.
@@ -166,10 +181,8 @@ struct deviceInfo {
166181
167182struct deviceInfo const devices[] PROGMEM = {
168183 // http://ww1.microchip.com/downloads/en/DeviceDoc/41191D.pdf
169- // 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},
173186 {s_pic16f630, 0x10C0 , 1024 , 0x2000 , 0x2100 , 8 , 128 , 1 , 0x3E00 , FLASH4 , EEPROM , MCLR_first},
174187 {s_pic16f676, 0x10E0 , 1024 , 0x2000 , 0x2100 , 8 , 128 , 1 , 0x3E00 , FLASH4 , EEPROM , MCLR_first},
175188
@@ -189,14 +202,18 @@ struct deviceInfo const devices[] PROGMEM = {
189202 {s_pic16f628a, 0x1060 , 2048 , 0x2000 , 0x2100 , 8 , 128 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
190203 {s_pic16f648a, 0x1100 , 4096 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
191204
192- // http://ww1.microchip.com/downloads/en/devicedoc/41202C.pdf
205+ // https://ww1.microchip.com/downloads/en/DeviceDoc/40001204J.pdf
206+ {s_pic16f631, 0x1420 , 1024 , 0x2000 , 0x2100 , 8 , 128 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
207+ {s_pic16f635, 0x0FA0 , 1024 , 0x2000 , 0x2100 , 8 , 128 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
208+ {s_pic16f636, 0x10A0 , 2048 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first}, // this deviceId also used for pic16f639
209+ {s_pic16f677, 0x1440 , 2048 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
210+ {s_pic16f683, 0x0460 , 2048 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
193211 {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
212+ {s_pic16f685, 0x04A0 , 4096 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
213+ {s_pic16f687, 0x1320 , 2048 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
196214 {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},
215+ {s_pic16f689, 0x1340 , 4096 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
216+ {s_pic16f690, 0x1400 , 4096 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
200217
201218 // http://ww1.microchip.com/downloads/en/DeviceDoc/39025f.pdf
202219 {s_pic16f877, 0x09A0 , 8192 , 0x2000 , 0x2100 , 8 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
@@ -210,6 +227,12 @@ struct deviceInfo const devices[] PROGMEM = {
210227 {s_pic16f884, 0x2040 , 4096 , 0x2000 , 0x2100 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
211228 {s_pic16f886, 0x2060 , 8192 , 0x2000 , 0x2100 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
212229 {s_pic16f887, 0x2080 , 8192 , 0x2000 , 0x2100 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
230+
231+ // http://ww1.microchip.com/downloads/en/DeviceDoc/41390B.pdf
232+ {s_pic12f1822, 0x2700 , 2048 , 0x8000 , 0x1E000 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
233+ {s_pic12lf1822, 0x2800 , 2048 , 0x8000 , 0x1E000 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
234+ {s_pic16f1823, 0x2720 , 2048 , 0x8000 , 0x1E000 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
235+ {s_pic16lf1823, 0x2820 , 2048 , 0x8000 , 0x1E000 , 9 , 256 , 0 , 0 , FLASH4 , EEPROM , MCLR_first},
213236 {0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 }
214237};
215238
@@ -317,6 +340,7 @@ void initDevice(const struct deviceInfo *dev) {
317340 programEnd = pgm_read_dword (&(dev->programSize )) - 1 ;
318341 configStart = pgm_read_dword (&(dev->configStart ));
319342 configEnd = configStart + pgm_read_word (&(dev->configSize )) - 1 ;
343+ configSize = pgm_read_word (&(dev->configSize ));
320344 dataStart = pgm_read_dword (&(dev->dataStart ));
321345 dataEnd = dataStart + pgm_read_word (&(dev->dataSize )) - 1 ;
322346 reservedStart = programEnd - pgm_read_word (&(dev->reservedWords )) + 1 ;
@@ -363,7 +387,8 @@ void initDevice(const struct deviceInfo *dev) {
363387#define DEV_USERID2 2
364388#define DEV_USERID3 3
365389#define DEV_ID 6
366- #define DEV_CONFIG_WORD 7
390+ #define DEV_CONFIG_WORD1 7
391+ #define DEV_CONFIG_WORD2 8
367392
368393
369394// DEVICE command.
@@ -376,7 +401,9 @@ void cmdDevice(const char *args) {
376401 unsigned int userid2 = readConfigWord (DEV_USERID2 );
377402 unsigned int userid3 = readConfigWord (DEV_USERID3 );
378403 unsigned int deviceId = readConfigWord (DEV_ID );
379- unsigned int configWord = readConfigWord (DEV_CONFIG_WORD );
404+ unsigned int configWord1 = readConfigWord (DEV_CONFIG_WORD1 );
405+ unsigned int configWord2 = readConfigWord (DEV_CONFIG_WORD2 );
406+
380407 // If the device ID is all-zeroes or all-ones, then it could mean
381408 // one of the following:
382409 //
@@ -401,12 +428,16 @@ void cmdDevice(const char *args) {
401428 userid2 = readConfigWord (DEV_USERID2 );
402429 userid3 = readConfigWord (DEV_USERID3 );
403430 deviceId = readConfigWord (DEV_ID );
404- configWord = readConfigWord (DEV_CONFIG_WORD );
431+ configWord1 = readConfigWord (DEV_CONFIG_WORD1 );
432+ configWord2 = readConfigWord (DEV_CONFIG_WORD2 );
405433
406434 if (deviceId == 0 || deviceId == 0x3FFF ) {
407435 // now we explore case 5...
408436 hpp_progEntryMode = MCLR_first; // swith order, might be another type
409- unsigned int word = userid0 | userid1 | userid2 | userid3 | configWord;
437+ unsigned int word = userid0 | userid1 | userid2 | userid3 | configWord1;
438+ if (configSize == 9 ) {
439+ word |= configWord2;
440+ }
410441 unsigned int addr = 0 ;
411442 while (!word && addr < 16 ) {
412443 word |= readWord (addr);
@@ -454,7 +485,10 @@ void cmdDevice(const char *args) {
454485 dataFlashType = EEPROM ;
455486 }
456487 Serial.print (" ConfigWord: " );
457- printHex4 (configWord);
488+ printHex4 (configWord1);
489+ if (configSize == 9 ) {
490+ printHex4 (configWord2);
491+ }
458492 Serial.println ();
459493 Serial.println (" ." );
460494 // Don't need programming mode once the details have been read.
@@ -854,7 +888,8 @@ void cmdErase(const char *args) {
854888 bool preserve = !matchString (s_noPreserve, args, len);
855889 // Preserve reserved words if necessary.
856890 unsigned int *reserved = 0 ;
857- unsigned int configWord = 0x3FFF ;
891+ unsigned int configWord1 = 0x3FFF ;
892+ unsigned int configWord2 = 0x3FFF ;
858893 if (preserve && reservedStart <= reservedEnd) {
859894 size_t size = ((size_t )(reservedEnd - reservedStart + 1 ))
860895 * sizeof (unsigned int );
@@ -875,8 +910,12 @@ void cmdErase(const char *args) {
875910 }
876911 if (configSave != 0 && preserve) {
877912 // Some of the bits in the configuration word must also be saved.
878- configWord &= ~configSave;
879- configWord |= readWord (configStart + DEV_CONFIG_WORD ) & configSave;
913+ configWord1 &= ~configSave;
914+ configWord1 |= readWord (configStart + DEV_CONFIG_WORD1 ) & configSave;
915+ if (configSize == 9 ) {
916+ configWord2 &= ~configSave;
917+ configWord2 |= readWord (configStart + DEV_CONFIG_WORD2 ) & configSave;
918+ }
880919 }
881920 // Perform the memory type specific erase sequence.
882921 switch (progFlashType) {
@@ -936,9 +975,14 @@ void cmdErase(const char *args) {
936975 // Forcibly write 0x3FFF over the configuration words as erase
937976 // sometimes won't reset the words (e.g. PIC16F628A). If the
938977 // write fails, then leave the words as-is - don't report the failure.
939- for (unsigned long configAddr = configStart + DEV_CONFIG_WORD ;
978+ for (unsigned long configAddr = configStart + DEV_CONFIG_WORD1 ;
940979 configAddr <= configEnd; ++configAddr)
941- writeWordForced (configAddr, configWord);
980+ writeWordForced (configAddr, configWord1);
981+ if (configSize == 9 ) {
982+ for (unsigned long configAddr = configStart + DEV_CONFIG_WORD2 ;
983+ configAddr <= configEnd; ++configAddr)
984+ writeWordForced (configAddr, configWord2);
985+ }
942986 // Done.
943987 Serial.println (" OK" );
944988}
@@ -1369,7 +1413,7 @@ bool writeWord(unsigned long addr, unsigned int word) {
13691413 beginProgramCycle (addr, true );
13701414 readBack = sendReadCommand (CMD_READ_DATA_MEMORY );
13711415 readBack = (readBack >> 1 ) & 0x00FF ;
1372- } else if (!configSave || addr != (configStart + DEV_CONFIG_WORD )) {
1416+ } else if (!configSave || ( addr != (configStart + DEV_CONFIG_WORD1 ) || addr != (configStart + DEV_CONFIG_WORD2 ) )) {
13731417 word &= 0x3FFF ;
13741418 sendWriteCommand (CMD_LOAD_PROGRAM_MEMORY , word << 1 );
13751419 beginProgramCycle (addr, false );
0 commit comments