<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://w.electrodragon.com/w/index.php?action=history&amp;feed=atom&amp;title=ArduinoISP</id>
	<title>ArduinoISP - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://w.electrodragon.com/w/index.php?action=history&amp;feed=atom&amp;title=ArduinoISP"/>
	<link rel="alternate" type="text/html" href="https://w.electrodragon.com/w/index.php?title=ArduinoISP&amp;action=history"/>
	<updated>2026-07-21T20:04:00Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.37.2</generator>
	<entry>
		<id>https://w.electrodragon.com/w/index.php?title=ArduinoISP&amp;diff=32438&amp;oldid=prev</id>
		<title>Chao at 07:05, 14 December 2021</title>
		<link rel="alternate" type="text/html" href="https://w.electrodragon.com/w/index.php?title=ArduinoISP&amp;diff=32438&amp;oldid=prev"/>
		<updated>2021-12-14T07:05:43Z</updated>

		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Troubleshooting of &amp;quot;programmer is not in sync&amp;quot; ==&lt;br /&gt;
* Try to use different version of arduino IDE, arduino IDE 1.0 with UNO will cause this problem.&lt;br /&gt;
* Double check all the connections&lt;br /&gt;
* The receive side of arduino is out of buffer, if you are using the official &amp;quot;arduinoISP&amp;quot; in the arduino IDE examples folder, please try to use the following code. This will solve the problem too:&lt;br /&gt;
 avrdude.exe: stk500_paged_write(): (a) protocol error, expect=0x14, resp=0x64&lt;br /&gt;
 avrdude.exe: stk500_cmd(): programmer is out of sync&lt;br /&gt;
== Main Sketch (Retired Code) ==&lt;br /&gt;
* Replace the A0 pin with pin 7, which is programming pin.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;Arduino&amp;quot;&amp;gt;&lt;br /&gt;
// this sketch turns the Arduino into a AVRISP&lt;br /&gt;
// using the following pins:&lt;br /&gt;
// 10: slave reset&lt;br /&gt;
// 11: MOSI&lt;br /&gt;
// 12: MISO&lt;br /&gt;
// 13: SCK&lt;br /&gt;
&lt;br /&gt;
// Put an LED (with resistor) on the following pins:&lt;br /&gt;
//  8: Error - Lights up if something goes wrong (use red if that makes sense)&lt;br /&gt;
// A0: Programming - In communication with the slave&lt;br /&gt;
//  6: Heartbeat - shows the programmer is running (removed, see notes below)&lt;br /&gt;
// Optional - Piezo speaker on pin A3&lt;br /&gt;
//&lt;br /&gt;
// October 2009 by David A. Mellis&lt;br /&gt;
// - Added support for the read signature command&lt;br /&gt;
// &lt;br /&gt;
// February 2009 by Randall Bohn&lt;br /&gt;
// - Added support for writing to EEPROM (what took so long?)&lt;br /&gt;
// Windows users should consider WinAVR's avrdude instead of the&lt;br /&gt;
// avrdude included with Arduino software.&lt;br /&gt;
//&lt;br /&gt;
// January 2008 by Randall Bohn&lt;br /&gt;
// - Thanks to Amplificar for helping me with the STK500 protocol&lt;br /&gt;
// - The AVRISP/STK500 (mk I) protocol is used in the arduino bootloader&lt;br /&gt;
// - The SPI functions herein were developed for the AVR910_ARD programmer &lt;br /&gt;
// - More information at http://code.google.com/p/mega-isp&lt;br /&gt;
//&lt;br /&gt;
// March 2012 - William Phelps&lt;br /&gt;
// modify to work with Arduino IDE 1.0 which has a shorter serial port receive buffer&lt;br /&gt;
// getEOP() now gets entire request before avrisp() is called to process it&lt;br /&gt;
// Serial.print((char) xxx) changed to Serial.write(xxx)&lt;br /&gt;
// uint8_t changed to byte&lt;br /&gt;
// added support for Piezo speaker&lt;br /&gt;
// moved Pmode LED to A0&lt;br /&gt;
// removed &amp;quot;heartbeat&amp;quot; on pin 6, added short blip of ERROR LED instead &lt;br /&gt;
// Why is it that PROG_FLASH and PROG_DATA don't actually do anything???&lt;br /&gt;
// Tested with Arduino IDE 22 and 1.0&lt;br /&gt;
// IDE 22 - 5148 bytes&lt;br /&gt;
// IDE 1.0 - 5524 bytes!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// SLOW SPEED CHIP ERASE AND FUSE BURNING&lt;br /&gt;
//&lt;br /&gt;
// Enable LOW_SPEED to allow you to erase chips that would fail otherwise,&lt;br /&gt;
// for being running with a clock too slow for the programmer.&lt;br /&gt;
//&lt;br /&gt;
// This allowed me to recover several ATMega328 that had no boot loader and the&lt;br /&gt;
// first instruction was to set the clock to the slowest speed. Usually this&lt;br /&gt;
// kind of recovery requires high voltage programming, but this trick will do&lt;br /&gt;
// just fine.&lt;br /&gt;
//&lt;br /&gt;
// How to proceed:&lt;br /&gt;
// 1. Enable LOW_SPEED, and load it to the programmer.&lt;br /&gt;
// 2. Erase and burn the fuses on the target uC. Example for ATMega328:&lt;br /&gt;
//   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&lt;br /&gt;
// 3. Comment LOW_SPEED and load it back to the programmer.&lt;br /&gt;
// 4. Program the target uC as usual. Example:&lt;br /&gt;
//  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 &lt;br /&gt;
//&lt;br /&gt;
// Note 1: EXTRA_SPI_DELAY was added to let you slow down SPI even more. You can&lt;br /&gt;
// play with the value if it does not work with the default.&lt;br /&gt;
// Note 2: LOW_SPEED will alow you only to erase the chip and burn the fuses! It&lt;br /&gt;
// will fail if you try to program the target uC this way!&lt;br /&gt;
&lt;br /&gt;
//#define LOW_SPEED&lt;br /&gt;
#ifdef LOW_SPEED&lt;br /&gt;
#define EXTRA_SPI_DELAY 125&lt;br /&gt;
#else&lt;br /&gt;
#define EXTRA_SPI_DELAY 0&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;pins_arduino.h&amp;quot;  // defines SS,MOSI,MISO,SCK&lt;br /&gt;
#define RESET SS&lt;br /&gt;
&lt;br /&gt;
#define LED_ERR 8&lt;br /&gt;
#define LED_PMODE A0&lt;br /&gt;
//#define LED_HB 6&lt;br /&gt;
#define PIEZO A3&lt;br /&gt;
&lt;br /&gt;
#define HWVER 2&lt;br /&gt;
#define SWMAJ 1&lt;br /&gt;
#define SWMIN 18&lt;br /&gt;
&lt;br /&gt;
// STK Definitions&lt;br /&gt;
const byte STK_OK = 0x10;&lt;br /&gt;
const byte STK_FAILED = 0x11;&lt;br /&gt;
const byte STK_UNKNOWN = 0x12;&lt;br /&gt;
const byte STK_INSYNC = 0x14;&lt;br /&gt;
const byte STK_NOSYNC = 0x15;&lt;br /&gt;
const byte CRC_EOP = 0x20; //ok it is a space...&lt;br /&gt;
&lt;br /&gt;
const byte STK_GET_SYNC     = 0x30;&lt;br /&gt;
const byte STK_GET_SIGNON   = 0x31;&lt;br /&gt;
const byte STK_GET_PARM     = 0x41;&lt;br /&gt;
const byte STK_SET_PARM     = 0x42;&lt;br /&gt;
const byte STK_SET_PARM_EXT = 0x45;&lt;br /&gt;
const byte STK_PMODE_START  = 0x50;&lt;br /&gt;
const byte STK_PMODE_END    = 0x51;&lt;br /&gt;
const byte STK_SET_ADDR     = 0x55;&lt;br /&gt;
const byte STK_UNIVERSAL    = 0x56;&lt;br /&gt;
const byte STK_PROG_FLASH   = 0x60;&lt;br /&gt;
const byte STK_PROG_DATA    = 0x61;&lt;br /&gt;
const byte STK_PROG_PAGE    = 0x64;&lt;br /&gt;
const byte STK_READ_PAGE    = 0x74;&lt;br /&gt;
const byte STK_READ_SIGN    = 0x75;&lt;br /&gt;
&lt;br /&gt;
//// TONES  ==========================================&lt;br /&gt;
//// Start by defining the relationship between&lt;br /&gt;
////       note, period, &amp;amp;  frequency.&lt;br /&gt;
//#define  c     3830    // 261 Hz&lt;br /&gt;
//#define  d     3400    // 294 Hz&lt;br /&gt;
//#define  e     3038    // 329 Hz&lt;br /&gt;
//#define  f     2864    // 349 Hz&lt;br /&gt;
//#define  g     2550    // 392 Hz&lt;br /&gt;
//#define  a     2272    // 440 Hz&lt;br /&gt;
//#define  b     2028    // 493 Hz&lt;br /&gt;
//#define  C     1912    // 523 Hz &lt;br /&gt;
&lt;br /&gt;
//void pulse(int pin, int times);&lt;br /&gt;
&lt;br /&gt;
int error=0;&lt;br /&gt;
int pmode=0;&lt;br /&gt;
// address for reading and writing, set by STK_SET_ADDR command&lt;br /&gt;
int _addr;&lt;br /&gt;
byte _buffer[256]; // serial port buffer&lt;br /&gt;
int pBuffer = 0;  // buffer pointer&lt;br /&gt;
int iBuffer = 0;  // buffer index&lt;br /&gt;
byte buff[256];  // temporary buffer&lt;br /&gt;
boolean EOP_SEEN = false;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
&lt;br /&gt;
  Serial.begin(19200);&lt;br /&gt;
  pinMode(PIEZO, OUTPUT);&lt;br /&gt;
  beep(1700, 40);&lt;br /&gt;
  EOP_SEEN = false;&lt;br /&gt;
  iBuffer = pBuffer = 0;&lt;br /&gt;
&lt;br /&gt;
  pinMode(LED_PMODE, OUTPUT);&lt;br /&gt;
  pulse(LED_PMODE, 2);&lt;br /&gt;
  pinMode(LED_ERR, OUTPUT);&lt;br /&gt;
  pulse(LED_ERR, 2);&lt;br /&gt;
//  pinMode(LED_HB, OUTPUT);&lt;br /&gt;
//  pulse(LED_HB, 2);&lt;br /&gt;
  &lt;br /&gt;
  pinMode(9, OUTPUT);&lt;br /&gt;
  // setup high freq PWM on pin 9 (timer 1)&lt;br /&gt;
  // 50% duty cycle -&amp;gt; 8 MHz&lt;br /&gt;
  OCR1A = 0;&lt;br /&gt;
  ICR1 = 1;&lt;br /&gt;
  // OC1A output, fast PWM&lt;br /&gt;
  TCCR1A = _BV(WGM11) | _BV(COM1A1);&lt;br /&gt;
  TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // no clock prescale&lt;br /&gt;
  &lt;br /&gt;
 &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#define beget16(addr) (*addr * 256 + *(addr+1) )&lt;br /&gt;
typedef struct param {&lt;br /&gt;
  byte devicecode;&lt;br /&gt;
  byte revision;&lt;br /&gt;
  byte progtype;&lt;br /&gt;
  byte parmode;&lt;br /&gt;
  byte polling;&lt;br /&gt;
  byte selftimed;&lt;br /&gt;
  byte lockbytes;&lt;br /&gt;
  byte fusebytes;&lt;br /&gt;
  int flashpoll;&lt;br /&gt;
  int eeprompoll;&lt;br /&gt;
  int pagesize;&lt;br /&gt;
  int eepromsize;&lt;br /&gt;
  int flashsize;&lt;br /&gt;
} &lt;br /&gt;
parameter;&lt;br /&gt;
&lt;br /&gt;
parameter param;&lt;br /&gt;
&lt;br /&gt;
// this provides a heartbeat on pin 6, so you can tell the software is running.&lt;br /&gt;
//byte hbval=128;&lt;br /&gt;
//int8_t hbdelta=4;&lt;br /&gt;
//void heartbeat() {&lt;br /&gt;
////  if (hbval &amp;gt; 192) hbdelta = -hbdelta;&lt;br /&gt;
////  if (hbval &amp;lt; 32) hbdelta = -hbdelta;&lt;br /&gt;
//  if (hbval &amp;gt; 250) hbdelta = -hbdelta;&lt;br /&gt;
//  if (hbval &amp;lt; 10) hbdelta = -hbdelta;&lt;br /&gt;
//  hbval += hbdelta;&lt;br /&gt;
//  analogWrite(LED_HB, hbval);&lt;br /&gt;
//  delay(20);&lt;br /&gt;
//}&lt;br /&gt;
  &lt;br /&gt;
void getEOP() {&lt;br /&gt;
  int minL = 0;&lt;br /&gt;
  byte avrch = 0;&lt;br /&gt;
  byte bl = 0;&lt;br /&gt;
  while (!EOP_SEEN) {&lt;br /&gt;
    while (Serial.available()&amp;gt;0) {&lt;br /&gt;
      byte ch = Serial.read();&lt;br /&gt;
      _buffer[iBuffer] = ch;&lt;br /&gt;
      iBuffer = (++iBuffer)%256;  // increment and wrap&lt;br /&gt;
      if (iBuffer == 1)  avrch = ch;  // save command&lt;br /&gt;
      if ((avrch == STK_PROG_PAGE) &amp;amp;&amp;amp; (iBuffer==3)) {&lt;br /&gt;
        minL = 256*_buffer[1] + _buffer[2] + 4;&lt;br /&gt;
      }&lt;br /&gt;
      if ((iBuffer&amp;gt;minL) &amp;amp;&amp;amp; (ch == CRC_EOP)) {&lt;br /&gt;
        EOP_SEEN = true;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    if (!EOP_SEEN) {&lt;br /&gt;
//      heartbeat(); // light the heartbeat LED&lt;br /&gt;
      if (bl == 100) {&lt;br /&gt;
        pulse(LED_ERR,1,10);  // blink the red LED&lt;br /&gt;
        bl = 0;&lt;br /&gt;
      }&lt;br /&gt;
      bl++;&lt;br /&gt;
      delay(10);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// serialEvent not used so sketch would be compatible with older IDE versions&lt;br /&gt;
//void serialEvent() {&lt;br /&gt;
//  int minL = 0;&lt;br /&gt;
//  byte avrch = 0;&lt;br /&gt;
//  while (Serial.available()&amp;gt;0)&lt;br /&gt;
//  {&lt;br /&gt;
//    byte ch = Serial.read();&lt;br /&gt;
//    _buffer[iBuffer] = ch;&lt;br /&gt;
//    iBuffer = (++iBuffer)%256;  // increment and wrap&lt;br /&gt;
//    if (iBuffer == 1)  avrch = ch;  // save command&lt;br /&gt;
//    if ((avrch == STK_PROG_PAGE) &amp;amp;&amp;amp; (iBuffer==3)) {&lt;br /&gt;
//      minL = 256*_buffer[1] + _buffer[2] + 4;&lt;br /&gt;
//    }&lt;br /&gt;
//    if ((iBuffer&amp;gt;minL) &amp;amp;&amp;amp; (ch == CRC_EOP)) {&lt;br /&gt;
//      EOP_SEEN = true;&lt;br /&gt;
//    }&lt;br /&gt;
//  }&lt;br /&gt;
//}&lt;br /&gt;
&lt;br /&gt;
void loop(void) {&lt;br /&gt;
  // is pmode active?&lt;br /&gt;
//  if (pmode) digitalWrite(LED_PMODE, HIGH); &lt;br /&gt;
//  else digitalWrite(LED_PMODE, LOW);&lt;br /&gt;
  digitalWrite(LED_PMODE, LOW);&lt;br /&gt;
  // is there an error?&lt;br /&gt;
  if (error) digitalWrite(LED_ERR, HIGH); &lt;br /&gt;
  else digitalWrite(LED_ERR, LOW);&lt;br /&gt;
&lt;br /&gt;
  getEOP();&lt;br /&gt;
  &lt;br /&gt;
  // have we received a complete request?  (ends with CRC_EOP)&lt;br /&gt;
  if (EOP_SEEN) {&lt;br /&gt;
    digitalWrite(LED_PMODE, HIGH);&lt;br /&gt;
    EOP_SEEN = false;&lt;br /&gt;
    avrisp();&lt;br /&gt;
    iBuffer = pBuffer = 0;  // restart buffer&lt;br /&gt;
  }&lt;br /&gt;
  &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
byte getch() {&lt;br /&gt;
  if (pBuffer == iBuffer) {  // spin until data available ???&lt;br /&gt;
    pulse(LED_ERR, 1);&lt;br /&gt;
    beep(1700, 20);&lt;br /&gt;
    error++;&lt;br /&gt;
    return -1;&lt;br /&gt;
  }&lt;br /&gt;
  byte ch = _buffer[pBuffer];  // get next char&lt;br /&gt;
  pBuffer = (++pBuffer)%256;  // increment and wrap&lt;br /&gt;
  return ch;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void readbytes(int n) {&lt;br /&gt;
  for (int x = 0; x &amp;lt; n; x++) {&lt;br /&gt;
    buff[x] = getch();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//#define PTIME 20&lt;br /&gt;
void pulse(int pin, int times, int ptime) {&lt;br /&gt;
  do {&lt;br /&gt;
    digitalWrite(pin, HIGH);&lt;br /&gt;
    delay(ptime);&lt;br /&gt;
    digitalWrite(pin, LOW);&lt;br /&gt;
    delay(ptime);&lt;br /&gt;
    times--;&lt;br /&gt;
  } &lt;br /&gt;
  while (times &amp;gt; 0);&lt;br /&gt;
}&lt;br /&gt;
void pulse(int pin, int times) {&lt;br /&gt;
  pulse(pin, times, 50);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void spi_init() {&lt;br /&gt;
  byte x;&lt;br /&gt;
  SPCR = 0x53;&lt;br /&gt;
#ifdef LOW_SPEED&lt;br /&gt;
SPCR=SPCR|B00000011;&lt;br /&gt;
#endif&lt;br /&gt;
  x=SPSR;&lt;br /&gt;
  x=SPDR;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void spi_wait() {&lt;br /&gt;
  do {&lt;br /&gt;
  } &lt;br /&gt;
  while (!(SPSR &amp;amp; (1 &amp;lt;&amp;lt; SPIF)));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
byte spi_send(byte b) {&lt;br /&gt;
  byte reply;&lt;br /&gt;
#ifdef LOW_SPEED&lt;br /&gt;
    cli();&lt;br /&gt;
    CLKPR=B10000000;&lt;br /&gt;
    CLKPR=B00000011;&lt;br /&gt;
    sei();&lt;br /&gt;
#endif&lt;br /&gt;
  SPDR=b;&lt;br /&gt;
  spi_wait();&lt;br /&gt;
  reply = SPDR;&lt;br /&gt;
#ifdef LOW_SPEED&lt;br /&gt;
    cli();&lt;br /&gt;
    CLKPR=B10000000;&lt;br /&gt;
    CLKPR=B00000000;&lt;br /&gt;
   sei();&lt;br /&gt;
#endif&lt;br /&gt;
    return reply;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
byte spi_transaction(byte a, byte b, byte c, byte d) {&lt;br /&gt;
  byte n;&lt;br /&gt;
  spi_send(a); &lt;br /&gt;
  n=spi_send(b);&lt;br /&gt;
  //if (n != a) error = -1;&lt;br /&gt;
  n=spi_send(c);&lt;br /&gt;
  return spi_send(d);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void replyOK() {&lt;br /&gt;
//  if (EOP_SEEN == true) {&lt;br /&gt;
  if (CRC_EOP == getch()) {  // EOP should be next char&lt;br /&gt;
    Serial.write(STK_INSYNC);&lt;br /&gt;
    Serial.write(STK_OK);&lt;br /&gt;
  } &lt;br /&gt;
  else {&lt;br /&gt;
    pulse(LED_ERR, 2);&lt;br /&gt;
    Serial.write(STK_NOSYNC);&lt;br /&gt;
    error++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void breply(byte b) {&lt;br /&gt;
  if (CRC_EOP == getch()) {  // EOP should be next char&lt;br /&gt;
    Serial.write(STK_INSYNC);&lt;br /&gt;
    Serial.write(b);&lt;br /&gt;
    Serial.write(STK_OK);&lt;br /&gt;
  } &lt;br /&gt;
  else {&lt;br /&gt;
    Serial.write(STK_NOSYNC);&lt;br /&gt;
    error++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void get_parameter(byte c) {&lt;br /&gt;
  switch(c) {&lt;br /&gt;
  case 0x80:&lt;br /&gt;
    breply(HWVER);&lt;br /&gt;
    break;&lt;br /&gt;
  case 0x81:&lt;br /&gt;
    breply(SWMAJ);&lt;br /&gt;
    break;&lt;br /&gt;
  case 0x82:&lt;br /&gt;
    breply(SWMIN);&lt;br /&gt;
    break;&lt;br /&gt;
  case 0x93:&lt;br /&gt;
    breply('S'); // serial programmer&lt;br /&gt;
    break;&lt;br /&gt;
  default:&lt;br /&gt;
    breply(0);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void set_parameters() {&lt;br /&gt;
  // call this after reading paramter packet into buff[]&lt;br /&gt;
  param.devicecode = buff[0];&lt;br /&gt;
  param.revision = buff[1];&lt;br /&gt;
  param.progtype = buff[2];&lt;br /&gt;
  param.parmode = buff[3];&lt;br /&gt;
  param.polling = buff[4];&lt;br /&gt;
  param.selftimed = buff[5];&lt;br /&gt;
  param.lockbytes = buff[6];&lt;br /&gt;
  param.fusebytes = buff[7];&lt;br /&gt;
  param.flashpoll = buff[8]; &lt;br /&gt;
  // ignore buff[9] (= buff[8])&lt;br /&gt;
  //getch(); // discard second value&lt;br /&gt;
  &lt;br /&gt;
  // WARNING: not sure about the byte order of the following&lt;br /&gt;
  // following are 16 bits (big endian)&lt;br /&gt;
  param.eeprompoll = beget16(&amp;amp;buff[10]);&lt;br /&gt;
  param.pagesize = beget16(&amp;amp;buff[12]);&lt;br /&gt;
  param.eepromsize = beget16(&amp;amp;buff[14]);&lt;br /&gt;
&lt;br /&gt;
  // 32 bits flashsize (big endian)&lt;br /&gt;
  param.flashsize = buff[16] * 0x01000000&lt;br /&gt;
    + buff[17] * 0x00010000&lt;br /&gt;
    + buff[18] * 0x00000100&lt;br /&gt;
    + buff[19];&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void start_pmode() {&lt;br /&gt;
  spi_init();&lt;br /&gt;
  // following delays may not work on all targets...&lt;br /&gt;
  pinMode(RESET, OUTPUT);&lt;br /&gt;
  digitalWrite(RESET, HIGH);&lt;br /&gt;
  pinMode(SCK, OUTPUT);&lt;br /&gt;
  digitalWrite(SCK, LOW);&lt;br /&gt;
  delay(50+EXTRA_SPI_DELAY);&lt;br /&gt;
  digitalWrite(RESET, LOW);&lt;br /&gt;
  delay(50+EXTRA_SPI_DELAY);&lt;br /&gt;
  pinMode(MISO, INPUT);&lt;br /&gt;
  pinMode(MOSI, OUTPUT);&lt;br /&gt;
  spi_transaction(0xAC, 0x53, 0x00, 0x00);&lt;br /&gt;
  pmode = 1;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void end_pmode() {&lt;br /&gt;
  pinMode(MISO, INPUT);&lt;br /&gt;
  pinMode(MOSI, INPUT);&lt;br /&gt;
  pinMode(SCK, INPUT);&lt;br /&gt;
  pinMode(RESET, INPUT);&lt;br /&gt;
  pmode = 0;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void universal() {&lt;br /&gt;
//  int w;&lt;br /&gt;
  byte ch;&lt;br /&gt;
//  for (w = 0; w &amp;lt; 4; w++) {&lt;br /&gt;
//    buff[w] = getch();&lt;br /&gt;
//  }&lt;br /&gt;
  readbytes(4);&lt;br /&gt;
  ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);&lt;br /&gt;
  breply(ch);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void flash(byte hilo, int addr, byte data) {&lt;br /&gt;
  spi_transaction(0x40+8*hilo, addr&amp;gt;&amp;gt;8 &amp;amp; 0xFF, addr &amp;amp; 0xFF, data);&lt;br /&gt;
}&lt;br /&gt;
void commit(int addr) {&lt;br /&gt;
  spi_transaction(0x4C, (addr &amp;gt;&amp;gt; 8) &amp;amp; 0xFF, addr &amp;amp; 0xFF, 0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
//#define _current_page(x) (here &amp;amp; 0xFFFFE0)&lt;br /&gt;
int current_page(int addr) {&lt;br /&gt;
  if (param.pagesize == 32) return addr &amp;amp; 0xFFFFFFF0;&lt;br /&gt;
  if (param.pagesize == 64) return addr &amp;amp; 0xFFFFFFE0;&lt;br /&gt;
  if (param.pagesize == 128) return addr &amp;amp; 0xFFFFFFC0;&lt;br /&gt;
  if (param.pagesize == 256) return addr &amp;amp; 0xFFFFFF80;&lt;br /&gt;
  return addr;&lt;br /&gt;
}&lt;br /&gt;
byte write_flash(int length) {&lt;br /&gt;
  if (param.pagesize &amp;lt; 1) {&lt;br /&gt;
    return STK_FAILED;&lt;br /&gt;
  }&lt;br /&gt;
  //if (param.pagesize != 64) return STK_FAILED;&lt;br /&gt;
  int page = current_page(_addr);&lt;br /&gt;
  int x = 0;&lt;br /&gt;
  while (x &amp;lt; length) {&lt;br /&gt;
    if (page != current_page(_addr)) {&lt;br /&gt;
      commit(page);&lt;br /&gt;
      page = current_page(_addr);&lt;br /&gt;
    }&lt;br /&gt;
    flash(LOW, _addr, buff[x++]);&lt;br /&gt;
    flash(HIGH, _addr, buff[x++]);&lt;br /&gt;
    _addr++;&lt;br /&gt;
  }&lt;br /&gt;
  commit(page);&lt;br /&gt;
  return STK_OK;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
byte write_eeprom(int length) {&lt;br /&gt;
  // here is a word address, so we use here*2&lt;br /&gt;
  // this writes byte-by-byte,&lt;br /&gt;
  // page writing may be faster (4 bytes at a time)&lt;br /&gt;
  for (int x = 0; x &amp;lt; length; x++) {&lt;br /&gt;
    spi_transaction(0xC0, 0x00, _addr*2+x, buff[x]);&lt;br /&gt;
    delay(45);&lt;br /&gt;
  } &lt;br /&gt;
  return STK_OK;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void program_page() {&lt;br /&gt;
  byte result = STK_FAILED;&lt;br /&gt;
  int length = 256 * getch() + getch();&lt;br /&gt;
  if (length &amp;gt; 256) {&lt;br /&gt;
      Serial.write(STK_FAILED);&lt;br /&gt;
      error++;&lt;br /&gt;
      return;&lt;br /&gt;
  }&lt;br /&gt;
  char memtype = (char)getch();&lt;br /&gt;
//  for (int x = 0; x &amp;lt; length; x++) {&lt;br /&gt;
//    buff[x] = getch();&lt;br /&gt;
//  }&lt;br /&gt;
  readbytes(length);&lt;br /&gt;
  if (CRC_EOP == getch()) {&lt;br /&gt;
    Serial.write(STK_INSYNC);&lt;br /&gt;
    switch (memtype) {&lt;br /&gt;
      case 'E':&lt;br /&gt;
        result = (byte)write_eeprom(length);&lt;br /&gt;
        break;&lt;br /&gt;
      case 'F':&lt;br /&gt;
        result = (byte)write_flash(length);&lt;br /&gt;
        break;&lt;br /&gt;
    }&lt;br /&gt;
    Serial.write(result);&lt;br /&gt;
    if (result != STK_OK) {&lt;br /&gt;
      error++;&lt;br /&gt;
    }&lt;br /&gt;
  } &lt;br /&gt;
  else {&lt;br /&gt;
    Serial.write(STK_NOSYNC);&lt;br /&gt;
    error++;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
byte flash_read(byte hilo, int addr) {&lt;br /&gt;
  return spi_transaction(0x20 + hilo * 8,&lt;br /&gt;
    (addr &amp;gt;&amp;gt; 8) &amp;amp; 0xFF,&lt;br /&gt;
    addr &amp;amp; 0xFF,&lt;br /&gt;
    0);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
char flash_read_page(int length) {&lt;br /&gt;
  for (int x = 0; x &amp;lt; length; x+=2) {&lt;br /&gt;
    byte low = flash_read(LOW, _addr);&lt;br /&gt;
    Serial.write( low);&lt;br /&gt;
    byte high = flash_read(HIGH, _addr);&lt;br /&gt;
    Serial.write( high);&lt;br /&gt;
    _addr++;&lt;br /&gt;
  }&lt;br /&gt;
  return STK_OK;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
char eeprom_read_page(int length) {&lt;br /&gt;
  // here again we have a word address&lt;br /&gt;
  for (int x = 0; x &amp;lt; length; x++) {&lt;br /&gt;
    byte ee = spi_transaction(0xA0, 0x00, _addr*2+x, 0xFF);&lt;br /&gt;
    Serial.write( ee);&lt;br /&gt;
  }&lt;br /&gt;
  return STK_OK;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void read_page() {&lt;br /&gt;
  byte result = (byte)STK_FAILED;&lt;br /&gt;
  int length = 256 * getch() + getch();&lt;br /&gt;
  char memtype = getch();&lt;br /&gt;
  if (CRC_EOP != getch()) {&lt;br /&gt;
    Serial.write(STK_NOSYNC);&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  Serial.write(STK_INSYNC);&lt;br /&gt;
  if (memtype == 'F') result = flash_read_page(length);&lt;br /&gt;
  if (memtype == 'E') result = eeprom_read_page(length);&lt;br /&gt;
  Serial.write(result);&lt;br /&gt;
  return;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void read_signature() {&lt;br /&gt;
  if (CRC_EOP != getch()) {&lt;br /&gt;
    Serial.write(STK_NOSYNC);&lt;br /&gt;
    error++;&lt;br /&gt;
    return;&lt;br /&gt;
  }&lt;br /&gt;
  Serial.write(STK_INSYNC);&lt;br /&gt;
  byte high = spi_transaction(0x30, 0x00, 0x00, 0x00);&lt;br /&gt;
  Serial.write(high);&lt;br /&gt;
  byte middle = spi_transaction(0x30, 0x00, 0x01, 0x00);&lt;br /&gt;
  Serial.write(middle);&lt;br /&gt;
  byte low = spi_transaction(0x30, 0x00, 0x02, 0x00);&lt;br /&gt;
  Serial.write(low);&lt;br /&gt;
  Serial.write(STK_OK);&lt;br /&gt;
}&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
//////////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
////////////////////////////////////&lt;br /&gt;
&lt;br /&gt;
int avrisp() { &lt;br /&gt;
  byte data, low, high;&lt;br /&gt;
  byte avrch = getch();&lt;br /&gt;
  switch (avrch) {&lt;br /&gt;
    case STK_GET_SYNC: // get in sync&lt;br /&gt;
      replyOK();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_GET_SIGNON:  // get sign on&lt;br /&gt;
      if (getch() == CRC_EOP) {&lt;br /&gt;
        Serial.write(STK_INSYNC);&lt;br /&gt;
        Serial.write(&amp;quot;AVR ISP&amp;quot;);&lt;br /&gt;
        Serial.write(STK_OK);&lt;br /&gt;
      }&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_GET_PARM:  // 0x41&lt;br /&gt;
      get_parameter(getch());&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_SET_PARM:  // 0x42&lt;br /&gt;
      readbytes(20);&lt;br /&gt;
      set_parameters();&lt;br /&gt;
      replyOK();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_SET_PARM_EXT: // extended parameters - ignore for now&lt;br /&gt;
      readbytes(5);&lt;br /&gt;
      replyOK();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_PMODE_START:  // 0x50&lt;br /&gt;
      beep(2272, 20);&lt;br /&gt;
      start_pmode();&lt;br /&gt;
      replyOK();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_PMODE_END:  //0x51&lt;br /&gt;
      beep(1912, 50);&lt;br /&gt;
      error=0;&lt;br /&gt;
      end_pmode();&lt;br /&gt;
      replyOK();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_SET_ADDR:  // 0x55&lt;br /&gt;
      _addr = getch() + 256 * getch();&lt;br /&gt;
      replyOK();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_UNIVERSAL:  //UNIVERSAL 0x56&lt;br /&gt;
      universal();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_PROG_FLASH: //STK_PROG_FLASH  ???&lt;br /&gt;
      low = getch();&lt;br /&gt;
      high = getch();&lt;br /&gt;
      replyOK();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_PROG_DATA: //STK_PROG_DATA  ???&lt;br /&gt;
      data = getch();&lt;br /&gt;
      replyOK();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_PROG_PAGE:  //STK_PROG_PAGE&lt;br /&gt;
//      beep(1912, 20);&lt;br /&gt;
      program_page();&lt;br /&gt;
      break;&lt;br /&gt;
    case STK_READ_PAGE: //STK_READ_PAGE&lt;br /&gt;
      read_page();    &lt;br /&gt;
      break;&lt;br /&gt;
    case STK_READ_SIGN: //STK_READ_SIGN&lt;br /&gt;
      read_signature();&lt;br /&gt;
      break;&lt;br /&gt;
    // expecting a command, not CRC_EOP&lt;br /&gt;
    // this is how we can get back in sync&lt;br /&gt;
    case CRC_EOP:&lt;br /&gt;
      Serial.write(STK_NOSYNC);&lt;br /&gt;
      break;&lt;br /&gt;
    // anything else we will return STK_UNKNOWN&lt;br /&gt;
    default:&lt;br /&gt;
      if (CRC_EOP == getch()) &lt;br /&gt;
        Serial.write(STK_UNKNOWN);&lt;br /&gt;
      else&lt;br /&gt;
        Serial.write(STK_NOSYNC);&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// beep without using PWM&lt;br /&gt;
void beep(int tone, long duration){&lt;br /&gt;
  long elapsed = 0;&lt;br /&gt;
  while (elapsed &amp;lt; (duration * 10000)) {&lt;br /&gt;
    digitalWrite(PIEZO, HIGH);&lt;br /&gt;
    delayMicroseconds(tone / 2);&lt;br /&gt;
    digitalWrite(PIEZO, LOW);&lt;br /&gt;
    delayMicroseconds(tone / 2);&lt;br /&gt;
    // Keep track of how long we pulsed&lt;br /&gt;
    elapsed += tone;&lt;br /&gt;
  } &lt;br /&gt;
}  &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Reference==&lt;br /&gt;
* The arduinoISP original sketch from adafruit [https://github.com/adafruit/ArduinoISP here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category: Arduino]]&lt;br /&gt;
[[category: AVR-ISP]]&lt;/div&gt;</summary>
		<author><name>Chao</name></author>
	</entry>
</feed>