1 #ifndef AVRMega2560Programmer_h
2 #define AVRMega2560Programmer_h
7 #define AVR_DEBUG_PRINT(s) DEBUG_PRINT(s)
8 #define AVR_DEBUG_PRINTLN(s) DEBUG_PRINTLN(s)
9 #define AVR_DEBUG_PRINT_HEX(s) DEBUG_PRINT_HEX(s)
10 #define AVR_DEBUG_PRINTLN_HEX(s) DEBUG_PRINTLN_HEX(s)
12 #define AVR_DEBUG_PRINT(s)
13 #define AVR_DEBUG_PRINTLN(s)
14 #define AVR_DEBUG_PRINT_HEX(s)
15 #define AVR_DEBUG_PRINTLN_HEX(s)
56 fFlashPageCache(NULL),
57 fEEPROMPageCache(NULL)
64 pinMode(fResetPin, OUTPUT);
65 digitalWrite(fResetPin, HIGH);
72 fProgress = progressFunc;
77 digitalWrite(fResetPin, LOW);
82 digitalWrite(fResetPin, HIGH);
91 digitalWrite(fResetPin, LOW);
96 digitalWrite(fResetPin, HIGH);
99 while (MEGA_SERIAL.available())
109 while (MEGA_SERIAL.available())
112 unsigned timeout = 0;
113 fCommandSequence = 1;
114 fFlashPageAddr = ~0u;
115 fFlashPageSize = fRegions.flash.page_size;
116 fFlashPageCache = (uint8_t*)ps_malloc(fFlashPageSize);
118 fEEPROMPageAddr = ~0u;
119 fEEPROMPageSize = fRegions.eeprom.page_size;
120 fEEPROMPageCache = (uint8_t*)ps_malloc(fEEPROMPageSize);
123 for (Memory* mem = *Memory::head(); mem != NULL; mem = mem->next)
139 if (timeout++ >= ENTER_PROGRAMMING_ATTEMPTS)
156 if (programEnable() > 0)
170 unsigned char buf[8];
171 buf[0] = CMD_LEAVE_PROGMODE_ISP;
175 command(buf, 3,
sizeof(buf));
177 if (fFlashPageCache != NULL)
178 free(fFlashPageCache);
179 if (fEEPROMPageCache != NULL)
180 free(fEEPROMPageCache);
181 for (Memory* mem = *Memory::head(); mem != NULL; mem = mem->next)
190 Memory* mem = findRegion(type);
191 return (mem != NULL) ?
dumpMemory(*mem) :
false;
198 Memory* mem = findRegion(type);
212 Memory* mem = findRegion(type);
213 return (mem != NULL) ?
writeHexString(*mem, hexString, lineno) :
false;
218 Memory* mem = findRegion(type);
219 return (mem != NULL) ?
writeMemory(*mem, verify) :
false;
224 Memory* mem = findRegion(type);
232 CMD_SET_PARAMETER = 0x02,
233 CMD_GET_PARAMETER = 0x03,
234 CMD_SET_DEVICE_PARAMETERS = 0x04,
236 CMD_LOAD_ADDRESS = 0x06,
237 CMD_FIRMWARE_UPGRADE = 0x07,
241 CMD_ENTER_PROGMODE_ISP = 0x10,
242 CMD_LEAVE_PROGMODE_ISP = 0x11,
243 CMD_CHIP_ERASE_ISP = 0x12,
244 CMD_PROGRAM_FLASH_ISP = 0x13,
245 CMD_READ_FLASH_ISP = 0x14,
246 CMD_PROGRAM_EEPROM_ISP = 0x15,
247 CMD_READ_EEPROM_ISP= 0x16,
248 CMD_PROGRAM_FUSE_ISP = 0x17,
249 CMD_READ_FUSE_ISP= 0x18,
250 CMD_PROGRAM_LOCK_ISP = 0x19,
251 CMD_READ_LOCK_ISP= 0x1A,
252 CMD_READ_SIGNATURE_ISP = 0x1B,
253 CMD_READ_OSCCAL_ISP = 0x1C,
254 CMD_SPI_MULTI = 0x1D,
258 CMD_XPROG_SETMODE = 0x51,
263 STATUS_CMD_OK = 0x00,
266 STATUS_CMD_TOUT = 0x80,
267 STATUS_RDY_BSY_TOUT = 0x81,
268 STATUS_SET_PARAM_MISSING = 0x82,
271 STATUS_CMD_FAILED = 0xC0,
272 STATUS_CKSUM_ERROR = 0xC1,
273 STATUS_CMD_UNKNOWN = 0xC9,
274 STATUS_CMD_ILLEGAL_PARAMETER = 0xCA,
277 STATUS_ISP_READY = 0x00,
278 STATUS_CONN_FAIL_MOSI = 0x01,
279 STATUS_CONN_FAIL_RST = 0x02,
280 STATUS_CONN_FAIL_SCK = 0x04,
281 STATUS_TGT_NOT_DETECTED = 0x10,
282 STATUS_TGT_REVERSE_INSERTED = 0x20,
284 MESSAGE_START = 0x1B,
287 ANSWER_CKSUM_ERROR = 0xB0,
292 XPRG_ERR_COLLISION = 2,
293 XPRG_ERR_TIMEOUT = 3,
296 PARAM_SW_MAJOR = 0x91,
297 PARAM_SW_MINOR = 0x92,
351 MemOp() : fValid(false)
355 MemOp(ByteOp byte1, ByteOp byte2)
357 const ByteOp descs[] = { byte1, byte2 };
358 parseDescription(
sizeof(descs)/
sizeof(descs[0]), descs);
361 MemOp(ByteOp byte1, ByteOp byte2,
362 ByteOp byte3, ByteOp byte4)
364 const ByteOp descs[] = { byte1, byte2, byte3, byte4 };
365 parseDescription(
sizeof(descs)/
sizeof(descs[0]), descs);
368 inline bool isValid()
const
373 void setBits(uint8_t* cmd)
375 for (
int i = 0; i < 32; i++)
377 if (fBit[i].fOp == kValue)
381 uint8_t mask = 1 << bit;
390 void setAddress(uint8_t* cmd, uint32_t addr)
392 for (
int i = 0; i < 32; i++)
394 if (fBit[i].fOp == kAddress)
398 uint8_t mask = 1 << bit;
399 uint32_t value = addr >> fBit[i].fNum & 0x01;
408 void setInput(uint8_t* cmd, uint32_t data)
410 for (
int i = 0; i < 32; i++)
412 if (fBit[i].fOp == kInput)
416 uint8_t mask = 1 << bit;
417 uint8_t value = data >> fBit[i].fNum & 0x01;
426 void getOutput(uint8_t* res, uint8_t* data)
428 for (
int i = 0; i < 32; i++)
430 if (fBit[i].fOp == kOutput)
434 uint8_t mask = 1 << bit;
435 uint8_t value = ((res[j] & mask) >> bit) & 0x01;
436 value = value << fBit[i].fNum;
447 for (
int i = 0; i < 32; i++)
449 if (fBit[i].fOp == kOutput)
456 void printDescriptor(
const char* name)
458 static const char* opname[] = {
465 for (
int i = 31; i >= 0; i--)
469 printf(
"%-11s %8d %8s %5d %5d\n",
470 name, i, opname[fBit[i].fOp], fBit[i].fNum, fBit[i].fValue);
494 bool parseDescription(
size_t count,
const ByteOp* byteops)
498 for (
unsigned wi = 0; wi < count; wi++)
500 const BitOp* op = byteops[wi].arr;
501 for (
unsigned bi = 0; bi < 8; bi++)
507 BitOp bitop = op[bi];
511 fBit[bit].fOp = kValue;
512 fBit[bit].fValue = 1;
513 fBit[bit].fNum = bit % 8;
516 fBit[bit].fOp = kValue;
517 fBit[bit].fValue = 0;
518 fBit[bit].fNum = bit % 8;
521 fBit[bit].fOp = kIgnore;
522 fBit[bit].fValue = 0;
523 fBit[bit].fNum = bit % 8;
526 fBit[bit].fOp = kAddress;
527 fBit[bit].fValue = 0;
528 fBit[bit].fNum = 8 * (bit / 8) + bit % 8;
531 fBit[bit].fOp = kInput;
532 fBit[bit].fValue = 0;
533 fBit[bit].fNum = bit % 8;
536 fBit[bit].fOp = kOutput;
537 fBit[bit].fValue = 0;
538 fBit[bit].fNum = bit % 8;
541 fBit[bit].fNum = (uint8_t)bitop-(uint8_t)BitOp::a0;
542 fBit[bit].fOp = kAddress;
543 fBit[bit].fValue = 0;
553 MemOp pgmEnableOp = MemOp( ByteOp{ I, O, I, O, I, I, O, O }, ByteOp{ O, I, O, I, O, O, I, I },
554 ByteOp{ x, x, x, x, x, x, x, x }, ByteOp{ x, x, x, x, x, x, x, x });
556 MemOp chipEraseOp = MemOp( ByteOp{ I, O, I, O, I, I, O, I }, ByteOp{ I, O, O, O, O, O, O, O },
557 ByteOp{ x, x, x, x, x, x, x, x }, ByteOp{ x, x, x, x, x, x, x, x });
565 unsigned page_size = 0;
566 unsigned num_pages = 0;
567 unsigned min_write_delay = 0;
568 unsigned max_write_delay = 0;
569 unsigned readback_p1 = 0;
570 unsigned readback_p2 = 0;
574 unsigned blocksize = 0;
575 unsigned readsize = 0;
590 uint32_t* tags = NULL;
591 uint32_t* page_tags = NULL;
601 (*tail())->next =
this;
607 buf = (uint8_t*)ps_malloc(size);
608 memset(buf, 0xFF, size);
610 unsigned tagsize = (size/32+1)*
sizeof(uint32_t);
611 tags = (uint32_t*)ps_malloc(tagsize);
612 memset(tags, 0, tagsize);
616 tagsize = ((size/page_size)/32+1)*
sizeof(uint32_t);
617 page_tags = (uint32_t*)ps_malloc(tagsize);
618 memset(page_tags, 0, tagsize);
634 if (page_tags != NULL)
641 void tagAddress(
unsigned addr,
bool tag)
646 tags[addr / 32] |= (1 << (addr % 32));
648 tags[addr / 32] &= ~(1 << (addr % 32));
652 void tagPage(
unsigned addr,
bool tag)
654 if (page_size > 0 && addr < size)
656 unsigned pageAddr = addr / page_size;
658 page_tags[pageAddr / 32] |= (1 << (pageAddr % 32));
660 page_tags[pageAddr / 32] &= ~(1 << (pageAddr % 32));
664 bool isAddressTagged(
unsigned addr)
666 return (addr < size) ? ((tags[addr / 32] & (1 << (addr % 32))) != 0) :
false;
669 bool isPageTagged(
unsigned addr)
671 if (page_size > 0 && addr < size)
673 unsigned pageAddr = addr / page_size;
674 return ((page_tags[pageAddr / 32] & (1 << (pageAddr % 32))) != 0);
679 uint8_t get(
unsigned addr)
686 void set(
unsigned addr, uint8_t
byte)
688 if (addr < size && buf[addr] !=
byte)
691 tagAddress(addr,
true);
696 static Memory** head()
698 static Memory* sHead;
702 static Memory** tail()
704 static Memory* sTail;
709 void printDescription()
711 printf(
" Block Poll Page Polled\n");
712 printf(
"Memory Type Mode Delay Size Indx Paged Size Size #Pages MinW MaxW ReadBack\n");
713 printf(
"----------- ---- ----- ----- ---- ------ ------ ---- ------ ----- ----- ---------\n");
714 printf(
"%-11s %4d %5d %5d %4d %6s %6d %4d %6d %4d %4d 0x%02X 0x%02X\n",
715 "signature", mode, delay, blocksize, 0, ((paged) ?
"yes" :
"no"),
716 size, page_size, (page_size != 0) ? size / page_size : 0,
717 min_write_delay, max_write_delay, readback_p1, readback_p2);
719 printf(
" Memory Ops:\n");
720 printf(
" Operation Inst Bit Bit Type Bitno Value\n");
721 printf(
" ----------- -------- -------- ----- -----\n");
723 read.printDescriptor(
"READ");
738 min_write_delay = 4500;
739 max_write_delay = 4500;
748 read_lo = MemOp(ByteOp{ O, O, I, O, O, O, O, O },
749 ByteOp{ a15, a14, a13, a12, a11, a10, a9, a8 },
750 ByteOp{ a7, a6, a5, a4, a3, a2, a1, a0 },
751 ByteOp{ o, o, o, o, o, o, o, o });
753 read_hi = MemOp(ByteOp{ O, O, I, O, I, O, O, O },
754 ByteOp{ a15, a14, a13, a12, a11, a10, a9, a8 },
755 ByteOp{ a7, a6, a5, a4, a3, a2, a1, a0 },
756 ByteOp{ o, o, o, o, o, o, o, o });
758 loadpage_lo = MemOp(ByteOp{ O, I, O, O, O, O, O, O },
759 ByteOp{ x, x, x, x, x, x, x, x },
760 ByteOp{ x, a6, a5, a4, a3, a2, a1, a0 },
761 ByteOp{ i, i, i, i, i, i, i, i });
763 loadpage_hi = MemOp(ByteOp{ O, I, O, O, I, O, O, O },
764 ByteOp{ x, x, x, x, x, x, x, x },
765 ByteOp{ x, a6, a5, a4, a3, a2, a1, a0 },
766 ByteOp{ i, i, i, i, i, i, i, i });
768 writepage = MemOp(ByteOp{ O, I, O, O, I, I, O, O },
769 ByteOp{ a15, a14, a13, a12, a11, a10, a9, a8 },
770 ByteOp{ a7, x, x, x, x, x, x, x },
771 ByteOp{ x, x, x, x, x, x, x, x });
773 load_ext_addr = MemOp(ByteOp{ O, I, O, O, I, I, O, I },
774 ByteOp{ O, O, O, O, O, O, O, O },
775 ByteOp{ O, O, O, O, O, O, O, a16 },
776 ByteOp{ O, O, O, O, O, O, O, O });
786 min_write_delay = 9000;
787 max_write_delay = 9000;
796 read = MemOp(ByteOp{ I, O, I, O, O, O, O, O },
797 ByteOp{ x, x, x, x, a11, a10, a9, a8 },
798 ByteOp{ a7, a6, a5, a4, a3, a2, a1, a0 },
799 ByteOp{ o, o, o, o, o, o, o, o });
801 write = MemOp(ByteOp{ I, I, O, O, O, O, O, O },
802 ByteOp{ x, x, x, x, a11, a10, a9, a8 },
803 ByteOp{ a7, a6, a5, a4, a3, a2, a1, a0 },
804 ByteOp{ i, i, i, i, i, i, i, i });
806 loadpage_lo = MemOp(ByteOp{ I, I, I, I, O, O, O, I},
807 ByteOp{ O, O, O, O, O, O, O, I},
808 ByteOp{ O, O, O, O, O, a2, a1, a0},
809 ByteOp{ i, i, i, i, i, i, i, i});
811 writepage = MemOp(ByteOp{ I, I, O, O, O, O, I, O},
812 ByteOp{ O, O, x, x, a11, a10, a9, a8},
813 ByteOp{ a7, a6, a5, a4, a3, O, O, O},
814 ByteOp{ x, x, x, x, x, x, x, x});
822 min_write_delay = 9000;
823 max_write_delay = 9000;
829 write = MemOp(ByteOp{ I, O, I, O, I, I, O, O },
830 ByteOp{ I, O, I, O, O, O, O, I },
831 ByteOp{ x, x, x, x, x, x, x, x },
832 ByteOp{ i, i, i, i, i, i, i, i });
834 read = MemOp(ByteOp{ O, I, O, I, O, O, O, O },
835 ByteOp{ O, O, O, O, O, O, O, O },
836 ByteOp{ x, x, x, x, x, x, x, x },
837 ByteOp{ o, o, o, o, o, o, o, o });
844 write = MemOp(ByteOp{ I, O, I, O, I, I, O, O },
845 ByteOp{ I, O, I, O, I, O, O, O },
846 ByteOp{ x, x, x, x, x, x, x, x },
847 ByteOp{ i, i, i, i, i, i, i, i });
849 read = MemOp(ByteOp{ O, I, O, I, I, O, O, O },
850 ByteOp{ O, O, O, O, I, O, O, O },
851 ByteOp{ x, x, x, x, x, x, x, x },
852 ByteOp{ o, o, o, o, o, o, o, o });
859 write = MemOp(ByteOp{ I, O, I, O, I, I, O, O },
860 ByteOp{ I, O, I, O, O, I, O, O },
861 ByteOp{ x, x, x, x, x, x, x, x },
862 ByteOp{ x, x, x, x, x, i, i, i });
864 read = MemOp(ByteOp{ O, I, O, I, O, O, O, O },
865 ByteOp{ O, O, O, O, I, O, O, O },
866 ByteOp{ x, x, x, x, x, x, x, x },
867 ByteOp{ o, o, o, o, o, o, o, o });
874 read = MemOp(ByteOp{ O, I, O, I, I, O, O, O },
875 ByteOp{ O, O, O, O, O, O, O, O },
876 ByteOp{ x, x, x, x, x, x, x, x },
877 ByteOp{ x, x, o, o, o, o, o, o });
879 write = MemOp(ByteOp{ I, O, I, O, I, I, O, O },
880 ByteOp{ I, I, I, x, x, x, x, x },
881 ByteOp{ x, x, x, x, x, x, x, x },
882 ByteOp{ I, I, i, i, i, i, i, i });
890 read = MemOp(ByteOp{ O, O, I, I, I, O, O, O },
891 ByteOp{ x, x, x, x, x, x, x, x },
892 ByteOp{ O, O, O, O, O, O, O, O },
893 ByteOp{ o, o, o, o, o, o, o, o });
901 read = MemOp(ByteOp{ O, O, I, I, O, O, O, O },
902 ByteOp{ x, x, x, x, x, x, x, x },
903 ByteOp{ x, x, x, x, x, x, a1, a0 },
904 ByteOp{ o, o, o, o, o, o, o, o });
909 static constexpr uint8_t fTimeOut = 200;
910 static constexpr uint8_t fStabDelay = 100;
911 static constexpr uint8_t fCmdExeDelay = 25;
912 static constexpr uint8_t fSynchLoops = 32;
913 static constexpr uint8_t fByteDelay = 0;
914 static constexpr uint8_t fPollValue = 0x53;
915 static constexpr uint8_t fPollIndex = 3;
916 static constexpr
unsigned fReadSize = 256;
917 static constexpr
unsigned fBlockSize = 256;
918 static constexpr
unsigned fChipEraseDelay = 9000;
919 static constexpr
unsigned fDelay = 10;
920 static constexpr
unsigned ENTER_PROGRAMMING_ATTEMPTS = 50;
922 uint8_t fCommandSequence;
923 uint8_t* fFlashPageCache;
924 uint32_t fFlashPageAddr;
925 unsigned fFlashPageSize;
927 uint8_t* fEEPROMPageCache;
928 uint32_t fEEPROMPageAddr;
929 unsigned fEEPROMPageSize;
931 bool fProgMode =
false;
935 Memory* findRegion(
MemType type)
937 for (Memory* mem = *Memory::head(); mem != NULL; mem = mem->next)
939 if (mem->type == type)
951 MEGA_SERIAL.write(&b, 1); MEGA_SERIAL.flush();
954 bool send(
unsigned char* data,
size_t len)
956 unsigned char buf[fBlockSize + 19 + 6];
959 buf[0] = MESSAGE_START;
960 buf[1] = fCommandSequence;
961 buf[2] = len / fBlockSize;
962 buf[3] = len % fBlockSize;
964 memcpy(buf+5, data, len);
968 for (i=0;i<5+len;i++)
969 buf[5+len] ^= buf[i];
973 for (i=0;i<len+6;i++) {
979 if (MEGA_SERIAL.write(buf, len+6) != len+6)
987 size_t serialRecv(uint8_t* buf,
size_t len = 1)
989 return MEGA_SERIAL.readBytes(buf, len);
992 int recv(
unsigned char* msg,
size_t maxsize)
994 enum states { sINIT, sSTART, sSEQNUM, sSIZE1, sSIZE2, sTOKEN, sDATA, sCSUM, sDONE } state = sSTART;
995 unsigned int msglen = 0;
996 unsigned int curlen = 0;
998 unsigned char c, checksum = 0;
1000 uint32_t tstart = millis();
1002 while (state != sDONE && !timeout)
1004 if (serialRecv(&c, 1) == 0)
1013 if (c == MESSAGE_START)
1016 checksum = MESSAGE_START;
1026 if (c == fCommandSequence)
1040 msglen = (unsigned)c * fBlockSize;
1045 msglen += (unsigned)c;
1056 if (curlen < maxsize)
1065 if ((curlen == 0) && (msg[0] == ANSWER_CKSUM_ERROR))
1071 if (curlen == msglen)
1091 if (millis() - tstart > MEGA_SERIAL_TIMEOUT)
1100 return (
int)(msglen+6);
1108 unsigned char buf[1], resp[32];
1115 buf[0] = CMD_SIGN_ON;
1119 status = recv(resp,
sizeof(resp));
1124 if ((resp[0] == CMD_SIGN_ON) && (resp[1] == STATUS_CMD_OK) &&
1128 unsigned siglen = resp[2];
1129 const char* sig =
"AVRISP_2";
1130 size_t len = strlen(sig);
1131 if (siglen >= len &&
1132 memcmp(resp + 3, sig, len) == 0)
1139 Serial.println(
"UNSUPPORTED BOOTLOADER");
1148 Serial.println(
"Can't communicate with device");
1159 else if (status == -1)
1163 Serial.println(
"Timeout");
1176 Serial.println(
"Error");
1186 int command(
unsigned char * buf,
size_t len,
size_t maxlen)
1191 #ifdef USE_AVR_DEBUG
1193 for (
size_t i = 0; i < len; i++)
1207 status = recv(buf,maxlen);
1218 if (buf[1] >= STATUS_CMD_TOUT && buf[1] < 0xa0)
1222 else if (buf[1] == STATUS_CMD_OK)
1226 else if (buf[1] == STATUS_CMD_FAILED)
1230 else if (buf[1] == STATUS_CMD_UNKNOWN)
1258 int getparm(
unsigned char parm,
unsigned char * value)
1260 unsigned char buf[32];
1262 buf[0] = CMD_GET_PARAMETER;
1265 if (command(buf, 2,
sizeof(buf)) < 0)
1273 int setparm_real(
unsigned char parm,
unsigned char value)
1275 unsigned char buf[32];
1277 buf[0] = CMD_SET_PARAMETER;
1281 if (command(buf, 3,
sizeof(buf)) < 0)
1288 int setparm(
unsigned char parm,
unsigned char value)
1291 unsigned char current_value;
1293 res = getparm(parm, ¤t_value);
1294 if (res == 0 && value == current_value)
1298 return setparm_real(parm, value);
1301 int getparm2(
unsigned char parm,
unsigned int * value)
1303 unsigned char buf[32];
1305 buf[0] = CMD_GET_PARAMETER;
1308 if (command(buf, 2,
sizeof(buf)) < 0)
1312 *value = ((unsigned)buf[2] << 8) | buf[3];
1316 int setparm2(
unsigned char parm,
unsigned int value)
1318 unsigned char buf[32];
1320 buf[0] = CMD_SET_PARAMETER;
1322 buf[2] = value >> 8;
1325 if (command(buf, 4,
sizeof(buf)) < 0)
1334 unsigned char buf[16];
1336 buf[0] = CMD_ENTER_PROGMODE_ISP;
1338 buf[2] = fStabDelay;
1339 buf[3] = fCmdExeDelay;
1340 buf[4] = fSynchLoops;
1341 buf[5] = fByteDelay;
1342 buf[6] = fPollValue;
1343 buf[7] = fPollIndex;
1344 pgmEnableOp.setBits(buf+8);
1345 buf[10] = buf[11] = 0;
1347 return command(buf, 12,
sizeof(buf));
1352 unsigned char maj, min, hdw;
1354 if (getparm(PARAM_HW_VER, &hdw) == 0 &&
1355 getparm(PARAM_SW_MAJOR, &maj) == 0 &&
1356 getparm(PARAM_SW_MINOR, &min) == 0)
1366 int readByte(Memory& mem, uint32_t addr, uint8_t* value)
1377 uint32_t paddr = 0UL;
1378 uint32_t* paddr_ptr = NULL;
1379 unsigned pagesize = 0;
1380 uint8_t *cache_ptr = NULL;
1384 pagesize = fFlashPageSize;
1385 paddr = addr & ~(pagesize - 1);
1386 paddr_ptr = &fFlashPageAddr;
1387 cache_ptr = fFlashPageCache;
1391 pagesize = mem.page_size;
1394 paddr = addr & ~(pagesize - 1);
1395 paddr_ptr = &fEEPROMPageAddr;
1396 cache_ptr = fEEPROMPageCache;
1399 if (paddr == *paddr_ptr)
1401 *value = cache_ptr[addr & (pagesize - 1)];
1405 if (readPage(mem, pagesize, paddr, pagesize) < 0)
1409 memcpy(cache_ptr, &mem.buf[paddr], pagesize);
1410 *value = cache_ptr[addr & (pagesize - 1)];
1416 buf[0] = CMD_READ_FUSE_ISP;
1421 buf[0] = CMD_READ_FUSE_ISP;
1426 buf[0] = CMD_READ_FUSE_ISP;
1431 buf[0] = CMD_READ_LOCK_ISP;
1435 buf[0] = CMD_READ_SIGNATURE_ISP;
1439 buf[0] = CMD_READ_SIGNATURE_ISP;
1447 MemOp& op = mem.read;
1448 memset(buf + 1, 0, 5);
1453 op.setBits(buf + 2);
1455 if ((pollidx = op.getOutputIndex()) == -1)
1459 buf[1] = pollidx + 1;
1460 op.setAddress(buf + 2, addr);
1462 int result = command(buf, 6,
sizeof(buf));
1471 int readPage(Memory& mem,
unsigned page_size,
unsigned addr,
unsigned n_bytes)
1475 unsigned block_size, hiaddr, addrshift, use_ext_addr;
1476 unsigned maxaddr = addr + n_bytes;
1477 uint8_t commandbuf[4];
1483 page_size = fBlockSize;
1484 MemOp& readOp = mem.invalid;
1494 commandbuf[0] = CMD_READ_FLASH_ISP;
1495 readOp = fRegions.flash.read_lo;
1497 use_ext_addr = (1U << 31);
1501 commandbuf[0] = CMD_READ_EEPROM_ISP;
1502 readOp = fRegions.eeprom.read;
1509 if (!readOp.isValid())
1513 readOp.setBits(cmds);
1514 commandbuf[3] = cmds[0];
1516 for (; addr < maxaddr; addr += page_size)
1518 if ((maxaddr - addr) < page_size)
1519 block_size = maxaddr - addr;
1521 block_size = page_size;
1523 memcpy(buf, commandbuf,
sizeof(commandbuf));
1525 buf[1] = block_size >> 8;
1526 buf[2] = block_size & 0xff;
1528 if (hiaddr != (addr & ~0xFFFF))
1530 hiaddr = addr & ~0xFFFF;
1531 if (loadAddress(use_ext_addr | (addr >> addrshift)) < 0)
1535 result = command(buf, 4,
sizeof(buf));
1540 memcpy(&mem.buf[addr], &buf[2], block_size);
1545 int loadAddress(
unsigned int addr)
1547 unsigned char buf[16];
1551 buf[0] = CMD_LOAD_ADDRESS;
1552 buf[1] = (addr >> 24) & 0xff;
1553 buf[2] = (addr >> 16) & 0xff;
1554 buf[3] = (addr >> 8) & 0xff;
1555 buf[4] = addr & 0xff;
1557 return command(buf, 5,
sizeof(buf));
1562 unsigned char buf[16];
1564 buf[0] = CMD_CHIP_ERASE_ISP;
1565 buf[1] = fChipEraseDelay / 1000;
1567 chipEraseOp.setBits(buf+3);
1568 return (command(buf, 7,
sizeof(buf)) >= 0) ? 0 : -1;
1571 int writePage(Memory& mem,
unsigned page_size, uint32_t addr,
unsigned n_bytes)
1573 unsigned block_size;
1576 unsigned use_ext_addr;
1577 uint32_t maxaddr = addr + n_bytes;
1578 uint8_t commandbuf[10];
1582 MemOp& rop = mem.invalid;
1583 MemOp& wop = mem.invalid;
1586 page_size = fBlockSize;
1594 commandbuf[0] = CMD_PROGRAM_FLASH_ISP;
1601 if (mem.load_ext_addr.isValid())
1603 use_ext_addr = (1U << 31);
1608 commandbuf[0] = CMD_PROGRAM_EEPROM_ISP;
1610 commandbuf[4] = mem.delay;
1624 if (mem.mode & 0x01)
1626 commandbuf[3] = mem.mode | 0x80;
1628 if (!mem.loadpage_lo.isValid())
1632 mem.loadpage_lo.setBits(cmds);
1633 commandbuf[5] = cmds[0];
1635 if (!mem.writepage.isValid())
1639 mem.writepage.setBits(cmds);
1640 commandbuf[6] = cmds[0];
1646 commandbuf[3] = mem.mode | 0x80;
1653 commandbuf[5] = cmds[0];
1663 commandbuf[7] = cmds[0];
1665 commandbuf[8] = mem.readback_p1;
1666 commandbuf[9] = mem.readback_p2;
1669 for (; addr < maxaddr; addr += page_size)
1671 if ((maxaddr - addr) < page_size)
1672 block_size = maxaddr - addr;
1674 block_size = page_size;
1676 memcpy(buf,commandbuf,
sizeof(commandbuf));
1678 buf[1] = block_size >> 8;
1679 buf[2] = block_size & 0xff;
1681 if (last_addr == UINT_MAX || last_addr + block_size != addr)
1683 if (loadAddress(use_ext_addr | (addr >> addrshift)) < 0)
1688 memcpy(buf + 10, &mem.buf[addr], block_size);
1690 result = command(buf, block_size + 10,
sizeof(buf));
1708 while (addr < mem.size)
1710 unsigned minpagesize = (mem.page_size > 0) ? mem.page_size : 16;
1713 if (readPage(mem, mem.page_size, addr, mem.page_size) < 0)
1718 for (
int i = 0; i < minpagesize; i += 1)
1720 if (addr+i < mem.size && readByte(mem, addr+i, &mem.buf[addr+i]) < 0)
1724 addr += minpagesize;
1736 bool lastRowRepeats =
false;
1737 bool lastRowRepeatPrinted =
false;
1738 uint8_t printedRow[16];
1739 memset(printedRow, 0xFF,
sizeof(printedRow));
1740 int progressIndex = 0;
1741 static constexpr
char progress[] = {
'|',
'/',
'-',
'\\' };
1742 printf(
"=======\n");
1743 uint32_t startTime = millis();
1744 while (addr < mem.size)
1746 unsigned minpagesize = (mem.page_size > 0) ? mem.page_size : 16;
1749 if (readPage(mem, mem.page_size, addr, mem.page_size) < 0)
1754 for (
int i = 0; i < minpagesize; i += 1)
1756 if (addr+i < mem.size && readByte(mem, addr+i, &mem.buf[addr+i]) < 0)
1760 for (
int i = 0; i < minpagesize; i += 16)
1762 unsigned rowsize = 16;
1763 if (addr+i+16 >= mem.size)
1764 rowsize = mem.size - addr+i;
1765 bool rowRepeats = (addr+i > 0) ? memcmp(&mem.buf[addr+i], printedRow, rowsize) == 0 :
false;
1768 lastRowRepeats =
false;
1769 lastRowRepeatPrinted =
false;
1771 if (!lastRowRepeats)
1776 memcpy(printedRow, &mem.buf[addr+i],
sizeof(printedRow));
1777 printf(
"%08x ", addr+i);
1778 for (x = 0; x < 16 && addr+i+x < mem.size; x++)
1780 printf(
"%02x ", printedRow[x]);
1781 if (((x+1) % 8) == 0) printf(
" ");
1786 if (((++x) % 8) == 0) printf(
" ");
1789 for (x = 0; x < 16 && addr+i+x < mem.size; x++)
1791 uint8_t ch = printedRow[x];
1792 printf(
"%c", ((ch >= 32 && ch <= 127) ? ch :
'.'));
1798 lastRowRepeats =
true;
1801 else if (!lastRowRepeatPrinted)
1804 lastRowRepeatPrinted =
true;
1807 addr += minpagesize;
1808 if (lastRowRepeats && !mem.loaded)
1810 printf(
"\r%c\r", progress[progressIndex++>>1]); fflush(stdout);
1811 if (progressIndex ==
sizeof(progress)*2)
1815 printf(
"\r%08x\n", mem.size);
1816 printf(
"=======\n");
1817 uint32_t stopTime = millis();
1818 printf(
"elapsed : %u\n", stopTime - startTime);
1823 int parseHexLine(
char* line, uint8_t* bytes,
unsigned &addr,
unsigned &num,
int &status)
1825 int sum, len, cksum;
1831 if (strlen(line) < 11)
1834 if (!sscanf(ptr,
"%02x", &len))
1837 if (strlen(line) < (11 + (len * 2)))
1839 if (!sscanf(ptr,
"%04x", &addr))
1842 if (!sscanf(ptr,
"%02x", &status))
1845 sum = (len & 255) + ((addr >> 8) & 255) + (addr & 255) + (status & 255);
1849 if (!sscanf(ptr,
"%02x", &data))
1851 bytes[num] = (uint8_t)data;
1855 if (num >= fBlockSize)
1858 if (!sscanf(ptr,
"%02x", &cksum))
1860 if (((sum & 255) + (cksum & 255)) & 255)
1865 bool writeHexString(Memory& mem,
const char* str,
unsigned* lineno)
1871 char line[fBlockSize];
1872 const char* ch = str;
1877 if (!mem.page_size && !mem.loaded && !
readMemory(mem))
1879 unsigned lastPageRead = ~0u;
1880 while ((c = *ch++) !=
'\0')
1883 if (c ==
'\n' || c ==
'\r')
1888 uint8_t bytes[fBlockSize];
1889 if (linei != 0 && parseHexLine(line, bytes, addr, n, status))
1894 for (
unsigned i = 0; i <= (n-1); i++)
1896 if (mem.page_size > 0)
1898 unsigned pageNumber = addr / mem.page_size;
1899 if (!mem.loaded && lastPageRead != pageNumber)
1901 unsigned pageAddr = pageNumber * mem.page_size;
1902 if (!readPage(mem, mem.page_size, pageAddr, mem.page_size))
1904 lastPageRead = pageNumber;
1905 progressCallback((
double)addr / (
double)mem.size);
1908 mem.set(addr, bytes[i]);
1912 else if (status == 1)
1917 else if (status == 2)
1930 else if (linei <
sizeof(line)-1)
1944 if (mem.page_size != 0)
1946 for (
unsigned addr = 0; addr < mem.size; addr += mem.page_size)
1948 if (mem.isPageTagged(addr))
1955 for (
unsigned addr = 0; addr < mem.size; addr++)
1957 if (mem.isAddressTagged(addr))
1965 if (mem.page_size == 0)
1978 unsigned maxChangedPageAddr = 0;
1979 for (
unsigned addr = 0; addr < mem.size; addr += mem.page_size)
1981 if (mem.isPageTagged(addr))
1982 maxChangedPageAddr = addr;
1985 for (
unsigned addr = 0; addr < maxChangedPageAddr; addr += mem.page_size)
1987 mem.tagPage(addr,
true);
1993 uint8_t* verifyBuffer = (verify) ? (uint8_t*)alloca(mem.page_size) : NULL;
1994 for (
unsigned addr = 0; addr < mem.size; addr += mem.page_size)
1996 if (mem.isPageTagged(addr))
1998 if (writePage(mem, 0, addr, mem.page_size) < 0)
2004 memcpy(verifyBuffer, &mem.buf[addr], mem.page_size);
2005 if (readPage(mem, mem.page_size, addr, mem.page_size) < 0)
2009 if (memcmp(verifyBuffer, &mem.buf[addr], mem.page_size) != 0)
2014 progressCallback((
double)addr / (
double)mem.size);
2021 void progressCallback(
double percent)
2023 if (fProgress != NULL)