ArduinoISP.ino
1 // SPDX-FileCopyrightText: 2009 David A. Mellis 2 // SPDX-FileCopyrightText: 2009 Randall Bohn 3 // SPDX-FileCopyrightText: 2012 William Phelps 4 // SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries 5 // 6 // SPDX-License-Identifier: MIT 7 8 // this sketch turns the Arduino into a AVRISP 9 // using the following pins: 10 // 10: slave reset 11 // 11: MOSI 12 // 12: MISO 13 // 13: SCK 14 15 // Put an LED (with resistor) on the following pins: 16 // 8: Error - Lights up if something goes wrong (use red if that makes sense) 17 // A0: Programming - In communication with the slave 18 // 6: Heartbeat - shows the programmer is running (removed, see notes below) 19 // Optional - Piezo speaker on pin A3 20 // 21 // October 2009 by David A. Mellis 22 // - Added support for the read signature command 23 // 24 // February 2009 by Randall Bohn 25 // - Added support for writing to EEPROM (what took so long?) 26 // Windows users should consider WinAVR's avrdude instead of the 27 // avrdude included with Arduino software. 28 // 29 // January 2008 by Randall Bohn 30 // - Thanks to Amplificar for helping me with the STK500 protocol 31 // - The AVRISP/STK500 (mk I) protocol is used in the arduino bootloader 32 // - The SPI functions herein were developed for the AVR910_ARD programmer 33 // - More information at http://code.google.com/p/mega-isp 34 // 35 // March 2012 - William Phelps 36 // modify to work with Arduino IDE 1.0 which has a shorter serial port receive buffer 37 // getEOP() now gets entire request before avrisp() is called to process it 38 // Serial.print((char) xxx) changed to Serial.write(xxx) 39 // uint8_t changed to byte 40 // added support for Piezo speaker 41 // moved Pmode LED to A0 42 // removed "heartbeat" on pin 6, added short blip of ERROR LED instead 43 // Why is it that PROG_FLASH and PROG_DATA don't actually do anything??? 44 // Tested with Arduino IDE 22 and 1.0 45 // IDE 22 - 5148 bytes 46 // IDE 1.0 - 5524 bytes! 47 48 49 // SLOW SPEED CHIP ERASE AND FUSE BURNING 50 // 51 // Enable LOW_SPEED to allow you to erase chips that would fail otherwise, 52 // for being running with a clock too slow for the programmer. 53 // 54 // This allowed me to recover several ATMega328 that had no boot loader and the 55 // first instruction was to set the clock to the slowest speed. Usually this 56 // kind of recovery requires high voltage programming, but this trick will do 57 // just fine. 58 // 59 // How to proceed: 60 // 1. Enable LOW_SPEED, and load it to the programmer. 61 // 2. Erase and burn the fuses on the target uC. Example for ATMega328: 62 // arduino-1.0.1/hardware/tools/avrdude -Carduino-1.0.1/hardware/tools/avrdude.conf -patmega328p -cstk500v1 -P /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A900cf1Q-if00-port0 -b19200 -e -Ulock:w:0x3F:m -Uefuse:w:0x05:m -Uhfuse:w:0xDA:m -Ulfuse:w:0xF7:m 63 // 3. Comment LOW_SPEED and load it back to the programmer. 64 // 4. Program the target uC as usual. Example: 65 // arduino-1.0.1/hardware/tools/avrdude -Carduino-1.0.1/hardware/tools/avrdude.conf -patmega328p -cstk500v1 -P /dev/serial/by-id/usb-FTDI_FT232R_USB_UART_A900cf1Q-if00-port0 -b19200 -Uflash:w:firmware.hex:i 66 // 67 // Note 1: EXTRA_SPI_DELAY was added to let you slow down SPI even more. You can 68 // play with the value if it does not work with the default. 69 // Note 2: LOW_SPEED will alow you only to erase the chip and burn the fuses! It 70 // will fail if you try to program the target uC this way! 71 72 //#define LOW_SPEED 73 #ifdef LOW_SPEED 74 #define EXTRA_SPI_DELAY 125 75 #else 76 #define EXTRA_SPI_DELAY 0 77 #endif 78 79 #include "pins_arduino.h" // defines SS,MOSI,MISO,SCK 80 #define RESET SS 81 82 #define LED_ERR 8 83 #define LED_PMODE A0 84 //#define LED_HB 6 85 #define PIEZO A3 86 87 #define HWVER 2 88 #define SWMAJ 1 89 #define SWMIN 18 90 91 // STK Definitions 92 const byte STK_OK = 0x10; 93 const byte STK_FAILED = 0x11; 94 const byte STK_UNKNOWN = 0x12; 95 const byte STK_INSYNC = 0x14; 96 const byte STK_NOSYNC = 0x15; 97 const byte CRC_EOP = 0x20; //ok it is a space... 98 99 const byte STK_GET_SYNC = 0x30; 100 const byte STK_GET_SIGNON = 0x31; 101 const byte STK_GET_PARM = 0x41; 102 const byte STK_SET_PARM = 0x42; 103 const byte STK_SET_PARM_EXT = 0x45; 104 const byte STK_PMODE_START = 0x50; 105 const byte STK_PMODE_END = 0x51; 106 const byte STK_SET_ADDR = 0x55; 107 const byte STK_UNIVERSAL = 0x56; 108 const byte STK_PROG_FLASH = 0x60; 109 const byte STK_PROG_DATA = 0x61; 110 const byte STK_PROG_PAGE = 0x64; 111 const byte STK_READ_PAGE = 0x74; 112 const byte STK_READ_SIGN = 0x75; 113 114 //// TONES ========================================== 115 //// Start by defining the relationship between 116 //// note, period, & frequency. 117 //#define c 3830 // 261 Hz 118 //#define d 3400 // 294 Hz 119 //#define e 3038 // 329 Hz 120 //#define f 2864 // 349 Hz 121 //#define g 2550 // 392 Hz 122 //#define a 2272 // 440 Hz 123 //#define b 2028 // 493 Hz 124 //#define C 1912 // 523 Hz 125 126 //void pulse(int pin, int times); 127 128 int error=0; 129 int pmode=0; 130 // address for reading and writing, set by STK_SET_ADDR command 131 int _addr; 132 byte _buffer[256]; // serial port buffer 133 int pBuffer = 0; // buffer pointer 134 int iBuffer = 0; // buffer index 135 byte buff[256]; // temporary buffer 136 boolean EOP_SEEN = false; 137 138 void setup() { 139 140 Serial.begin(19200); 141 pinMode(PIEZO, OUTPUT); 142 beep(1700, 40); 143 EOP_SEEN = false; 144 iBuffer = pBuffer = 0; 145 146 pinMode(LED_PMODE, OUTPUT); 147 pulse(LED_PMODE, 2); 148 pinMode(LED_ERR, OUTPUT); 149 pulse(LED_ERR, 2); 150 // pinMode(LED_HB, OUTPUT); 151 // pulse(LED_HB, 2); 152 153 pinMode(9, OUTPUT); 154 // setup high freq PWM on pin 9 (timer 1) 155 // 50% duty cycle -> 8 MHz 156 OCR1A = 0; 157 ICR1 = 1; 158 // OC1A output, fast PWM 159 TCCR1A = _BV(WGM11) | _BV(COM1A1); 160 TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // no clock prescale 161 162 163 } 164 165 #define beget16(addr) (*addr * 256 + *(addr+1) ) 166 typedef struct param { 167 byte devicecode; 168 byte revision; 169 byte progtype; 170 byte parmode; 171 byte polling; 172 byte selftimed; 173 byte lockbytes; 174 byte fusebytes; 175 int flashpoll; 176 int eeprompoll; 177 int pagesize; 178 int eepromsize; 179 int flashsize; 180 } 181 parameter; 182 183 parameter param; 184 185 // this provides a heartbeat on pin 6, so you can tell the software is running. 186 //byte hbval=128; 187 //int8_t hbdelta=4; 188 //void heartbeat() { 189 //// if (hbval > 192) hbdelta = -hbdelta; 190 //// if (hbval < 32) hbdelta = -hbdelta; 191 // if (hbval > 250) hbdelta = -hbdelta; 192 // if (hbval < 10) hbdelta = -hbdelta; 193 // hbval += hbdelta; 194 // analogWrite(LED_HB, hbval); 195 // delay(20); 196 //} 197 198 void getEOP() { 199 int minL = 0; 200 byte avrch = 0; 201 byte bl = 0; 202 while (!EOP_SEEN) { 203 while (Serial.available()>0) { 204 byte ch = Serial.read(); 205 _buffer[iBuffer] = ch; 206 iBuffer = (++iBuffer)%256; // increment and wrap 207 if (iBuffer == 1) avrch = ch; // save command 208 if ((avrch == STK_PROG_PAGE) && (iBuffer==3)) { 209 minL = 256*_buffer[1] + _buffer[2] + 4; 210 } 211 if ((iBuffer>minL) && (ch == CRC_EOP)) { 212 EOP_SEEN = true; 213 } 214 } 215 if (!EOP_SEEN) { 216 // heartbeat(); // light the heartbeat LED 217 if (bl == 100) { 218 pulse(LED_ERR,1,10); // blink the red LED 219 bl = 0; 220 } 221 bl++; 222 delay(10); 223 } 224 } 225 } 226 227 // serialEvent not used so sketch would be compatible with older IDE versions 228 //void serialEvent() { 229 // int minL = 0; 230 // byte avrch = 0; 231 // while (Serial.available()>0) 232 // { 233 // byte ch = Serial.read(); 234 // _buffer[iBuffer] = ch; 235 // iBuffer = (++iBuffer)%256; // increment and wrap 236 // if (iBuffer == 1) avrch = ch; // save command 237 // if ((avrch == STK_PROG_PAGE) && (iBuffer==3)) { 238 // minL = 256*_buffer[1] + _buffer[2] + 4; 239 // } 240 // if ((iBuffer>minL) && (ch == CRC_EOP)) { 241 // EOP_SEEN = true; 242 // } 243 // } 244 //} 245 246 void loop(void) { 247 // is pmode active? 248 // if (pmode) digitalWrite(LED_PMODE, HIGH); 249 // else digitalWrite(LED_PMODE, LOW); 250 digitalWrite(LED_PMODE, LOW); 251 // is there an error? 252 if (error) digitalWrite(LED_ERR, HIGH); 253 else digitalWrite(LED_ERR, LOW); 254 255 getEOP(); 256 257 // have we received a complete request? (ends with CRC_EOP) 258 if (EOP_SEEN) { 259 digitalWrite(LED_PMODE, HIGH); 260 EOP_SEEN = false; 261 avrisp(); 262 iBuffer = pBuffer = 0; // restart buffer 263 } 264 265 } 266 267 byte getch() { 268 if (pBuffer == iBuffer) { // spin until data available ??? 269 pulse(LED_ERR, 1); 270 beep(1700, 20); 271 error++; 272 return -1; 273 } 274 byte ch = _buffer[pBuffer]; // get next char 275 pBuffer = (++pBuffer)%256; // increment and wrap 276 return ch; 277 } 278 279 void readbytes(int n) { 280 for (int x = 0; x < n; x++) { 281 buff[x] = getch(); 282 } 283 } 284 285 //#define PTIME 20 286 void pulse(int pin, int times, int ptime) { 287 do { 288 digitalWrite(pin, HIGH); 289 delay(ptime); 290 digitalWrite(pin, LOW); 291 delay(ptime); 292 times--; 293 } 294 while (times > 0); 295 } 296 void pulse(int pin, int times) { 297 pulse(pin, times, 50); 298 } 299 300 void spi_init() { 301 byte x; 302 SPCR = 0x53; 303 #ifdef LOW_SPEED 304 SPCR=SPCR|B00000011; 305 #endif 306 x=SPSR; 307 x=SPDR; 308 } 309 310 void spi_wait() { 311 do { 312 } 313 while (!(SPSR & (1 << SPIF))); 314 } 315 316 byte spi_send(byte b) { 317 byte reply; 318 #ifdef LOW_SPEED 319 cli(); 320 CLKPR=B10000000; 321 CLKPR=B00000011; 322 sei(); 323 #endif 324 SPDR=b; 325 spi_wait(); 326 reply = SPDR; 327 #ifdef LOW_SPEED 328 cli(); 329 CLKPR=B10000000; 330 CLKPR=B00000000; 331 sei(); 332 #endif 333 return reply; 334 } 335 336 byte spi_transaction(byte a, byte b, byte c, byte d) { 337 byte n; 338 spi_send(a); 339 n=spi_send(b); 340 //if (n != a) error = -1; 341 n=spi_send(c); 342 return spi_send(d); 343 } 344 345 void replyOK() { 346 // if (EOP_SEEN == true) { 347 if (CRC_EOP == getch()) { // EOP should be next char 348 Serial.write(STK_INSYNC); 349 Serial.write(STK_OK); 350 } 351 else { 352 pulse(LED_ERR, 2); 353 Serial.write(STK_NOSYNC); 354 error++; 355 } 356 } 357 358 void breply(byte b) { 359 if (CRC_EOP == getch()) { // EOP should be next char 360 Serial.write(STK_INSYNC); 361 Serial.write(b); 362 Serial.write(STK_OK); 363 } 364 else { 365 Serial.write(STK_NOSYNC); 366 error++; 367 } 368 } 369 370 void get_parameter(byte c) { 371 switch(c) { 372 case 0x80: 373 breply(HWVER); 374 break; 375 case 0x81: 376 breply(SWMAJ); 377 break; 378 case 0x82: 379 breply(SWMIN); 380 break; 381 case 0x93: 382 breply('S'); // serial programmer 383 break; 384 default: 385 breply(0); 386 } 387 } 388 389 void set_parameters() { 390 // call this after reading paramter packet into buff[] 391 param.devicecode = buff[0]; 392 param.revision = buff[1]; 393 param.progtype = buff[2]; 394 param.parmode = buff[3]; 395 param.polling = buff[4]; 396 param.selftimed = buff[5]; 397 param.lockbytes = buff[6]; 398 param.fusebytes = buff[7]; 399 param.flashpoll = buff[8]; 400 // ignore buff[9] (= buff[8]) 401 //getch(); // discard second value 402 403 // WARNING: not sure about the byte order of the following 404 // following are 16 bits (big endian) 405 param.eeprompoll = beget16(&buff[10]); 406 param.pagesize = beget16(&buff[12]); 407 param.eepromsize = beget16(&buff[14]); 408 409 // 32 bits flashsize (big endian) 410 param.flashsize = buff[16] * 0x01000000 411 + buff[17] * 0x00010000 412 + buff[18] * 0x00000100 413 + buff[19]; 414 415 } 416 417 void start_pmode() { 418 spi_init(); 419 // following delays may not work on all targets... 420 pinMode(RESET, OUTPUT); 421 digitalWrite(RESET, HIGH); 422 pinMode(SCK, OUTPUT); 423 digitalWrite(SCK, LOW); 424 delay(50+EXTRA_SPI_DELAY); 425 digitalWrite(RESET, LOW); 426 delay(50+EXTRA_SPI_DELAY); 427 pinMode(MISO, INPUT); 428 pinMode(MOSI, OUTPUT); 429 spi_transaction(0xAC, 0x53, 0x00, 0x00); 430 pmode = 1; 431 } 432 433 void end_pmode() { 434 pinMode(MISO, INPUT); 435 pinMode(MOSI, INPUT); 436 pinMode(SCK, INPUT); 437 pinMode(RESET, INPUT); 438 pmode = 0; 439 } 440 441 void universal() { 442 // int w; 443 byte ch; 444 // for (w = 0; w < 4; w++) { 445 // buff[w] = getch(); 446 // } 447 readbytes(4); 448 ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]); 449 breply(ch); 450 } 451 452 void flash(byte hilo, int addr, byte data) { 453 spi_transaction(0x40+8*hilo, addr>>8 & 0xFF, addr & 0xFF, data); 454 } 455 void commit(int addr) { 456 spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0); 457 } 458 459 //#define _current_page(x) (here & 0xFFFFE0) 460 int current_page(int addr) { 461 if (param.pagesize == 32) return addr & 0xFFFFFFF0; 462 if (param.pagesize == 64) return addr & 0xFFFFFFE0; 463 if (param.pagesize == 128) return addr & 0xFFFFFFC0; 464 if (param.pagesize == 256) return addr & 0xFFFFFF80; 465 return addr; 466 } 467 byte write_flash(int length) { 468 if (param.pagesize < 1) { 469 return STK_FAILED; 470 } 471 //if (param.pagesize != 64) return STK_FAILED; 472 int page = current_page(_addr); 473 int x = 0; 474 while (x < length) { 475 if (page != current_page(_addr)) { 476 commit(page); 477 page = current_page(_addr); 478 } 479 flash(LOW, _addr, buff[x++]); 480 flash(HIGH, _addr, buff[x++]); 481 _addr++; 482 } 483 commit(page); 484 return STK_OK; 485 } 486 487 byte write_eeprom(int length) { 488 // here is a word address, so we use here*2 489 // this writes byte-by-byte, 490 // page writing may be faster (4 bytes at a time) 491 for (int x = 0; x < length; x++) { 492 spi_transaction(0xC0, 0x00, _addr*2+x, buff[x]); 493 delay(45); 494 } 495 return STK_OK; 496 } 497 498 void program_page() { 499 byte result = STK_FAILED; 500 int length = 256 * getch() + getch(); 501 if (length > 256) { 502 Serial.write(STK_FAILED); 503 error++; 504 return; 505 } 506 char memtype = (char)getch(); 507 // for (int x = 0; x < length; x++) { 508 // buff[x] = getch(); 509 // } 510 readbytes(length); 511 if (CRC_EOP == getch()) { 512 Serial.write(STK_INSYNC); 513 switch (memtype) { 514 case 'E': 515 result = (byte)write_eeprom(length); 516 break; 517 case 'F': 518 result = (byte)write_flash(length); 519 break; 520 } 521 Serial.write(result); 522 if (result != STK_OK) { 523 error++; 524 } 525 } 526 else { 527 Serial.write(STK_NOSYNC); 528 error++; 529 } 530 } 531 532 byte flash_read(byte hilo, int addr) { 533 return spi_transaction(0x20 + hilo * 8, 534 (addr >> 8) & 0xFF, 535 addr & 0xFF, 536 0); 537 } 538 539 char flash_read_page(int length) { 540 for (int x = 0; x < length; x+=2) { 541 byte low = flash_read(LOW, _addr); 542 Serial.write( low); 543 byte high = flash_read(HIGH, _addr); 544 Serial.write( high); 545 _addr++; 546 } 547 return STK_OK; 548 } 549 550 char eeprom_read_page(int length) { 551 // here again we have a word address 552 for (int x = 0; x < length; x++) { 553 byte ee = spi_transaction(0xA0, 0x00, _addr*2+x, 0xFF); 554 Serial.write( ee); 555 } 556 return STK_OK; 557 } 558 559 void read_page() { 560 byte result = (byte)STK_FAILED; 561 int length = 256 * getch() + getch(); 562 char memtype = getch(); 563 if (CRC_EOP != getch()) { 564 Serial.write(STK_NOSYNC); 565 return; 566 } 567 Serial.write(STK_INSYNC); 568 if (memtype == 'F') result = flash_read_page(length); 569 if (memtype == 'E') result = eeprom_read_page(length); 570 Serial.write(result); 571 return; 572 } 573 574 void read_signature() { 575 if (CRC_EOP != getch()) { 576 Serial.write(STK_NOSYNC); 577 error++; 578 return; 579 } 580 Serial.write(STK_INSYNC); 581 byte high = spi_transaction(0x30, 0x00, 0x00, 0x00); 582 Serial.write(high); 583 byte middle = spi_transaction(0x30, 0x00, 0x01, 0x00); 584 Serial.write(middle); 585 byte low = spi_transaction(0x30, 0x00, 0x02, 0x00); 586 Serial.write(low); 587 Serial.write(STK_OK); 588 } 589 ////////////////////////////////////////// 590 ////////////////////////////////////////// 591 592 593 //////////////////////////////////// 594 //////////////////////////////////// 595 596 int avrisp() { 597 byte data, low, high; 598 byte avrch = getch(); 599 switch (avrch) { 600 case STK_GET_SYNC: // get in sync 601 replyOK(); 602 break; 603 case STK_GET_SIGNON: // get sign on 604 if (getch() == CRC_EOP) { 605 Serial.write(STK_INSYNC); 606 Serial.write("AVR ISP"); 607 Serial.write(STK_OK); 608 } 609 break; 610 case STK_GET_PARM: // 0x41 611 get_parameter(getch()); 612 break; 613 case STK_SET_PARM: // 0x42 614 readbytes(20); 615 set_parameters(); 616 replyOK(); 617 break; 618 case STK_SET_PARM_EXT: // extended parameters - ignore for now 619 readbytes(5); 620 replyOK(); 621 break; 622 case STK_PMODE_START: // 0x50 623 beep(2272, 20); 624 start_pmode(); 625 replyOK(); 626 break; 627 case STK_PMODE_END: //0x51 628 beep(1912, 50); 629 error=0; 630 end_pmode(); 631 replyOK(); 632 break; 633 case STK_SET_ADDR: // 0x55 634 _addr = getch() + 256 * getch(); 635 replyOK(); 636 break; 637 case STK_UNIVERSAL: //UNIVERSAL 0x56 638 universal(); 639 break; 640 case STK_PROG_FLASH: //STK_PROG_FLASH ??? 641 low = getch(); 642 high = getch(); 643 replyOK(); 644 break; 645 case STK_PROG_DATA: //STK_PROG_DATA ??? 646 data = getch(); 647 replyOK(); 648 break; 649 case STK_PROG_PAGE: //STK_PROG_PAGE 650 // beep(1912, 20); 651 program_page(); 652 break; 653 case STK_READ_PAGE: //STK_READ_PAGE 654 read_page(); 655 break; 656 case STK_READ_SIGN: //STK_READ_SIGN 657 read_signature(); 658 break; 659 // expecting a command, not CRC_EOP 660 // this is how we can get back in sync 661 case CRC_EOP: 662 Serial.write(STK_NOSYNC); 663 break; 664 // anything else we will return STK_UNKNOWN 665 default: 666 if (CRC_EOP == getch()) 667 Serial.write(STK_UNKNOWN); 668 else 669 Serial.write(STK_NOSYNC); 670 } 671 } 672 673 // beep without using PWM 674 void beep(int tone, long duration){ 675 long elapsed = 0; 676 while (elapsed < (duration * 10000)) { 677 digitalWrite(PIEZO, HIGH); 678 delayMicroseconds(tone / 2); 679 digitalWrite(PIEZO, LOW); 680 delayMicroseconds(tone / 2); 681 // Keep track of how long we pulsed 682 elapsed += tone; 683 } 684 }