RSeries astromech firmware
AVRMega2560Programmer.h
Go to the documentation of this file.
1 #ifndef AVRMega2560Programmer_h
2 #define AVRMega2560Programmer_h
3 
4 #include "core/SetupEvent.h"
5 //#define USE_AVR_DEBUG
6 #ifdef USE_AVR_DEBUG
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)
11 #else
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)
16 #endif
17 
33 {
34 public:
35  enum MemType
36  {
46  };
47 
49  {
52  };
53 
54  AVRMega2560Programmer(uint8_t resetPin, HardwareSerial& port) :
55  fResetPin(resetPin),
56  fFlashPageCache(NULL),
57  fEEPROMPageCache(NULL)
58  {
59  }
60 
61  virtual void setup() override
62  {
63  DEBUG_PRINT("SETTING RESET HIGH pin="); DEBUG_PRINTLN(fResetPin); delay(200);
64  pinMode(fResetPin, OUTPUT);
65  digitalWrite(fResetPin, HIGH);
66  DEBUG_PRINTLN("SET RESET HIGH"); delay(200);
67  }
68 
69  typedef void (*ProgressProc)(double percent);
70  void setProgress(ProgressProc progressFunc)
71  {
72  fProgress = progressFunc;
73  }
74 
75  void block()
76  {
77  digitalWrite(fResetPin, LOW);
78  }
79 
80  void release()
81  {
82  digitalWrite(fResetPin, HIGH);
83  }
84 
85  void reset()
86  {
87  /* Perform Wiring programming mode RESET. */
88  /* This effectively *releases* both DTR and RTS. */
89  /* i.e. both DTR and RTS rise to a HIGH logic level */
90  /* since they are active LOW signals. */
91  digitalWrite(fResetPin, LOW);
92  delay(50);
93 
94  /* After releasing for 50 milliseconds, DTR and RTS */
95  /* are asserted (i.e. logic LOW) again. */
96  digitalWrite(fResetPin, HIGH);
97  delay(50);
98 
99  while (MEGA_SERIAL.available())
100  MEGA_SERIAL.read();
101  }
102 
104  {
105  if (fProgMode)
106  return true;
107  AVR_DEBUG_PRINTLN("Attempting to enter ICSP programming mode ..."); delay(200);
108 
109  while (MEGA_SERIAL.available())
110  MEGA_SERIAL.read();
111 
112  unsigned timeout = 0;
113  fCommandSequence = 1;
114  fFlashPageAddr = ~0u;
115  fFlashPageSize = fRegions.flash.page_size;
116  fFlashPageCache = (uint8_t*)ps_malloc(fFlashPageSize);
117 
118  fEEPROMPageAddr = ~0u;
119  fEEPROMPageSize = fRegions.eeprom.page_size;
120  fEEPROMPageCache = (uint8_t*)ps_malloc(fEEPROMPageSize);
121 
122  fProgMode = false;
123  for (Memory* mem = *Memory::head(); mem != NULL; mem = mem->next)
124  {
125  mem->init();
126  }
127  for (;;)
128  {
129  // regrouping pause
130  delay(100);
131 
132  reset();
133 
134  // Need more time for the boot loader to start
135  delay(50);
136 
137  if (getsync() < 0)
138  {
139  if (timeout++ >= ENTER_PROGRAMMING_ATTEMPTS)
140  {
142  AVR_DEBUG_PRINTLN("Failed to enter programming mode. Double-check wiring!");
143  return false;
144  }
145  AVR_DEBUG_PRINTLN("RETRYING TO SYNC");
146  continue;
147  }
148 
149  #ifdef USE_AVR_DEBUG
150  if (display() < 0)
151  {
152  AVR_DEBUG_PRINTLN("FAILED TO RETRIEVE DEVICE INFO");
153  continue;
154  }
155  #endif
156  if (programEnable() > 0)
157  {
158  break;
159  }
160  AVR_DEBUG_PRINTLN("FAILED TO ENTER PROGRAMMING MODE");
161  }
163  AVR_DEBUG_PRINTLN("Entered programming mode OK.");
164  fProgMode = true;
165  return true;
166  }
167 
169  {
170  unsigned char buf[8];
171  buf[0] = CMD_LEAVE_PROGMODE_ISP;
172  buf[1] = 1; // preDelay;
173  buf[2] = 1; // postDelay;
174 
175  command(buf, 3, sizeof(buf));
176 
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)
182  {
183  mem->dispose();
184  }
185  fProgMode = false;
186  }
187 
188  bool dumpMemory(MemType type)
189  {
190  Memory* mem = findRegion(type);
191  return (mem != NULL) ? dumpMemory(*mem) : false;
192  }
193 
194  uint8_t* readMemory(MemType type, size_t* size)
195  {
196  if (size != NULL)
197  *size = 0;
198  Memory* mem = findRegion(type);
199  if (mem != NULL && readMemory(*mem))
200  {
201  if (size != NULL)
202  *size = mem->size;
203  return mem->buf;
204  }
205  return NULL;
206  }
207 
208  bool writeHexString(MemType type, const char* hexString, unsigned* lineno = NULL)
209  {
210  if (lineno != NULL)
211  *lineno = 0;
212  Memory* mem = findRegion(type);
213  return (mem != NULL) ? writeHexString(*mem, hexString, lineno) : false;
214  }
215 
216  bool writeMemory(MemType type, bool verify = true)
217  {
218  Memory* mem = findRegion(type);
219  return (mem != NULL) ? writeMemory(*mem, verify) : false;
220  }
221 
223  {
224  Memory* mem = findRegion(type);
225  return (mem != NULL) ? hasMemoryChanged(*mem) : false;
226  }
227 
228 private:
229  enum
230  {
231  CMD_SIGN_ON = 0x01,
232  CMD_SET_PARAMETER = 0x02,
233  CMD_GET_PARAMETER = 0x03,
234  CMD_SET_DEVICE_PARAMETERS = 0x04,
235  CMD_OSCCAL = 0x05,
236  CMD_LOAD_ADDRESS = 0x06,
237  CMD_FIRMWARE_UPGRADE = 0x07,
238 
239  // *****************[ STK ISP command constants ]******************************
240 
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,
255 
256  // *** XPROG command constants ***
257  CMD_XPROG = 0x50,
258  CMD_XPROG_SETMODE = 0x51,
259 
260  // *****************[ STK status constants ]***************************
261 
262  // Success
263  STATUS_CMD_OK = 0x00,
264 
265  // Warnings
266  STATUS_CMD_TOUT = 0x80,
267  STATUS_RDY_BSY_TOUT = 0x81,
268  STATUS_SET_PARAM_MISSING = 0x82,
269 
270  // Errors
271  STATUS_CMD_FAILED = 0xC0,
272  STATUS_CKSUM_ERROR = 0xC1,
273  STATUS_CMD_UNKNOWN = 0xC9,
274  STATUS_CMD_ILLEGAL_PARAMETER = 0xCA,
275 
276  // Status
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,
283 
284  MESSAGE_START = 0x1B,
285  TOKEN = 0x0E,
286 
287  ANSWER_CKSUM_ERROR = 0xB0,
288 
289  // Error codes
290  XPRG_ERR_OK = 0,
291  XPRG_ERR_FAILED = 1,
292  XPRG_ERR_COLLISION = 2,
293  XPRG_ERR_TIMEOUT = 3,
294 
295  PARAM_HW_VER = 0x90,
296  PARAM_SW_MAJOR = 0x91,
297  PARAM_SW_MINOR = 0x92,
298  };
299 
300  // #define BITOP (BitOp[])
301  enum BitOp
302  {
303  O, /* the bit is always clear on input as well as output */
304  I, /* the bit is always set on input as well as output */
305  o, /* the bit is an output data bit */
306  a, /* the bit is an address bit, the bit-number matches this bit */
307  /* specifier's position within the current instruction byte */
308  i, /* the bit is an input data bit */
309  x, /* the bit is ignored on input and output */
310  a0, /* the bit is the Nth address bit, bit-number = N, i.e., a16 */
311  a1, /* is address bit 12 on input, a0 is address bit 0. */
312  a2,
313  a3,
314  a4,
315  a5,
316  a6,
317  a7,
318  a8,
319  a9,
320  a10,
321  a11,
322  a12,
323  a13,
324  a14,
325  a15,
326  a16
327  };
328 
329  struct ByteOp
330  {
331  union
332  {
333  struct
334  {
335  BitOp op1;
336  BitOp op2;
337  BitOp op3;
338  BitOp op4;
339  BitOp op5;
340  BitOp op6;
341  BitOp op7;
342  BitOp op8;
343  };
344  BitOp arr[8];
345  };
346  };
347 
348  class MemOp
349  {
350  public:
351  MemOp() : fValid(false)
352  {
353  }
354 
355  MemOp(ByteOp byte1, ByteOp byte2)
356  {
357  const ByteOp descs[] = { byte1, byte2 };
358  parseDescription(sizeof(descs)/sizeof(descs[0]), descs);
359  }
360 
361  MemOp(ByteOp byte1, ByteOp byte2,
362  ByteOp byte3, ByteOp byte4)
363  {
364  const ByteOp descs[] = { byte1, byte2, byte3, byte4 };
365  parseDescription(sizeof(descs)/sizeof(descs[0]), descs);
366  }
367 
368  inline bool isValid() const
369  {
370  return fValid;
371  }
372 
373  void setBits(uint8_t* cmd)
374  {
375  for (int i = 0; i < 32; i++)
376  {
377  if (fBit[i].fOp == kValue)
378  {
379  int j = 3 - i / 8;
380  int bit = i % 8;
381  uint8_t mask = 1 << bit;
382  if (fBit[i].fValue)
383  cmd[j] |= mask;
384  else
385  cmd[j] &= ~mask;
386  }
387  }
388  }
389 
390  void setAddress(uint8_t* cmd, uint32_t addr)
391  {
392  for (int i = 0; i < 32; i++)
393  {
394  if (fBit[i].fOp == kAddress)
395  {
396  int j = 3 - i / 8;
397  int bit = i % 8;
398  uint8_t mask = 1 << bit;
399  uint32_t value = addr >> fBit[i].fNum & 0x01;
400  if (value)
401  cmd[j] |= mask;
402  else
403  cmd[j] &= ~mask;
404  }
405  }
406  }
407 
408  void setInput(uint8_t* cmd, uint32_t data)
409  {
410  for (int i = 0; i < 32; i++)
411  {
412  if (fBit[i].fOp == kInput)
413  {
414  int j = 3 - i / 8;
415  int bit = i % 8;
416  uint8_t mask = 1 << bit;
417  uint8_t value = data >> fBit[i].fNum & 0x01;
418  if (value)
419  cmd[j] |= mask;
420  else
421  cmd[j] &= ~mask;
422  }
423  }
424  }
425 
426  void getOutput(uint8_t* res, uint8_t* data)
427  {
428  for (int i = 0; i < 32; i++)
429  {
430  if (fBit[i].fOp == kOutput)
431  {
432  int j = 3 - i / 8;
433  int bit = i % 8;
434  uint8_t mask = 1 << bit;
435  uint8_t value = ((res[j] & mask) >> bit) & 0x01;
436  value = value << fBit[i].fNum;
437  if (value)
438  *data |= value;
439  else
440  *data &= ~value;
441  }
442  }
443  }
444 
445  int getOutputIndex()
446  {
447  for (int i = 0; i < 32; i++)
448  {
449  if (fBit[i].fOp == kOutput)
450  return 3 - i / 8;
451  }
452  return -1;
453  }
454 
455  #ifdef USE_AVR_DEBUG
456  void printDescriptor(const char* name)
457  {
458  static const char* opname[] = {
459  "IGNORE",
460  "VALUE",
461  "ADDRESS",
462  "INPUT",
463  "OUTPUT"
464  };
465  for (int i = 31; i >= 0; i--)
466  {
467  //----------- -------- -------- ----- -----
468  //12345678901 12345678 12345678 12345 12345
469  printf("%-11s %8d %8s %5d %5d\n",
470  name, i, opname[fBit[i].fOp], fBit[i].fNum, fBit[i].fValue);
471  name = "";
472  }
473  }
474  #endif
475 
476  private:
477  enum Op
478  {
479  kIgnore,
480  kValue,
481  kAddress,
482  kInput,
483  kOutput
484  };
485  struct Bit
486  {
487  Op fOp;
488  uint8_t fNum;
489  uint8_t fValue;
490  };
491  Bit fBit[32];
492  bool fValid = false;
493 
494  bool parseDescription(size_t count, const ByteOp* byteops)
495  {
496  int bit = 32;
497  fValid = false;
498  for (unsigned wi = 0; wi < count; wi++)
499  {
500  const BitOp* op = byteops[wi].arr;
501  for (unsigned bi = 0; bi < 8; bi++)
502  {
503  bit--;
504  if (bit < 0)
505  return false;
506 
507  BitOp bitop = op[bi];
508  switch (bitop)
509  {
510  case I:
511  fBit[bit].fOp = kValue;
512  fBit[bit].fValue = 1;
513  fBit[bit].fNum = bit % 8;
514  break;
515  case O:
516  fBit[bit].fOp = kValue;
517  fBit[bit].fValue = 0;
518  fBit[bit].fNum = bit % 8;
519  break;
520  case x:
521  fBit[bit].fOp = kIgnore;
522  fBit[bit].fValue = 0;
523  fBit[bit].fNum = bit % 8;
524  break;
525  case a:
526  fBit[bit].fOp = kAddress;
527  fBit[bit].fValue = 0;
528  fBit[bit].fNum = 8 * (bit / 8) + bit % 8;
529  break;
530  case i:
531  fBit[bit].fOp = kInput;
532  fBit[bit].fValue = 0;
533  fBit[bit].fNum = bit % 8;
534  break;
535  case o:
536  fBit[bit].fOp = kOutput;
537  fBit[bit].fValue = 0;
538  fBit[bit].fNum = bit % 8;
539  break;
540  default:
541  fBit[bit].fNum = (uint8_t)bitop-(uint8_t)BitOp::a0;
542  fBit[bit].fOp = kAddress;
543  fBit[bit].fValue = 0;
544  break;
545  }
546  }
547  }
548  fValid = true;
549  return true;
550  }
551  };
552 
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 });
555 
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 });
558 
559  struct Memory
560  {
561  MemType type;
562  bool paged = false;
563  bool loaded = false;
564  unsigned size = 0;
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;
571 
572  unsigned mode = 0;
573  unsigned delay = 0;
574  unsigned blocksize = 0;
575  unsigned readsize = 0;
576 
577  MemOp invalid;
578  MemOp read;
579  MemOp write;
580  MemOp read_lo;
581  MemOp read_hi;
582  MemOp write_lo;
583  MemOp write_hi;
584  MemOp loadpage_lo;
585  MemOp loadpage_hi;
586  MemOp load_ext_addr;
587  MemOp writepage;
588 
589  uint8_t* buf = NULL;
590  uint32_t* tags = NULL;
591  uint32_t* page_tags = NULL;
592  Memory* next;
593 
594  Memory(MemType memtype) :
595  type(memtype),
596  next(NULL)
597  {
598  if (*head() == NULL)
599  *head() = this;
600  if (*tail() != NULL)
601  (*tail())->next = this;
602  *tail() = this;
603  }
604 
605  void init()
606  {
607  buf = (uint8_t*)ps_malloc(size);
608  memset(buf, 0xFF, size);
609 
610  unsigned tagsize = (size/32+1)*sizeof(uint32_t);
611  tags = (uint32_t*)ps_malloc(tagsize);
612  memset(tags, 0, tagsize);
613 
614  if (page_size > 0)
615  {
616  tagsize = ((size/page_size)/32+1)*sizeof(uint32_t);
617  page_tags = (uint32_t*)ps_malloc(tagsize);
618  memset(page_tags, 0, tagsize);
619  }
620  }
621 
622  void dispose()
623  {
624  if (buf != NULL)
625  {
626  free(buf);
627  buf = NULL;
628  }
629  if (tags != NULL)
630  {
631  free(tags);
632  tags = NULL;
633  }
634  if (page_tags != NULL)
635  {
636  free(page_tags);
637  page_tags = NULL;
638  }
639  }
640 
641  void tagAddress(unsigned addr, bool tag)
642  {
643  if (addr < size)
644  {
645  if (tag)
646  tags[addr / 32] |= (1 << (addr % 32));
647  else
648  tags[addr / 32] &= ~(1 << (addr % 32));
649  }
650  }
651 
652  void tagPage(unsigned addr, bool tag)
653  {
654  if (page_size > 0 && addr < size)
655  {
656  unsigned pageAddr = addr / page_size;
657  if (tag)
658  page_tags[pageAddr / 32] |= (1 << (pageAddr % 32));
659  else
660  page_tags[pageAddr / 32] &= ~(1 << (pageAddr % 32));
661  }
662  }
663 
664  bool isAddressTagged(unsigned addr)
665  {
666  return (addr < size) ? ((tags[addr / 32] & (1 << (addr % 32))) != 0) : false;
667  }
668 
669  bool isPageTagged(unsigned addr)
670  {
671  if (page_size > 0 && addr < size)
672  {
673  unsigned pageAddr = addr / page_size;
674  return ((page_tags[pageAddr / 32] & (1 << (pageAddr % 32))) != 0);
675  }
676  return false;
677  }
678 
679  uint8_t get(unsigned addr)
680  {
681  if (addr < size)
682  return buf[addr];
683  return 0xFF;
684  }
685 
686  void set(unsigned addr, uint8_t byte)
687  {
688  if (addr < size && buf[addr] != byte)
689  {
690  buf[addr] = byte;
691  tagAddress(addr, true);
692  tagPage(addr, true);
693  }
694  }
695 
696  static Memory** head()
697  {
698  static Memory* sHead;
699  return &sHead;
700  }
701 
702  static Memory** tail()
703  {
704  static Memory* sTail;
705  return &sTail;
706  }
707 
708  #ifdef USE_AVR_DEBUG
709  void printDescription()
710  {
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);
718 
719  printf(" Memory Ops:\n");
720  printf(" Operation Inst Bit Bit Type Bitno Value\n");
721  printf(" ----------- -------- -------- ----- -----\n");
722  if (read.isValid())
723  read.printDescriptor("READ");
724  }
725  #endif
726  };
727 
728  struct MemoyRegions
729  {
730  struct Flash : Memory
731  {
732  Flash() : Memory(kFlash)
733  {
734  paged = true;
735  size = 262144;
736  page_size = 256;
737  num_pages = 1024;
738  min_write_delay = 4500;
739  max_write_delay = 4500;
740  readback_p1 = 0x00;
741  readback_p2 = 0x00;
742 
743  mode = 0x41;
744  delay = 10;
745  blocksize = 256;
746  readsize = 256;
747 
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 });
752 
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 });
757 
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 });
762 
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 });
767 
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 });
772 
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 });
777  }
778  } flash;
779 
780  struct EEPROM : Memory {
781  EEPROM() : Memory(kEEPROM)
782  {
783  paged = false;
784  page_size = 8;
785  size = 4096;
786  min_write_delay = 9000;
787  max_write_delay = 9000;
788  readback_p1 = 0x00;
789  readback_p2 = 0x00;
790 
791  mode = 0x41;
792  delay = 10;
793  blocksize = 8;
794  readsize = 256;
795 
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 });
800 
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 });
805 
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});
810 
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});
815  }
816  } eeprom;
817 
818  struct Fuse : Memory {
819  Fuse(MemType type) : Memory(type)
820  {
821  size = 1;
822  min_write_delay = 9000;
823  max_write_delay = 9000;
824  }
825  };
826  struct LFuse : Fuse {
828  {
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 });
833 
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 });
838  }
839  } lfuse;
840 
841  struct HFuse : Fuse {
843  {
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 });
848 
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 });
853  }
854  } hfuse;
855 
856  struct EFuse : Fuse {
858  {
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 });
863 
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 });
868  }
869  } efuse;
870 
871  struct Lock : Fuse {
873  {
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 });
878 
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 });
883  }
884  } lock;
885 
886  struct Calibration : Memory {
887  Calibration() : Memory(kLock)
888  {
889  size = 1;
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 });
894  }
895  } calibration;
896 
897  struct Signature : Memory {
898  Signature() : Memory(kSignature)
899  {
900  size = 3;
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 });
905  }
906  } signature;
907  } fRegions;
908 
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;
921  uint8_t fResetPin;
922  uint8_t fCommandSequence;
923  uint8_t* fFlashPageCache;
924  uint32_t fFlashPageAddr;
925  unsigned fFlashPageSize;
926 
927  uint8_t* fEEPROMPageCache;
928  uint32_t fEEPROMPageAddr;
929  unsigned fEEPROMPageSize;
930 
931  bool fProgMode = false;
932  BootLoaderType fBootlLoader = kUnknown;
933  ProgressProc fProgress = NULL;
934 
935  Memory* findRegion(MemType type)
936  {
937  for (Memory* mem = *Memory::head(); mem != NULL; mem = mem->next)
938  {
939  if (mem->type == type)
940  {
941  return mem;
942  }
943  }
944  return NULL;
945  }
946 
947  // *****************[ STK ISP command constants ]******************************
948  void send(uint8_t b)
949  {
950  //Serial.print("SEND b="); Serial.println(b, HEX);
951  MEGA_SERIAL.write(&b, 1); MEGA_SERIAL.flush();
952  }
953 
954  bool send(unsigned char* data, size_t len)
955  {
956  unsigned char buf[fBlockSize + 19 + 6]; // max MESSAGE_BODY of 275 bytes, 6 bytes overhead
957  int i;
958 
959  buf[0] = MESSAGE_START;
960  buf[1] = fCommandSequence;
961  buf[2] = len / fBlockSize;
962  buf[3] = len % fBlockSize;
963  buf[4] = TOKEN;
964  memcpy(buf+5, data, len);
965 
966  // calculate the XOR checksum
967  buf[5+len] = 0;
968  for (i=0;i<5+len;i++)
969  buf[5+len] ^= buf[i];
970 
971  #ifdef USE_AVR_DEBUG
972  AVR_DEBUG_PRINT("AVR.send(");
973  for (i=0;i<len+6;i++) {
974  AVR_DEBUG_PRINT_HEX(buf[i]);
975  AVR_DEBUG_PRINT(" ");
976  }
978  #endif
979  if (MEGA_SERIAL.write(buf, len+6) != len+6)
980  {
981  DEBUG_PRINTLN("failed to send command to serial port");
982  return false;
983  }
984  return true;
985  }
986 
987  size_t serialRecv(uint8_t* buf, size_t len = 1)
988  {
989  return MEGA_SERIAL.readBytes(buf, len);
990  }
991 
992  int recv(unsigned char* msg, size_t maxsize)
993  {
994  enum states { sINIT, sSTART, sSEQNUM, sSIZE1, sSIZE2, sTOKEN, sDATA, sCSUM, sDONE } state = sSTART;
995  unsigned int msglen = 0;
996  unsigned int curlen = 0;
997  int timeout = 0;
998  unsigned char c, checksum = 0;
999 
1000  uint32_t tstart = millis();
1001 
1002  while (state != sDONE && !timeout)
1003  {
1004  if (serialRecv(&c, 1) == 0)
1005  goto timedout;
1007  checksum ^= c;
1008 
1009  switch (state)
1010  {
1011  case sSTART:
1012  AVR_DEBUG_PRINT("hoping for start token...");
1013  if (c == MESSAGE_START)
1014  {
1015  AVR_DEBUG_PRINTLN("got it");
1016  checksum = MESSAGE_START;
1017  state = sSEQNUM;
1018  }
1019  else
1020  {
1021  AVR_DEBUG_PRINTLN("sorry");
1022  }
1023  break;
1024  case sSEQNUM:
1025  AVR_DEBUG_PRINT("hoping for sequence...");
1026  if (c == fCommandSequence)
1027  {
1028  AVR_DEBUG_PRINTLN("got it, incrementing");
1029  state = sSIZE1;
1030  fCommandSequence++;
1031  }
1032  else
1033  {
1034  AVR_DEBUG_PRINT("sorry");
1035  state = sSTART;
1036  }
1037  break;
1038  case sSIZE1:
1039  AVR_DEBUG_PRINTLN("hoping for size LSB");
1040  msglen = (unsigned)c * fBlockSize;
1041  state = sSIZE2;
1042  break;
1043  case sSIZE2:
1044  AVR_DEBUG_PRINTLN("hoping for size MSB...");
1045  msglen += (unsigned)c;
1046  //DEBUG(" msg is %u bytes\n",msglen);
1047  state = sTOKEN;
1048  break;
1049  case sTOKEN:
1050  if (c == TOKEN)
1051  state = sDATA;
1052  else
1053  state = sSTART;
1054  break;
1055  case sDATA:
1056  if (curlen < maxsize)
1057  {
1058  msg[curlen] = c;
1059  }
1060  else
1061  {
1062  AVR_DEBUG_PRINTLN("recv(): buffer too small");
1063  return -2;
1064  }
1065  if ((curlen == 0) && (msg[0] == ANSWER_CKSUM_ERROR))
1066  {
1067  AVR_DEBUG_PRINTLN("recv(): previous packet sent with wrong checksum");
1068  return -3;
1069  }
1070  curlen++;
1071  if (curlen == msglen)
1072  state = sCSUM;
1073  break;
1074  case sCSUM:
1075  if (checksum == 0)
1076  {
1077  state = sDONE;
1078  }
1079  else
1080  {
1081  state = sSTART;
1082  AVR_DEBUG_PRINTLN("recv(): checksum error");
1083  return -4;
1084  }
1085  break;
1086  default:
1087  AVR_DEBUG_PRINTLN("recv(): unknown state");
1088  return -5;
1089  }
1090 
1091  if (millis() - tstart > MEGA_SERIAL_TIMEOUT)
1092  { // wuff - signed/unsigned/overflow
1093  timedout:
1094  AVR_DEBUG_PRINTLN("recv(): timeout");
1095  return -1;
1096  }
1097 
1098  }
1100  return (int)(msglen+6);
1101  }
1102 
1103 #define RETRIES 5
1104 
1105  int getsync()
1106  {
1107  int tries = 0;
1108  unsigned char buf[1], resp[32];
1109  int status;
1110 
1111  retry:
1112  tries++;
1113 
1114  // send the sync command and see if we can get there
1115  buf[0] = CMD_SIGN_ON;
1116  send(buf, 1);
1117 
1118  // try to get the response back and see where we got
1119  status = recv(resp, sizeof(resp));
1120 
1121  // if we got bytes returned, check to see what came back
1122  if (status > 0)
1123  {
1124  if ((resp[0] == CMD_SIGN_ON) && (resp[1] == STATUS_CMD_OK) &&
1125  (status > 3))
1126  {
1127  // success!
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)
1133  {
1134  fBootlLoader = kAVRISP;
1135  }
1136  else
1137  {
1138  // timing probably didn't work out
1139  Serial.println("UNSUPPORTED BOOTLOADER");
1140  return -1;
1141  }
1142  return 0;
1143  }
1144  else
1145  {
1146  if (tries > RETRIES)
1147  {
1148  Serial.println("Can't communicate with device");
1149  return -6;
1150  }
1151  else
1152  {
1153  goto retry;
1154  }
1155  }
1156 
1157  // or if we got a timeout
1158  }
1159  else if (status == -1)
1160  {
1161  if (tries > RETRIES)
1162  {
1163  Serial.println("Timeout");
1164  return -1;
1165  }
1166  else
1167  {
1168  goto retry;
1169  }
1170  // or any other error
1171  }
1172  else
1173  {
1174  if (tries > RETRIES)
1175  {
1176  Serial.println("Error");
1177  }
1178  else
1179  {
1180  goto retry;
1181  }
1182  }
1183  return 0;
1184  }
1185 
1186  int command(unsigned char * buf, size_t len, size_t maxlen)
1187  {
1188  int tries = 0;
1189  int status;
1190 
1191  #ifdef USE_AVR_DEBUG
1192  AVR_DEBUG_PRINT("STK500V2: command(");
1193  for (size_t i = 0; i < len; i++)
1194  {
1195  AVR_DEBUG_PRINT_HEX(buf[i]);
1196  AVR_DEBUG_PRINT(" ");
1197  }
1198  AVR_DEBUG_PRINT(", "); DEBUG_PRINTLN(len);
1199  #endif
1200 
1201  retry:
1202  tries++;
1203 
1204  // send the command to the programmer
1205  send(buf,len);
1206  // attempt to read the status back
1207  status = recv(buf,maxlen);
1208 
1209  // if we got a successful readback, return
1210  if (status > 0)
1211  {
1212  AVR_DEBUG_PRINT(" = "); AVR_DEBUG_PRINTLN(status);
1213  if (status < 2)
1214  {
1215  AVR_DEBUG_PRINTLN("short reply");
1216  return -1;
1217  }
1218  if (buf[1] >= STATUS_CMD_TOUT && buf[1] < 0xa0)
1219  {
1220  AVR_DEBUG_PRINTLN("command timed out");
1221  }
1222  else if (buf[1] == STATUS_CMD_OK)
1223  {
1224  return status;
1225  }
1226  else if (buf[1] == STATUS_CMD_FAILED)
1227  {
1228  AVR_DEBUG_PRINTLN("command failed");
1229  }
1230  else if (buf[1] == STATUS_CMD_UNKNOWN)
1231  {
1232  AVR_DEBUG_PRINTLN("unknown command");
1233  }
1234  else
1235  {
1236  }
1237  return -1;
1238  }
1239 
1240  // otherwise try to sync up again
1241  status = getsync();
1242  if (status != 0)
1243  {
1244  if (tries > RETRIES)
1245  {
1246  return -1;
1247  }
1248  else
1249  {
1250  goto retry;
1251  }
1252  }
1253 
1254  AVR_DEBUG_PRINTLN(" = 0");
1255  return 0;
1256  }
1257 
1258  int getparm(unsigned char parm, unsigned char * value)
1259  {
1260  unsigned char buf[32];
1261 
1262  buf[0] = CMD_GET_PARAMETER;
1263  buf[1] = parm;
1264 
1265  if (command(buf, 2, sizeof(buf)) < 0)
1266  {
1267  return -1;
1268  }
1269  *value = buf[2];
1270  return 0;
1271  }
1272 
1273  int setparm_real(unsigned char parm, unsigned char value)
1274  {
1275  unsigned char buf[32];
1276 
1277  buf[0] = CMD_SET_PARAMETER;
1278  buf[1] = parm;
1279  buf[2] = value;
1280 
1281  if (command(buf, 3, sizeof(buf)) < 0)
1282  {
1283  return -1;
1284  }
1285  return 0;
1286  }
1287 
1288  int setparm(unsigned char parm, unsigned char value)
1289  {
1290  int res;
1291  unsigned char current_value;
1292 
1293  res = getparm(parm, &current_value);
1294  if (res == 0 && value == current_value)
1295  {
1296  return 0;
1297  }
1298  return setparm_real(parm, value);
1299  }
1300 
1301  int getparm2(unsigned char parm, unsigned int * value)
1302  {
1303  unsigned char buf[32];
1304 
1305  buf[0] = CMD_GET_PARAMETER;
1306  buf[1] = parm;
1307 
1308  if (command(buf, 2, sizeof(buf)) < 0)
1309  {
1310  return -1;
1311  }
1312  *value = ((unsigned)buf[2] << 8) | buf[3];
1313  return 0;
1314  }
1315 
1316  int setparm2(unsigned char parm, unsigned int value)
1317  {
1318  unsigned char buf[32];
1319 
1320  buf[0] = CMD_SET_PARAMETER;
1321  buf[1] = parm;
1322  buf[2] = value >> 8;
1323  buf[3] = value;
1324 
1325  if (command(buf, 4, sizeof(buf)) < 0)
1326  {
1327  return -1;
1328  }
1329  return 0;
1330  }
1331 
1332  int programEnable()
1333  {
1334  unsigned char buf[16];
1335 
1336  buf[0] = CMD_ENTER_PROGMODE_ISP;
1337  buf[1] = fTimeOut;
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;
1346 
1347  return command(buf, 12, sizeof(buf));
1348  }
1349 
1350  int display()
1351  {
1352  unsigned char maj, min, hdw;
1353 
1354  if (getparm(PARAM_HW_VER, &hdw) == 0 &&
1355  getparm(PARAM_SW_MAJOR, &maj) == 0 &&
1356  getparm(PARAM_SW_MINOR, &min) == 0)
1357  {
1358  DEBUG_PRINT("Programmer Model: AVRISP");
1359  DEBUG_PRINT("Hardware Version: "); DEBUG_PRINTLN(hdw);
1360  DEBUG_PRINT("Firmware Version Master : "); DEBUG_PRINT(maj); DEBUG_PRINT("."); DEBUG_PRINTLN(min);
1361  return 0;
1362  }
1363  return -1;
1364  }
1365 
1366  int readByte(Memory& mem, uint32_t addr, uint8_t* value)
1367  {
1368  uint8_t buf[6];
1369 
1370  if (mem.loaded)
1371  return 0;
1372  switch (mem.type)
1373  {
1374  case kFlash:
1375  case kEEPROM:
1376  {
1377  uint32_t paddr = 0UL;
1378  uint32_t* paddr_ptr = NULL;
1379  unsigned pagesize = 0;
1380  uint8_t *cache_ptr = NULL;
1381  // use paged access, and cache result
1382  if (mem.type == kFlash)
1383  {
1384  pagesize = fFlashPageSize;
1385  paddr = addr & ~(pagesize - 1);
1386  paddr_ptr = &fFlashPageAddr;
1387  cache_ptr = fFlashPageCache;
1388  }
1389  else
1390  {
1391  pagesize = mem.page_size;
1392  if (pagesize == 0)
1393  pagesize = 1;
1394  paddr = addr & ~(pagesize - 1);
1395  paddr_ptr = &fEEPROMPageAddr;
1396  cache_ptr = fEEPROMPageCache;
1397  }
1398 
1399  if (paddr == *paddr_ptr)
1400  {
1401  *value = cache_ptr[addr & (pagesize - 1)];
1402  return 0;
1403  }
1404 
1405  if (readPage(mem, pagesize, paddr, pagesize) < 0)
1406  return -1;
1407 
1408  *paddr_ptr = paddr;
1409  memcpy(cache_ptr, &mem.buf[paddr], pagesize);
1410  *value = cache_ptr[addr & (pagesize - 1)];
1411  return 0;
1412  }
1413 
1414  case kLFuse:
1415  case kFuse:
1416  buf[0] = CMD_READ_FUSE_ISP;
1417  addr = 0;
1418  break;
1419 
1420  case kHFuse:
1421  buf[0] = CMD_READ_FUSE_ISP;
1422  addr = 1;
1423  break;
1424 
1425  case kEFuse:
1426  buf[0] = CMD_READ_FUSE_ISP;
1427  addr = 2;
1428  break;
1429 
1430  case kLock:
1431  buf[0] = CMD_READ_LOCK_ISP;
1432  break;
1433 
1434  case kCalibration:
1435  buf[0] = CMD_READ_SIGNATURE_ISP;
1436  break;
1437 
1438  case kSignature:
1439  buf[0] = CMD_READ_SIGNATURE_ISP;
1440  break;
1441 
1442  default:
1443  // Not supported
1444  return -1;
1445  }
1446 
1447  MemOp& op = mem.read;
1448  memset(buf + 1, 0, 5);
1449  if (!op.isValid())
1450  {
1451  return -1;
1452  }
1453  op.setBits(buf + 2);
1454  int pollidx;
1455  if ((pollidx = op.getOutputIndex()) == -1)
1456  {
1457  pollidx = 3;
1458  }
1459  buf[1] = pollidx + 1;
1460  op.setAddress(buf + 2, addr);
1461 
1462  int result = command(buf, 6, sizeof(buf));
1463  if (result < 0)
1464  {
1465  return -1;
1466  }
1467  *value = buf[2];
1468  return 0;
1469  }
1470 
1471  int readPage(Memory& mem, unsigned page_size, unsigned addr, unsigned n_bytes)
1472  {
1473  if (mem.loaded)
1474  return n_bytes;
1475  unsigned block_size, hiaddr, addrshift, use_ext_addr;
1476  unsigned maxaddr = addr + n_bytes;
1477  uint8_t commandbuf[4];
1478  uint8_t buf[275]; // max buffer size for stk500v2 at this point
1479  uint8_t cmds[4];
1480  int result;
1481  // DEBUG("STK500V2: stk500v2_paged_load(..,%s,%u,%u,%u)\n", m->desc, page_size, addr, n_bytes);
1482 
1483  page_size = fBlockSize;
1484  MemOp& readOp = mem.invalid;
1485 
1486  hiaddr = UINT_MAX;
1487  addrshift = 0;
1488  use_ext_addr = 0;
1489 
1490  // determine which command is to be used
1491  switch (mem.type)
1492  {
1493  case kFlash:
1494  commandbuf[0] = CMD_READ_FLASH_ISP;
1495  readOp = fRegions.flash.read_lo;
1496  addrshift = 1;
1497  use_ext_addr = (1U << 31);
1498  break;
1499 
1500  case kEEPROM:
1501  commandbuf[0] = CMD_READ_EEPROM_ISP;
1502  readOp = fRegions.eeprom.read;
1503  break;
1504 
1505  default:
1506  return -1;
1507  }
1508 
1509  if (!readOp.isValid())
1510  {
1511  return -1;
1512  }
1513  readOp.setBits(cmds);
1514  commandbuf[3] = cmds[0];
1515 
1516  for (; addr < maxaddr; addr += page_size)
1517  {
1518  if ((maxaddr - addr) < page_size)
1519  block_size = maxaddr - addr;
1520  else
1521  block_size = page_size;
1522 
1523  memcpy(buf, commandbuf, sizeof(commandbuf));
1524 
1525  buf[1] = block_size >> 8;
1526  buf[2] = block_size & 0xff;
1527 
1528  if (hiaddr != (addr & ~0xFFFF))
1529  {
1530  hiaddr = addr & ~0xFFFF;
1531  if (loadAddress(use_ext_addr | (addr >> addrshift)) < 0)
1532  return -1;
1533  }
1534 
1535  result = command(buf, 4, sizeof(buf));
1536  if (result < 0)
1537  {
1538  return -1;
1539  }
1540  memcpy(&mem.buf[addr], &buf[2], block_size);
1541  }
1542  return n_bytes;
1543  }
1544 
1545  int loadAddress(unsigned int addr)
1546  {
1547  unsigned char buf[16];
1548 
1549  // DEBUG("STK500V2: stk500v2_loadaddr(%d)\n",addr);
1550 
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;
1556 
1557  return command(buf, 5, sizeof(buf));
1558  }
1559 
1560  int chipErase()
1561  {
1562  unsigned char buf[16];
1563 
1564  buf[0] = CMD_CHIP_ERASE_ISP;
1565  buf[1] = fChipEraseDelay / 1000;
1566  buf[2] = 0;
1567  chipEraseOp.setBits(buf+3);
1568  return (command(buf, 7, sizeof(buf)) >= 0) ? 0 : -1;
1569  }
1570 
1571  int writePage(Memory& mem, unsigned page_size, uint32_t addr, unsigned n_bytes)
1572  {
1573  unsigned block_size;
1574  unsigned last_addr;
1575  unsigned addrshift;
1576  unsigned use_ext_addr;
1577  uint32_t maxaddr = addr + n_bytes;
1578  uint8_t commandbuf[10];
1579  uint8_t buf[266];
1580  uint8_t cmds[4];
1581  int result;
1582  MemOp& rop = mem.invalid;
1583  MemOp& wop = mem.invalid;
1584 
1585  if (page_size == 0)
1586  page_size = fBlockSize;
1587  addrshift = 0;
1588  use_ext_addr = 0;
1589 
1590  // determine which command is to be used
1591  if (mem.type == kFlash)
1592  {
1593  addrshift = 1;
1594  commandbuf[0] = CMD_PROGRAM_FLASH_ISP;
1595  /*
1596  * If bit 31 is set, this indicates that the following read/write
1597  * operation will be performed on a memory that is larger than
1598  * 64KBytes. This is an indication to STK500 that a load extended
1599  * address must be executed.
1600  */
1601  if (mem.load_ext_addr.isValid())
1602  {
1603  use_ext_addr = (1U << 31);
1604  }
1605  }
1606  else if (mem.type == kEEPROM)
1607  {
1608  commandbuf[0] = CMD_PROGRAM_EEPROM_ISP;
1609  }
1610  commandbuf[4] = mem.delay;
1611 
1612  if (addrshift == 0)
1613  {
1614  wop = mem.write;
1615  rop = mem.read;
1616  }
1617  else
1618  {
1619  wop = mem.write_lo;
1620  rop = mem.read_lo;
1621  }
1622 
1623  // if the memory is paged, load the appropriate commands into the buffer
1624  if (mem.mode & 0x01)
1625  {
1626  commandbuf[3] = mem.mode | 0x80; // yes, write the page to flash
1627 
1628  if (!mem.loadpage_lo.isValid())
1629  {
1630  return -1;
1631  }
1632  mem.loadpage_lo.setBits(cmds);
1633  commandbuf[5] = cmds[0];
1634 
1635  if (!mem.writepage.isValid())
1636  {
1637  return -1;
1638  }
1639  mem.writepage.setBits(cmds);
1640  commandbuf[6] = cmds[0];
1641 
1642  // otherwise, we need to load different commands in
1643  }
1644  else
1645  {
1646  commandbuf[3] = mem.mode | 0x80; // yes, write the words to flash
1647 
1648  if (!wop.isValid())
1649  {
1650  return -1;
1651  }
1652  wop.setBits(cmds);
1653  commandbuf[5] = cmds[0];
1654  commandbuf[6] = 0;
1655  }
1656 
1657  // the read command is common to both methods
1658  if (!rop.isValid())
1659  {
1660  return -1;
1661  }
1662  rop.setBits(cmds);
1663  commandbuf[7] = cmds[0];
1664 
1665  commandbuf[8] = mem.readback_p1;
1666  commandbuf[9] = mem.readback_p2;
1667 
1668  last_addr = ~0u;
1669  for (; addr < maxaddr; addr += page_size)
1670  {
1671  if ((maxaddr - addr) < page_size)
1672  block_size = maxaddr - addr;
1673  else
1674  block_size = page_size;
1675 
1676  memcpy(buf,commandbuf,sizeof(commandbuf));
1677 
1678  buf[1] = block_size >> 8;
1679  buf[2] = block_size & 0xff;
1680 
1681  if (last_addr == UINT_MAX || last_addr + block_size != addr)
1682  {
1683  if (loadAddress(use_ext_addr | (addr >> addrshift)) < 0)
1684  return -1;
1685  }
1686  last_addr = addr;
1687 
1688  memcpy(buf + 10, &mem.buf[addr], block_size);
1689 
1690  result = command(buf, block_size + 10, sizeof(buf));
1691  if (result < 0)
1692  {
1693  return -1;
1694  }
1695  }
1696  return n_bytes;
1697  }
1698 
1699  bool readMemory(Memory& mem)
1700  {
1701  if (mem.loaded)
1702  return true;
1703  if (!startProgramming())
1704  return false;
1705 
1706  mem.loaded = false;
1707  uint32_t addr = 0;
1708  while (addr < mem.size)
1709  {
1710  unsigned minpagesize = (mem.page_size > 0) ? mem.page_size : 16;
1711  if (mem.page_size)
1712  {
1713  if (readPage(mem, mem.page_size, addr, mem.page_size) < 0)
1714  return false;
1715  }
1716  else
1717  {
1718  for (int i = 0; i < minpagesize; i += 1)
1719  {
1720  if (addr+i < mem.size && readByte(mem, addr+i, &mem.buf[addr+i]) < 0)
1721  return false;
1722  }
1723  }
1724  addr += minpagesize;
1725  }
1726  mem.loaded = true;
1727  return true;
1728  }
1729 
1730  bool dumpMemory(Memory& mem)
1731  {
1732  if (!startProgramming())
1733  return false;
1734 
1735  uint32_t addr = 0;
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)
1745  {
1746  unsigned minpagesize = (mem.page_size > 0) ? mem.page_size : 16;
1747  if (mem.page_size)
1748  {
1749  if (readPage(mem, mem.page_size, addr, mem.page_size) < 0)
1750  return false;
1751  }
1752  else
1753  {
1754  for (int i = 0; i < minpagesize; i += 1)
1755  {
1756  if (addr+i < mem.size && readByte(mem, addr+i, &mem.buf[addr+i]) < 0)
1757  return false;
1758  }
1759  }
1760  for (int i = 0; i < minpagesize; i += 16)
1761  {
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;
1766  if (!rowRepeats)
1767  {
1768  lastRowRepeats = false;
1769  lastRowRepeatPrinted = false;
1770  }
1771  if (!lastRowRepeats)
1772  {
1773  if (!rowRepeats)
1774  {
1775  int x;
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++)
1779  {
1780  printf("%02x ", printedRow[x]);
1781  if (((x+1) % 8) == 0) printf(" ");
1782  }
1783  while (x < 16)
1784  {
1785  printf(" ");
1786  if (((++x) % 8) == 0) printf(" ");
1787  }
1788  printf("|");
1789  for (x = 0; x < 16 && addr+i+x < mem.size; x++)
1790  {
1791  uint8_t ch = printedRow[x];
1792  printf("%c", ((ch >= 32 && ch <= 127) ? ch : '.'));
1793  }
1794  printf("|\n");
1795  }
1796  else
1797  {
1798  lastRowRepeats = true;
1799  }
1800  }
1801  else if (!lastRowRepeatPrinted)
1802  {
1803  printf("*\n");
1804  lastRowRepeatPrinted = true;
1805  }
1806  }
1807  addr += minpagesize;
1808  if (lastRowRepeats && !mem.loaded)
1809  {
1810  printf("\r%c\r", progress[progressIndex++>>1]); fflush(stdout);
1811  if (progressIndex == sizeof(progress)*2)
1812  progressIndex = 0;
1813  }
1814  }
1815  printf("\r%08x\n", mem.size);
1816  printf("=======\n");
1817  uint32_t stopTime = millis();
1818  printf("elapsed : %u\n", stopTime - startTime);
1819  mem.loaded = true;
1820  return true;
1821  }
1822 
1823  int parseHexLine(char* line, uint8_t* bytes, unsigned &addr, unsigned &num, int &status)
1824  {
1825  int sum, len, cksum;
1826  char *ptr;
1827 
1828  num = 0;
1829  if (line[0] != ':')
1830  return 0;
1831  if (strlen(line) < 11)
1832  return 0;
1833  ptr = line + 1;
1834  if (!sscanf(ptr, "%02x", &len))
1835  return 0;
1836  ptr += 2;
1837  if (strlen(line) < (11 + (len * 2)))
1838  return 0;
1839  if (!sscanf(ptr, "%04x", &addr))
1840  return 0;
1841  ptr += 4;
1842  if (!sscanf(ptr, "%02x", &status))
1843  return 0;
1844  ptr += 2;
1845  sum = (len & 255) + ((addr >> 8) & 255) + (addr & 255) + (status & 255);
1846  while (num != len)
1847  {
1848  int data;
1849  if (!sscanf(ptr, "%02x", &data))
1850  return 0;
1851  bytes[num] = (uint8_t)data;
1852  ptr += 2;
1853  sum += data;
1854  num++;
1855  if (num >= fBlockSize)
1856  return 0;
1857  }
1858  if (!sscanf(ptr, "%02x", &cksum))
1859  return 0;
1860  if (((sum & 255) + (cksum & 255)) & 255)
1861  return 0; /* checksum error */
1862  return 1;
1863  }
1864 
1865  bool writeHexString(Memory& mem, const char* str, unsigned* lineno)
1866  {
1867  if (!startProgramming())
1868  return false;
1869 
1870  char c;
1871  char line[fBlockSize];
1872  const char* ch = str;
1873  unsigned linei = 0;
1874  if (lineno != NULL)
1875  *lineno = 1;
1876  // for non-paged memory just read the whole region
1877  if (!mem.page_size && !mem.loaded && !readMemory(mem))
1878  return false;
1879  unsigned lastPageRead = ~0u;
1880  while ((c = *ch++) != '\0')
1881  {
1882  line[linei] = '\0';
1883  if (c == '\n' || c == '\r')
1884  {
1885  int status;
1886  unsigned n;
1887  unsigned addr;
1888  uint8_t bytes[fBlockSize];
1889  if (linei != 0 && parseHexLine(line, bytes, addr, n, status))
1890  {
1891  if (status == 0)
1892  {
1893  // printf("address: %08x ", addr);
1894  for (unsigned i = 0; i <= (n-1); i++)
1895  {
1896  if (mem.page_size > 0)
1897  {
1898  unsigned pageNumber = addr / mem.page_size;
1899  if (!mem.loaded && lastPageRead != pageNumber)
1900  {
1901  unsigned pageAddr = pageNumber * mem.page_size;
1902  if (!readPage(mem, mem.page_size, pageAddr, mem.page_size))
1903  return false;
1904  lastPageRead = pageNumber;
1905  progressCallback((double)addr / (double)mem.size);
1906  }
1907  }
1908  mem.set(addr, bytes[i]);
1909  addr++;
1910  }
1911  }
1912  else if (status == 1)
1913  {
1914  /* end of file */
1915  return true;
1916  }
1917  else if (status == 2)
1918  {
1919  /* begin of file */
1920  }
1921  else
1922  {
1923  return false;
1924  }
1925  }
1926  linei = 0;
1927  if (lineno != NULL)
1928  (*lineno)++;
1929  }
1930  else if (linei < sizeof(line)-1)
1931  {
1932  line[linei++] = c;
1933  }
1934  else
1935  {
1936  /* ignore */
1937  }
1938  }
1939  return false;
1940  }
1941 
1942  bool hasMemoryChanged(Memory& mem)
1943  {
1944  if (mem.page_size != 0)
1945  {
1946  for (unsigned addr = 0; addr < mem.size; addr += mem.page_size)
1947  {
1948  if (mem.isPageTagged(addr))
1949  {
1950  return true;
1951  }
1952  }
1953  return false;
1954  }
1955  for (unsigned addr = 0; addr < mem.size; addr++)
1956  {
1957  if (mem.isAddressTagged(addr))
1958  return true;
1959  }
1960  return false;
1961  }
1962 
1963  bool writeMemory(Memory& mem, bool verify = true)
1964  {
1965  if (mem.page_size == 0)
1966  return false;
1967 
1968  if (fBootlLoader == kAVRISP)
1969  {
1970  // We would like to update only tagged pages, but the default
1971  // Arduino-stk500v2-bootloader has a bug that maintains a separate
1972  // page erase address pointer from the page address being updated.
1973  // The erase address pointer is incremented page by page. This forces
1974  // us to have to write changed pages starting with zero and ending with
1975  // the last modified page.
1976 
1977  // figure out min/max changed page addresses
1978  unsigned maxChangedPageAddr = 0;
1979  for (unsigned addr = 0; addr < mem.size; addr += mem.page_size)
1980  {
1981  if (mem.isPageTagged(addr))
1982  maxChangedPageAddr = addr;
1983  }
1984  // tag all pages before maxChangedPageAddr
1985  for (unsigned addr = 0; addr < maxChangedPageAddr; addr += mem.page_size)
1986  {
1987  mem.tagPage(addr, true);
1988  }
1989  // Make sure the erase address starts at zero.
1990  // Boot loader will return failed so just ignore the error
1991  (void) chipErase();
1992  }
1993  uint8_t* verifyBuffer = (verify) ? (uint8_t*)alloca(mem.page_size) : NULL;
1994  for (unsigned addr = 0; addr < mem.size; addr += mem.page_size)
1995  {
1996  if (mem.isPageTagged(addr))
1997  {
1998  if (writePage(mem, 0, addr, mem.page_size) < 0)
1999  {
2000  return false;
2001  }
2002  if (verify)
2003  {
2004  memcpy(verifyBuffer, &mem.buf[addr], mem.page_size);
2005  if (readPage(mem, mem.page_size, addr, mem.page_size) < 0)
2006  {
2007  return false;
2008  }
2009  if (memcmp(verifyBuffer, &mem.buf[addr], mem.page_size) != 0)
2010  {
2011  // verify failed
2012  return false;
2013  }
2014  progressCallback((double)addr / (double)mem.size);
2015  }
2016  }
2017  }
2018  return true;
2019  }
2020 
2021  void progressCallback(double percent)
2022  {
2023  if (fProgress != NULL)
2024  fProgress(percent);
2025  }
2026 };
2027 
2028 #endif
AVRMega2560Programmer::kFuse
@ kFuse
Definition: AVRMega2560Programmer.h:40
AVRMega2560Programmer::MemoyRegions::Calibration::Calibration
Calibration()
Definition: AVRMega2560Programmer.h:887
AVRMega2560Programmer::kUnknown
@ kUnknown
Definition: AVRMega2560Programmer.h:50
AVRMega2560Programmer::MemoyRegions::Lock::Lock
Lock()
Definition: AVRMega2560Programmer.h:872
AVR_DEBUG_PRINTLN
#define AVR_DEBUG_PRINTLN(s)
Definition: AVRMega2560Programmer.h:13
AVRMega2560Programmer::MemoyRegions::Lock
Definition: AVRMega2560Programmer.h:871
AVRMega2560Programmer::kCalibration
@ kCalibration
Definition: AVRMega2560Programmer.h:44
DEBUG_PRINT
#define DEBUG_PRINT(s)
Definition: ReelTwo.h:189
AVRMega2560Programmer::stopProgramming
void stopProgramming()
Definition: AVRMega2560Programmer.h:168
SetupEvent.h
AVRMega2560Programmer::MemoyRegions::EEPROM
Definition: AVRMega2560Programmer.h:780
SetupEvent
Base class for all devices that require setup that cannot happen in the constructor....
Definition: SetupEvent.h:15
AVRMega2560Programmer::writeMemory
bool writeMemory(MemType type, bool verify=true)
Definition: AVRMega2560Programmer.h:216
AVRMega2560Programmer::MemoyRegions::EFuse::EFuse
EFuse()
Definition: AVRMega2560Programmer.h:857
AVRMega2560Programmer::MemoyRegions::LFuse::LFuse
LFuse()
Definition: AVRMega2560Programmer.h:827
AVRMega2560Programmer::startProgramming
bool startProgramming()
Definition: AVRMega2560Programmer.h:103
AVR_DEBUG_PRINT
#define AVR_DEBUG_PRINT(s)
Definition: AVRMega2560Programmer.h:12
AVRMega2560Programmer::kAVRISP
@ kAVRISP
Definition: AVRMega2560Programmer.h:51
AVRMega2560Programmer::kSignature
@ kSignature
Definition: AVRMega2560Programmer.h:45
AVRMega2560Programmer::reset
void reset()
Definition: AVRMega2560Programmer.h:85
AVRMega2560Programmer::kHFuse
@ kHFuse
Definition: AVRMega2560Programmer.h:41
AVRMega2560Programmer::MemoyRegions::Calibration
Definition: AVRMega2560Programmer.h:886
DEBUG_PRINTLN
#define DEBUG_PRINTLN(s)
Definition: ReelTwo.h:188
AVRMega2560Programmer::kFlash
@ kFlash
Definition: AVRMega2560Programmer.h:37
RETRIES
#define RETRIES
Definition: AVRMega2560Programmer.h:1103
AVRMega2560Programmer::MemoyRegions::Fuse::Fuse
Fuse(MemType type)
Definition: AVRMega2560Programmer.h:819
AVRMega2560Programmer::hasMemoryChanged
bool hasMemoryChanged(MemType type)
Definition: AVRMega2560Programmer.h:222
AVRMega2560Programmer::kLock
@ kLock
Definition: AVRMega2560Programmer.h:43
AVRMega2560Programmer::setup
virtual void setup() override
Subclasses must implement this function to perform any necessary setup that cannot happen in the cons...
Definition: AVRMega2560Programmer.h:61
AVRMega2560Programmer::MemoyRegions::Flash
Definition: AVRMega2560Programmer.h:730
AVRMega2560Programmer::setProgress
void setProgress(ProgressProc progressFunc)
Definition: AVRMega2560Programmer.h:70
AVRMega2560Programmer::kEFuse
@ kEFuse
Definition: AVRMega2560Programmer.h:42
AVRMega2560Programmer::MemType
MemType
Definition: AVRMega2560Programmer.h:35
AVRMega2560Programmer::release
void release()
Definition: AVRMega2560Programmer.h:80
AVRMega2560Programmer::readMemory
uint8_t * readMemory(MemType type, size_t *size)
Definition: AVRMega2560Programmer.h:194
AVR_DEBUG_PRINT_HEX
#define AVR_DEBUG_PRINT_HEX(s)
Definition: AVRMega2560Programmer.h:14
AVRMega2560Programmer::MemoyRegions::Fuse
Definition: AVRMega2560Programmer.h:818
AVRMega2560Programmer::MemoyRegions::EEPROM::EEPROM
EEPROM()
Definition: AVRMega2560Programmer.h:781
AVRMega2560Programmer::MemoyRegions::HFuse
Definition: AVRMega2560Programmer.h:841
AVRMega2560Programmer::kEEPROM
@ kEEPROM
Definition: AVRMega2560Programmer.h:38
AVRMega2560Programmer::MemoyRegions::Signature::Signature
Signature()
Definition: AVRMega2560Programmer.h:898
AVRMega2560Programmer::MemoyRegions::EFuse
Definition: AVRMega2560Programmer.h:856
AVRMega2560Programmer::dumpMemory
bool dumpMemory(MemType type)
Definition: AVRMega2560Programmer.h:188
AVRMega2560Programmer::MemoyRegions::Flash::Flash
Flash()
Definition: AVRMega2560Programmer.h:732
AVRMega2560Programmer::block
void block()
Definition: AVRMega2560Programmer.h:75
AVRMega2560Programmer::MemoyRegions::HFuse::HFuse
HFuse()
Definition: AVRMega2560Programmer.h:842
AVRMega2560Programmer::ProgressProc
void(* ProgressProc)(double percent)
Definition: AVRMega2560Programmer.h:69
AVRMega2560Programmer::MemoyRegions::Signature
Definition: AVRMega2560Programmer.h:897
AVRMega2560Programmer::BootLoaderType
BootLoaderType
Definition: AVRMega2560Programmer.h:48
AVRMega2560Programmer
AVR Programmer.
Definition: AVRMega2560Programmer.h:32
AVRMega2560Programmer::AVRMega2560Programmer
AVRMega2560Programmer(uint8_t resetPin, HardwareSerial &port)
Definition: AVRMega2560Programmer.h:54
AVRMega2560Programmer::writeHexString
bool writeHexString(MemType type, const char *hexString, unsigned *lineno=NULL)
Definition: AVRMega2560Programmer.h:208
AVRMega2560Programmer::kLFuse
@ kLFuse
Definition: AVRMega2560Programmer.h:39
AVRMega2560Programmer::MemoyRegions::LFuse
Definition: AVRMega2560Programmer.h:826