Advertisement
claudiusmarius

ArduinoISP_auto

May 30th, 2023
779
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 18.63 KB | None | 0 0
  1. // ArduinoISP_Auto_v2.0 - Modifications 2021 - Serge Ducatez
  2. // Copyright (c) 2008-2011 Randall Bohn
  3. // If you require a license, see
  4. // http://www.opensource.org/licenses/bsd-license.php
  5. //
  6. // This sketch turns the Arduino into a AVRISP using the following Arduino pins:
  7. //
  8. // Pin 10 is used to reset the target microcontroller.
  9. //
  10. // By default, the hardware SPI pins MISO, MOSI and SCK are used to communicate
  11. // with the target. On all Arduinos, these pins can be found
  12. // on the ICSP/SPI header:
  13. //
  14. //               MISO °. . 5V (!) Avoid this pin on Due, Zero...
  15. //               SCK   . . MOSI
  16. //                     . . GND
  17. //
  18. // On some Arduinos (Uno,...), pins MOSI, MISO and SCK are the same pins as
  19. // digital pin 11, 12 and 13, respectively. That is why many tutorials instruct
  20. // you to hook up the target to these pins. If you find this wiring more
  21. // practical, have a define USE_OLD_STYLE_WIRING. This will work even when not
  22. // using an Uno. (On an Uno this is not needed).
  23. //
  24. // Alternatively you can use any other digital pin by configuring
  25. // software ('BitBanged') SPI and having appropriate defines for PIN_MOSI,
  26. // PIN_MISO and PIN_SCK.
  27. //
  28. // IMPORTANT: When using an Arduino that is not 5V tolerant (Due, Zero, ...) as
  29. // the programmer, make sure to not expose any of the programmer's pins to 5V.
  30. // A simple way to accomplish this is to power the complete system (programmer
  31. // and target) at 3V3.
  32. //
  33. // Put an LED (with resistor) on the following pins:
  34. // 9: Heartbeat   - shows the programmer is running
  35. // 8: Error       - Lights up if something goes wrong (use red if that makes sense)
  36. // 7: Programming - In communication with the slave
  37. //
  38. //----------------------------------------------------------------------------------------
  39. // Fichier par Claude DUFOURMONT pour sa carte de développement ATTINY85
  40. // Vidéo DFT_#A91 PLATINE DE DEVELOPPEMENT POUR ATTINY85-NEW CONCEPT
  41. //https://youtu.be/x3gs_hjUjcw
  42. //----------------------------------------------------------------------------------------
  43.  
  44. #include "Arduino.h"
  45. #undef SERIAL
  46.  
  47. #define PROG_FLICKER true
  48.  
  49. unsigned long tempoLED_MODE_LOW = 0ul;
  50.  
  51. // Configure SPI clock (in Hz).
  52. // E.g. for an ATtiny @ 128 kHz: the datasheet states that both the high and low
  53. // SPI clock pulse must be > 2 CPU cycles, so take 3 cycles i.e. divide target
  54. // f_cpu by 6:
  55. //     #define SPI_CLOCK            (128000/6)
  56. //
  57. // A clock slow enough for an ATtiny85 @ 1 MHz, is a reasonable default:
  58.  
  59. #define SPI_CLOCK     (1000000/6)
  60.  
  61. // Select hardware or software SPI, depending on SPI clock.
  62. // Currently only for AVR, for other architectures (Due, Zero,...), hardware SPI
  63. // is probably too fast anyway.
  64.  
  65. #if defined(ARDUINO_ARCH_AVR)
  66.  
  67. #if SPI_CLOCK > (F_CPU / 128)
  68. #define USE_HARDWARE_SPI
  69. #endif
  70.  
  71. #endif
  72.  
  73. // Configure which pins to use:
  74.  
  75. // The standard pin configuration.
  76. #ifndef ARDUINO_HOODLOADER2
  77.  
  78. #define RESET      10 // Use pin 10 to reset the target rather than SS
  79. #define LED_HB      9
  80. #define LED_ERR     8
  81. #define LED_PMODE   7
  82. #define TOR_SWITCH 3
  83.  
  84. // Uncomment following line to use the old Uno style wiring
  85. // (using pin 11, 12 and 13 instead of the SPI header) on Leonardo, Due...
  86.  
  87. // #define USE_OLD_STYLE_WIRING
  88.  
  89. #ifdef USE_OLD_STYLE_WIRING
  90.  
  91. #define PIN_MOSI  11
  92. #define PIN_MISO  12
  93. #define PIN_SCK   13
  94.  
  95. #endif
  96.  
  97. // HOODLOADER2 means running sketches on the ATmega16U2 serial converter chips
  98. // on Uno or Mega boards. We must use pins that are broken out:
  99. #else
  100.  
  101. #define RESET       4
  102. #define LED_HB      7
  103. #define LED_ERR     6
  104. #define LED_PMODE   5
  105.  
  106. #endif
  107.  
  108. // By default, use hardware SPI pins:
  109. #ifndef PIN_MOSI
  110. #define PIN_MOSI  MOSI
  111. #endif
  112.  
  113. #ifndef PIN_MISO
  114. #define PIN_MISO  MISO
  115. #endif
  116.  
  117. #ifndef PIN_SCK
  118. #define PIN_SCK   SCK
  119. #endif
  120.  
  121. // Force bitbanged SPI if not using the hardware SPI pins:
  122. #if (PIN_MISO != MISO) ||  (PIN_MOSI != MOSI) || (PIN_SCK != SCK)
  123. #undef USE_HARDWARE_SPI
  124. #endif
  125.  
  126. // Configure the serial port to use.
  127. //
  128. // Prefer the USB virtual serial port (aka. native USB port), if the Arduino has one:
  129. //   - it does not autoreset (except for the magic baud rate of 1200).
  130. //   - it is more reliable because of USB handshaking.
  131. //
  132. // Leonardo and similar have an USB virtual serial port: 'Serial'.
  133. // Due and Zero have an USB virtual serial port: 'SerialUSB'.
  134. //
  135. // On the Due and Zero, 'Serial' can be used too, provided you disable autoreset.
  136. // To use 'Serial': #define SERIAL Serial
  137.  
  138. #ifdef SERIAL_PORT_USBVIRTUAL
  139. #define SERIAL SERIAL_PORT_USBVIRTUAL
  140. #else
  141. #define SERIAL Serial
  142. #endif
  143.  
  144. // Configure the baud rate:
  145.  
  146. #define BAUDRATE  19200
  147. // #define BAUDRATE 115200
  148. // #define BAUDRATE 1000000
  149.  
  150. #define HWVER 2
  151. #define SWMAJ 1
  152. #define SWMIN 18
  153.  
  154. // STK Definitions
  155. #define STK_OK      0x10
  156. #define STK_FAILED  0x11
  157. #define STK_UNKNOWN 0x12
  158. #define STK_INSYNC  0x14
  159. #define STK_NOSYNC  0x15
  160. #define CRC_EOP     0x20 //ok it is a space...
  161.  
  162. void pulse(int pin, int times);
  163.  
  164. #ifdef USE_HARDWARE_SPI
  165. #include "SPI.h"
  166. #else
  167.  
  168. #define SPI_MODE0 0x00
  169.  
  170. class SPISettings
  171. {
  172.   public:
  173.     // clock is in Hz
  174.     SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) : clock(clock)
  175.     {
  176.       (void) bitOrder;
  177.       (void) dataMode;
  178.     };
  179.  
  180.   private:
  181.     uint32_t clock;
  182.    
  183.     friend class BitBangedSPI;
  184. };
  185.  
  186. class BitBangedSPI
  187. {
  188.   public:
  189.     void begin()
  190.     {
  191.       digitalWrite(PIN_SCK, LOW);
  192.       digitalWrite(PIN_MOSI, LOW);
  193.       pinMode(PIN_SCK, OUTPUT);
  194.       pinMode(PIN_MOSI, OUTPUT);
  195.       pinMode(PIN_MISO, INPUT);
  196.     }
  197.    
  198.     void beginTransaction(SPISettings settings)
  199.     {
  200.       pulseWidth = (500000 + settings.clock - 1) / settings.clock;
  201.       if (pulseWidth == 0)
  202.         pulseWidth = 1;
  203.     }
  204.    
  205.     void end() {}
  206.    
  207.     uint8_t transfer (uint8_t b)
  208.     {
  209.       for (unsigned int i = 0; i < 8; ++i)
  210.       {
  211.         digitalWrite(PIN_MOSI, (b & 0x80) ? HIGH : LOW);
  212.         digitalWrite(PIN_SCK, HIGH);
  213.         delayMicroseconds(pulseWidth);
  214.         b = (b << 1) | digitalRead(PIN_MISO);
  215.         digitalWrite(PIN_SCK, LOW); // slow pulse
  216.         delayMicroseconds(pulseWidth);
  217.       }
  218.       return b;
  219.     }
  220.  
  221.   private:
  222.     unsigned long pulseWidth; // in microseconds
  223. };
  224.  
  225. static BitBangedSPI SPI;
  226.  
  227. #endif
  228.  
  229. void setup()
  230. {
  231.   SERIAL.begin(BAUDRATE);
  232.  
  233.   pinMode(LED_PMODE, OUTPUT);
  234.   pulse(LED_PMODE, 2);
  235.   pinMode(LED_ERR, OUTPUT);
  236.   pulse(LED_ERR, 2);
  237.   pinMode(LED_HB, OUTPUT);
  238.   pulse(LED_HB, 2);
  239.                                                                                 pinMode(TOR_SWITCH, OUTPUT);
  240. }
  241.  
  242. int error = 0;
  243. int pmode = 0;
  244.  
  245. // address for reading and writing, set by 'U' command
  246. unsigned int here;
  247. uint8_t buff[256]; // global block storage
  248.  
  249. #define beget16(addr) (*addr * 256 + *(addr+1) )
  250. typedef struct param
  251. {
  252.   uint8_t devicecode;
  253.   uint8_t revision;
  254.   uint8_t progtype;
  255.   uint8_t parmode;
  256.   uint8_t polling;
  257.   uint8_t selftimed;
  258.   uint8_t lockbytes;
  259.   uint8_t fusebytes;
  260.   uint8_t flashpoll;
  261.   uint16_t eeprompoll;
  262.   uint16_t pagesize;
  263.   uint16_t eepromsize;
  264.   uint32_t flashsize;
  265. }
  266. parameter;
  267.  
  268. parameter param;
  269.  
  270. // this provides a heartbeat on pin 9, so you can tell the software is running.
  271. uint8_t hbval = 128;
  272. int8_t hbdelta = 8;
  273.  
  274. void heartbeat()
  275. {
  276.   static unsigned long last_time = 0;
  277.   unsigned long now = millis();
  278.   if ((now - last_time) < 40)
  279.     return;
  280.   last_time = now;
  281.   if (hbval > 192) hbdelta = -hbdelta;
  282.   if (hbval < 32) hbdelta = -hbdelta;
  283.   hbval += hbdelta;
  284.   analogWrite(LED_HB, hbval);
  285. }
  286.  
  287. static bool rst_active_high;
  288.  
  289. void reset_target(bool reset)
  290. {
  291.   digitalWrite(RESET, ((reset && rst_active_high) || (!reset && !rst_active_high)) ? HIGH : LOW);
  292. }
  293.  
  294. void loop(void)
  295. {
  296.   // is pmode active?
  297.   if (pmode) {digitalWrite(LED_PMODE, HIGH);}
  298.   else {digitalWrite(LED_PMODE, LOW);}
  299.  
  300.   // is there an error?
  301.   if (error) {digitalWrite(LED_ERR, HIGH);} else {digitalWrite(LED_ERR, LOW);}
  302.  
  303.   // light the heartbeat LED
  304.   heartbeat();
  305.  
  306.   if (SERIAL.available())
  307.   {
  308.     tempoLED_MODE_LOW = millis();
  309.     digitalWrite(TOR_SWITCH, HIGH);                                       //Normal cad avec mosfet
  310.     //digitalWrite(TOR_SWITCH, LOW);                                          //Inversé cad sans mosfet
  311.     avrisp();
  312.   }
  313.   else
  314.   {
  315.     if (millis() - tempoLED_MODE_LOW > 2000ul && tempoLED_MODE_LOW != 0ul)
  316.     {
  317.       digitalWrite(TOR_SWITCH, LOW);                                      //Normal cad avec mosfet
  318.       //digitalWrite(TOR_SWITCH, HIGH);                                       //Inversé cad sans mosfet
  319.      
  320.       tempoLED_MODE_LOW = 0ul;
  321.     }
  322.   }
  323. }
  324.  
  325. uint8_t getch()
  326. {
  327.   while (!SERIAL.available());
  328.   return SERIAL.read();
  329. }
  330.  
  331. void fill(int n)
  332. {
  333.   for (int x = 0; x < n; x++) {buff[x] = getch();}
  334. }
  335.  
  336. #define PTIME 30
  337. void pulse(int pin, int times)
  338. {
  339.   do
  340.   {
  341.     digitalWrite(pin, HIGH);
  342.     delay(PTIME);
  343.     digitalWrite(pin, LOW);
  344.     delay(PTIME);
  345.   } while (times--);
  346. }
  347.  
  348. void prog_lamp(int state)
  349. {
  350.   if (PROG_FLICKER) {digitalWrite(LED_PMODE, state);}
  351. }
  352.  
  353. uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d)
  354. {
  355.   SPI.transfer(a);
  356.   SPI.transfer(b);
  357.   SPI.transfer(c);
  358.   return SPI.transfer(d);
  359. }
  360.  
  361. void empty_reply()
  362. {
  363.   if (CRC_EOP == getch())
  364.   {
  365.     SERIAL.print((char)STK_INSYNC);
  366.     SERIAL.print((char)STK_OK);
  367.   }
  368.   else
  369.   {
  370.     error++;
  371.     SERIAL.print((char)STK_NOSYNC);
  372.   }
  373. }
  374.  
  375. void breply(uint8_t b)
  376. {
  377.   if (CRC_EOP == getch())
  378.   {
  379.     SERIAL.print((char)STK_INSYNC);
  380.     SERIAL.print((char)b);
  381.     SERIAL.print((char)STK_OK);
  382.   }
  383.   else
  384.   {
  385.     error++;
  386.     SERIAL.print((char)STK_NOSYNC);
  387.   }
  388. }
  389.  
  390. void get_version(uint8_t c)
  391. {
  392.   switch (c)
  393.   {
  394.     case 0x80:
  395.       breply(HWVER);
  396.       break;
  397.     case 0x81:
  398.       breply(SWMAJ);
  399.       break;
  400.     case 0x82:
  401.       breply(SWMIN);
  402.       break;
  403.     case 0x93:
  404.       breply('S'); // serial programmer
  405.       break;
  406.     default:
  407.       breply(0);
  408.   }
  409. }
  410.  
  411. void set_parameters()
  412. {
  413.   // call this after reading parameter packet into buff[]
  414.   param.devicecode = buff[0];
  415.   param.revision   = buff[1];
  416.   param.progtype   = buff[2];
  417.   param.parmode    = buff[3];
  418.   param.polling    = buff[4];
  419.   param.selftimed  = buff[5];
  420.   param.lockbytes  = buff[6];
  421.   param.fusebytes  = buff[7];
  422.   param.flashpoll  = buff[8];
  423.   // ignore buff[9] (= buff[8])
  424.   // following are 16 bits (big endian)
  425.   param.eeprompoll = beget16(&buff[10]);
  426.   param.pagesize   = beget16(&buff[12]);
  427.   param.eepromsize = beget16(&buff[14]);
  428.  
  429.   // 32 bits flashsize (big endian)
  430.   param.flashsize = buff[16] * 0x01000000
  431.                     + buff[17] * 0x00010000
  432.                     + buff[18] * 0x00000100
  433.                     + buff[19];
  434.  
  435.   // AVR devices have active low reset, AT89Sx are active high
  436.   rst_active_high = (param.devicecode >= 0xe0);
  437. }
  438.  
  439. void start_pmode()
  440. {
  441.   // Reset target before driving PIN_SCK or PIN_MOSI
  442.  
  443.   // SPI.begin() will configure SS as output, so SPI master mode is selected.
  444.   // We have defined RESET as pin 10, which for many Arduinos is not the SS pin.
  445.   // So we have to configure RESET as output here,
  446.   // (reset_target() first sets the correct level)
  447.   reset_target(true);
  448.   pinMode(RESET, OUTPUT);
  449.   SPI.begin();
  450.   SPI.beginTransaction(SPISettings(SPI_CLOCK, MSBFIRST, SPI_MODE0));
  451.  
  452.   // See AVR datasheets, chapter "SERIAL_PRG Programming Algorithm":
  453.  
  454.   // Pulse RESET after PIN_SCK is low:
  455.   digitalWrite(PIN_SCK, LOW);
  456.   delay(20); // discharge PIN_SCK, value arbitrarily chosen
  457.   reset_target(false);
  458.   // Pulse must be minimum 2 target CPU clock cycles so 100 usec is ok for CPU
  459.   // speeds above 20 KHz
  460.   delayMicroseconds(100);
  461.   reset_target(true);
  462.  
  463.   // Send the enable programming command:
  464.   delay(50); // datasheet: must be > 20 msec
  465.   spi_transaction(0xAC, 0x53, 0x00, 0x00);
  466.   pmode = 1;
  467. }
  468.  
  469. void end_pmode()
  470. {
  471.   SPI.end();
  472.   // We're about to take the target out of reset so configure SPI pins as input
  473.   pinMode(PIN_MOSI, INPUT);
  474.   pinMode(PIN_SCK, INPUT);
  475.   reset_target(false);
  476.   pinMode(RESET, INPUT);
  477.   pmode = 0;
  478. }
  479.  
  480. void universal()
  481. {
  482.   uint8_t ch;
  483.  
  484.   fill(4);
  485.   ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
  486.   breply(ch);
  487. }
  488.  
  489. void flash(uint8_t hilo, unsigned int addr, uint8_t data)
  490. {
  491.   spi_transaction(0x40 + 8 * hilo,
  492.                   addr >> 8 & 0xFF,
  493.                   addr & 0xFF,
  494.                   data);
  495. }
  496.  
  497. void commit(unsigned int addr)
  498. {
  499.   if (PROG_FLICKER) {prog_lamp(LOW);}
  500.   spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
  501.   if (PROG_FLICKER)
  502.   {
  503.     delay(PTIME);
  504.     prog_lamp(HIGH);
  505.   }
  506. }
  507.  
  508. unsigned int current_page()
  509. {
  510.   if (param.pagesize == 32)
  511.   {
  512.     return here & 0xFFFFFFF0;
  513.   }
  514.   if (param.pagesize == 64)
  515.   {
  516.     return here & 0xFFFFFFE0;
  517.   }
  518.   if (param.pagesize == 128)
  519.   {
  520.     return here & 0xFFFFFFC0;
  521.   }
  522.   if (param.pagesize == 256)
  523.   {
  524.     return here & 0xFFFFFF80;
  525.   }
  526.   return here;
  527. }
  528.  
  529. void write_flash(int length)
  530. {
  531.   fill(length);
  532.   if (CRC_EOP == getch())
  533.   {
  534.     SERIAL.print((char) STK_INSYNC);
  535.     SERIAL.print((char) write_flash_pages(length));
  536.   }
  537.   else
  538.   {
  539.     error++;
  540.     SERIAL.print((char) STK_NOSYNC);
  541.   }
  542. }
  543.  
  544. uint8_t write_flash_pages(int length)
  545. {
  546.   int x = 0;
  547.   unsigned int page = current_page();
  548.   while (x < length) {
  549.     if (page != current_page())
  550.     {
  551.       commit(page);
  552.       page = current_page();
  553.     }
  554.     flash(LOW, here, buff[x++]);
  555.     flash(HIGH, here, buff[x++]);
  556.     here++;
  557.   }
  558.  
  559.   commit(page);
  560.  
  561.   return STK_OK;
  562. }
  563.  
  564. #define EECHUNK (32)
  565. uint8_t write_eeprom(unsigned int length)
  566. {
  567.   // here is a word address, get the byte address
  568.   unsigned int start = here * 2;
  569.   unsigned int remaining = length;
  570.   if (length > param.eepromsize)
  571.   {
  572.     error++;
  573.     return STK_FAILED;
  574.   }
  575.   while (remaining > EECHUNK)
  576.   {
  577.     write_eeprom_chunk(start, EECHUNK);
  578.     start += EECHUNK;
  579.     remaining -= EECHUNK;
  580.   }
  581.   write_eeprom_chunk(start, remaining);
  582.   return STK_OK;
  583. }
  584.  
  585. // write (length) bytes, (start) is a byte address
  586. uint8_t write_eeprom_chunk(unsigned int start, unsigned int length)
  587. {
  588.   // this writes byte-by-byte, page writing may be faster (4 bytes at a time)
  589.   fill(length);
  590.   prog_lamp(LOW);
  591.   for (unsigned int x = 0; x < length; x++)
  592.   {
  593.     unsigned int addr = start + x;
  594.     spi_transaction(0xC0, (addr >> 8) & 0xFF, addr & 0xFF, buff[x]);
  595.     delay(45);
  596.   }
  597.   prog_lamp(HIGH);
  598.   return STK_OK;
  599. }
  600.  
  601. void program_page()
  602. {
  603.   char result = (char) STK_FAILED;
  604.   unsigned int length = 256 * getch();
  605.   length += getch();
  606.   char memtype = getch();
  607.   // flash memory @here, (length) bytes
  608.   if (memtype == 'F')
  609.   {
  610.     write_flash(length);
  611.     return;
  612.   }
  613.   if (memtype == 'E')
  614.   {
  615.     result = (char)write_eeprom(length);
  616.     if (CRC_EOP == getch())
  617.     {
  618.       SERIAL.print((char) STK_INSYNC);
  619.       SERIAL.print(result);
  620.     }
  621.     else {
  622.       error++;
  623.       SERIAL.print((char) STK_NOSYNC);
  624.     }
  625.     return;
  626.   }
  627.   SERIAL.print((char)STK_FAILED);
  628.   return;
  629. }
  630.  
  631. uint8_t flash_read(uint8_t hilo, unsigned int addr)
  632. {
  633.   return spi_transaction(0x20 + hilo * 8,
  634.                          (addr >> 8) & 0xFF,
  635.                          addr & 0xFF,
  636.                          0);
  637. }
  638.  
  639. char flash_read_page(int length)
  640. {
  641.   for (int x = 0; x < length; x += 2)
  642.   {
  643.     uint8_t low = flash_read(LOW, here);
  644.     SERIAL.print((char) low);
  645.     uint8_t high = flash_read(HIGH, here);
  646.     SERIAL.print((char) high);
  647.     here++;
  648.   }
  649.   return STK_OK;
  650. }
  651.  
  652. char eeprom_read_page(int length)
  653. {
  654.   // here again we have a word address
  655.   int start = here * 2;
  656.   for (int x = 0; x < length; x++)
  657.   {
  658.     int addr = start + x;
  659.     uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF);
  660.     SERIAL.print((char) ee);
  661.   }
  662.   return STK_OK;
  663. }
  664.  
  665. void read_page()
  666. {
  667.   char result = (char)STK_FAILED;
  668.   int length = 256 * getch();
  669.   length += getch();
  670.   char memtype = getch();
  671.   if (CRC_EOP != getch())
  672.   {
  673.     error++;
  674.     SERIAL.print((char) STK_NOSYNC);
  675.     return;
  676.   }
  677.   SERIAL.print((char) STK_INSYNC);
  678.   if (memtype == 'F') result = flash_read_page(length);
  679.   if (memtype == 'E') result = eeprom_read_page(length);
  680.   SERIAL.print(result);
  681. }
  682.  
  683. void read_signature()
  684. {
  685.   if (CRC_EOP != getch())
  686.   {
  687.     error++;
  688.     SERIAL.print((char) STK_NOSYNC);
  689.     return;
  690.   }
  691.   SERIAL.print((char) STK_INSYNC);
  692.   uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00);
  693.   SERIAL.print((char) high);
  694.   uint8_t middle = spi_transaction(0x30, 0x00, 0x01, 0x00);
  695.   SERIAL.print((char) middle);
  696.   uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00);
  697.   SERIAL.print((char) low);
  698.   SERIAL.print((char) STK_OK);
  699. }
  700. //////////////////////////////////////////
  701. //////////////////////////////////////////
  702.  
  703. /////////////////////////////////////////
  704. /////////////////////////////////////////
  705. void avrisp()
  706. {
  707.   uint8_t ch = getch();
  708.   switch (ch)
  709.   {
  710.     case '0': // signon
  711.       error = 0;
  712.       empty_reply();
  713.       break;
  714.     case '1':
  715.       if (getch() == CRC_EOP)
  716.       {
  717.         SERIAL.print((char) STK_INSYNC);
  718.         SERIAL.print("AVR ISP");
  719.         SERIAL.print((char) STK_OK);
  720.       }
  721.       else
  722.       {
  723.         error++;
  724.         SERIAL.print((char) STK_NOSYNC);
  725.       }
  726.       break;
  727.     case 'A':
  728.       get_version(getch());
  729.       break;
  730.     case 'B':
  731.       fill(20);
  732.       set_parameters();
  733.       empty_reply();
  734.       break;
  735.     case 'E': // extended parameters - ignore for now
  736.       fill(5);
  737.       empty_reply();
  738.       break;
  739.     case 'P':
  740.       if (!pmode)
  741.         start_pmode();
  742.       empty_reply();
  743.       break;
  744.     case 'U': // set address (word)
  745.       here = getch();
  746.       here += 256 * getch();
  747.       empty_reply();
  748.       break;
  749.    
  750.     case 0x60: //STK_PROG_FLASH
  751.       getch(); // low addr
  752.       getch(); // high addr
  753.       empty_reply();
  754.       break;
  755.     case 0x61: //STK_PROG_DATA
  756.       getch(); // data
  757.       empty_reply();
  758.       break;
  759.    
  760.     case 0x64: //STK_PROG_PAGE
  761.       program_page();
  762.       break;
  763.    
  764.     case 0x74: //STK_READ_PAGE 't'
  765.       read_page();
  766.       break;
  767.    
  768.     case 'V': //0x56
  769.       universal();
  770.       break;
  771.     case 'Q': //0x51
  772.       error = 0;
  773.       end_pmode();
  774.       empty_reply();
  775.       break;
  776.    
  777.     case 0x75: //STK_READ_SIGN 'u'
  778.       read_signature();
  779.       break;
  780.    
  781.     // expecting a command, not CRC_EOP
  782.     // this is how we can get back in sync
  783.     case CRC_EOP:
  784.       error++;
  785.       SERIAL.print((char) STK_NOSYNC);
  786.       break;
  787.    
  788.     // anything else we will return STK_UNKNOWN
  789.     default:
  790.       error++;
  791.       if (CRC_EOP == getch())
  792.         SERIAL.print((char)STK_UNKNOWN);
  793.       else
  794.         SERIAL.print((char)STK_NOSYNC);
  795.   }
  796. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement