[gnoduino] examples: include common ArduinoISP



commit 57e3e0e4775edf99f8b8cbbad780f622270236f2
Author: Pascal de Bruijn <pmjdebruijn pcode nl>
Date:   Thu Aug 14 18:42:12 2014 +0200

    examples: include common ArduinoISP

 examples/ArduinoISP/ArduinoISP.ino |  551 ++++++++++++++++++++++++++++++++++++
 setup.py                           |    2 +-
 2 files changed, 552 insertions(+), 1 deletions(-)
---
diff --git a/examples/ArduinoISP/ArduinoISP.ino b/examples/ArduinoISP/ArduinoISP.ino
new file mode 100644
index 0000000..cf25f91
--- /dev/null
+++ b/examples/ArduinoISP/ArduinoISP.ino
@@ -0,0 +1,551 @@
+// ArduinoISP version 04m3
+// Copyright (c) 2008-2011 Randall Bohn
+// If you require a license, see
+//     http://www.opensource.org/licenses/bsd-license.php
+//
+// This sketch turns the Arduino into a AVRISP
+// using the following arduino pins:
+//
+// pin name:    not-mega:         mega(1280 and 2560)
+// slave reset: 10:               53
+// MOSI:        11:               51
+// MISO:        12:               50
+// SCK:         13:               52
+//
+// Put an LED (with resistor) on the following pins:
+// 9: Heartbeat   - shows the programmer is running
+// 8: Error       - Lights up if something goes wrong (use red if that makes sense)
+// 7: Programming - In communication with the slave
+//
+// 23 July 2011 Randall Bohn
+// -Address Arduino issue 509 :: Portability of ArduinoISP
+// http://code.google.com/p/arduino/issues/detail?id=509
+//
+// October 2010 by Randall Bohn
+// - Write to EEPROM > 256 bytes
+// - Better use of LEDs:
+// -- Flash LED_PMODE on each flash commit
+// -- Flash LED_PMODE while writing EEPROM (both give visual feedback of writing progress)
+// - Light LED_ERR whenever we hit a STK_NOSYNC. Turn it off when back in sync.
+// - Use pins_arduino.h (should also work on Arduino Mega)
+//
+// October 2009 by David A. Mellis
+// - Added support for the read signature command
+//
+// February 2009 by Randall Bohn
+// - Added support for writing to EEPROM (what took so long?)
+// Windows users should consider WinAVR's avrdude instead of the
+// avrdude included with Arduino software.
+//
+// January 2008 by Randall Bohn
+// - Thanks to Amplificar for helping me with the STK500 protocol
+// - The AVRISP/STK500 (mk I) protocol is used in the arduino bootloader
+// - The SPI functions herein were developed for the AVR910_ARD programmer
+// - More information at http://code.google.com/p/mega-isp
+
+#include "pins_arduino.h"
+#define RESET     SS
+
+#define LED_HB    9
+#define LED_ERR   8
+#define LED_PMODE 7
+#define PROG_FLICKER true
+
+#define HWVER 2
+#define SWMAJ 1
+#define SWMIN 18
+
+// STK Definitions
+#define STK_OK      0x10
+#define STK_FAILED  0x11
+#define STK_UNKNOWN 0x12
+#define STK_INSYNC  0x14
+#define STK_NOSYNC  0x15
+#define CRC_EOP     0x20 //ok it is a space...
+
+void pulse(int pin, int times);
+
+void setup() {
+  Serial.begin(19200);
+  pinMode(LED_PMODE, OUTPUT);
+  pulse(LED_PMODE, 2);
+  pinMode(LED_ERR, OUTPUT);
+  pulse(LED_ERR, 2);
+  pinMode(LED_HB, OUTPUT);
+  pulse(LED_HB, 2);
+}
+
+int error=0;
+int pmode=0;
+// address for reading and writing, set by 'U' command
+int here;
+uint8_t buff[256]; // global block storage
+
+#define beget16(addr) (*addr * 256 + *(addr+1) )
+typedef struct param {
+  uint8_t devicecode;
+  uint8_t revision;
+  uint8_t progtype;
+  uint8_t parmode;
+  uint8_t polling;
+  uint8_t selftimed;
+  uint8_t lockbytes;
+  uint8_t fusebytes;
+  int flashpoll;
+  int eeprompoll;
+  int pagesize;
+  int eepromsize;
+  int flashsize;
+}
+parameter;
+
+parameter param;
+
+// this provides a heartbeat on pin 9, so you can tell the software is running.
+uint8_t hbval=128;
+int8_t hbdelta=8;
+void heartbeat() {
+  if (hbval > 192) hbdelta = -hbdelta;
+  if (hbval < 32) hbdelta = -hbdelta;
+  hbval += hbdelta;
+  analogWrite(LED_HB, hbval);
+  delay(20);
+}
+
+
+void loop(void) {
+  // is pmode active?
+  if (pmode) digitalWrite(LED_PMODE, HIGH);
+  else digitalWrite(LED_PMODE, LOW);
+  // is there an error?
+  if (error) digitalWrite(LED_ERR, HIGH);
+  else digitalWrite(LED_ERR, LOW);
+
+  // light the heartbeat LED
+  heartbeat();
+  if (Serial.available()) {
+    avrisp();
+  }
+}
+
+uint8_t getch() {
+  while(!Serial.available());
+  return Serial.read();
+}
+void fill(int n) {
+  for (int x = 0; x < n; x++) {
+    buff[x] = getch();
+  }
+}
+
+#define PTIME 30
+void pulse(int pin, int times) {
+  do {
+    digitalWrite(pin, HIGH);
+    delay(PTIME);
+    digitalWrite(pin, LOW);
+    delay(PTIME);
+  }
+  while (times--);
+}
+
+void prog_lamp(int state) {
+  if (PROG_FLICKER)
+    digitalWrite(LED_PMODE, state);
+}
+
+void spi_init() {
+  uint8_t x;
+  SPCR = 0x53;
+  x=SPSR;
+  x=SPDR;
+}
+
+void spi_wait() {
+  do {
+  }
+  while (!(SPSR & (1 << SPIF)));
+}
+
+uint8_t spi_send(uint8_t b) {
+  uint8_t reply;
+  SPDR=b;
+  spi_wait();
+  reply = SPDR;
+  return reply;
+}
+
+uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+  uint8_t n;
+  spi_send(a);
+  n=spi_send(b);
+  //if (n != a) error = -1;
+  n=spi_send(c);
+  return spi_send(d);
+}
+
+void empty_reply() {
+  if (CRC_EOP == getch()) {
+    Serial.print((char)STK_INSYNC);
+    Serial.print((char)STK_OK);
+  }
+  else {
+    error++;
+    Serial.print((char)STK_NOSYNC);
+  }
+}
+
+void breply(uint8_t b) {
+  if (CRC_EOP == getch()) {
+    Serial.print((char)STK_INSYNC);
+    Serial.print((char)b);
+    Serial.print((char)STK_OK);
+  }
+  else {
+    error++;
+    Serial.print((char)STK_NOSYNC);
+  }
+}
+
+void get_version(uint8_t c) {
+  switch(c) {
+  case 0x80:
+    breply(HWVER);
+    break;
+  case 0x81:
+    breply(SWMAJ);
+    break;
+  case 0x82:
+    breply(SWMIN);
+    break;
+  case 0x93:
+    breply('S'); // serial programmer
+    break;
+  default:
+    breply(0);
+  }
+}
+
+void set_parameters() {
+  // call this after reading paramter packet into buff[]
+  param.devicecode = buff[0];
+  param.revision   = buff[1];
+  param.progtype   = buff[2];
+  param.parmode    = buff[3];
+  param.polling    = buff[4];
+  param.selftimed  = buff[5];
+  param.lockbytes  = buff[6];
+  param.fusebytes  = buff[7];
+  param.flashpoll  = buff[8];
+  // ignore buff[9] (= buff[8])
+  // following are 16 bits (big endian)
+  param.eeprompoll = beget16(&buff[10]);
+  param.pagesize   = beget16(&buff[12]);
+  param.eepromsize = beget16(&buff[14]);
+
+  // 32 bits flashsize (big endian)
+  param.flashsize = buff[16] * 0x01000000
+    + buff[17] * 0x00010000
+    + buff[18] * 0x00000100
+    + buff[19];
+
+}
+
+void start_pmode() {
+  spi_init();
+  // following delays may not work on all targets...
+  pinMode(RESET, OUTPUT);
+  digitalWrite(RESET, HIGH);
+  pinMode(SCK, OUTPUT);
+  digitalWrite(SCK, LOW);
+  delay(50);
+  digitalWrite(RESET, LOW);
+  delay(50);
+  pinMode(MISO, INPUT);
+  pinMode(MOSI, OUTPUT);
+  spi_transaction(0xAC, 0x53, 0x00, 0x00);
+  pmode = 1;
+}
+
+void end_pmode() {
+  pinMode(MISO, INPUT);
+  pinMode(MOSI, INPUT);
+  pinMode(SCK, INPUT);
+  pinMode(RESET, INPUT);
+  pmode = 0;
+}
+
+void universal() {
+  int w;
+  uint8_t ch;
+
+  fill(4);
+  ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
+  breply(ch);
+}
+
+void flash(uint8_t hilo, int addr, uint8_t data) {
+  spi_transaction(0x40+8*hilo,
+  addr>>8 & 0xFF,
+  addr & 0xFF,
+  data);
+}
+void commit(int addr) {
+  if (PROG_FLICKER) prog_lamp(LOW);
+  spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
+  if (PROG_FLICKER) {
+    delay(PTIME);
+    prog_lamp(HIGH);
+  }
+}
+
+//#define _current_page(x) (here & 0xFFFFE0)
+int current_page(int addr) {
+  if (param.pagesize == 32)  return here & 0xFFFFFFF0;
+  if (param.pagesize == 64)  return here & 0xFFFFFFE0;
+  if (param.pagesize == 128) return here & 0xFFFFFFC0;
+  if (param.pagesize == 256) return here & 0xFFFFFF80;
+  return here;
+}
+
+
+void write_flash(int length) {
+  fill(length);
+  if (CRC_EOP == getch()) {
+    Serial.print((char) STK_INSYNC);
+    Serial.print((char) write_flash_pages(length));
+  }
+  else {
+    error++;
+    Serial.print((char) STK_NOSYNC);
+  }
+}
+
+uint8_t write_flash_pages(int length) {
+  int x = 0;
+  int page = current_page(here);
+  while (x < length) {
+    if (page != current_page(here)) {
+      commit(page);
+      page = current_page(here);
+    }
+    flash(LOW, here, buff[x++]);
+    flash(HIGH, here, buff[x++]);
+    here++;
+  }
+
+  commit(page);
+
+  return STK_OK;
+}
+
+#define EECHUNK (32)
+uint8_t write_eeprom(int length) {
+  // here is a word address, get the byte address
+  int start = here * 2;
+  int remaining = length;
+  if (length > param.eepromsize) {
+    error++;
+    return STK_FAILED;
+  }
+  while (remaining > EECHUNK) {
+    write_eeprom_chunk(start, EECHUNK);
+    start += EECHUNK;
+    remaining -= EECHUNK;
+  }
+  write_eeprom_chunk(start, remaining);
+  return STK_OK;
+}
+// write (length) bytes, (start) is a byte address
+uint8_t write_eeprom_chunk(int start, int length) {
+  // this writes byte-by-byte,
+  // page writing may be faster (4 bytes at a time)
+  fill(length);
+  prog_lamp(LOW);
+  for (int x = 0; x < length; x++) {
+    int addr = start+x;
+    spi_transaction(0xC0, (addr>>8) & 0xFF, addr & 0xFF, buff[x]);
+    delay(45);
+  }
+  prog_lamp(HIGH);
+  return STK_OK;
+}
+
+void program_page() {
+  char result = (char) STK_FAILED;
+  int length = 256 * getch();
+  length += getch();
+  char memtype = getch();
+  // flash memory @here, (length) bytes
+  if (memtype == 'F') {
+    write_flash(length);
+    return;
+  }
+  if (memtype == 'E') {
+    result = (char)write_eeprom(length);
+    if (CRC_EOP == getch()) {
+      Serial.print((char) STK_INSYNC);
+      Serial.print(result);
+    }
+    else {
+      error++;
+      Serial.print((char) STK_NOSYNC);
+    }
+    return;
+  }
+  Serial.print((char)STK_FAILED);
+  return;
+}
+
+uint8_t flash_read(uint8_t hilo, int addr) {
+  return spi_transaction(0x20 + hilo * 8,
+  (addr >> 8) & 0xFF,
+  addr & 0xFF,
+  0);
+}
+
+char flash_read_page(int length) {
+  for (int x = 0; x < length; x+=2) {
+    uint8_t low = flash_read(LOW, here);
+    Serial.print((char) low);
+    uint8_t high = flash_read(HIGH, here);
+    Serial.print((char) high);
+    here++;
+  }
+  return STK_OK;
+}
+
+char eeprom_read_page(int length) {
+  // here again we have a word address
+  int start = here * 2;
+  for (int x = 0; x < length; x++) {
+    int addr = start + x;
+    uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF);
+    Serial.print((char) ee);
+  }
+  return STK_OK;
+}
+
+void read_page() {
+  char result = (char)STK_FAILED;
+  int length = 256 * getch();
+  length += getch();
+  char memtype = getch();
+  if (CRC_EOP != getch()) {
+    error++;
+    Serial.print((char) STK_NOSYNC);
+    return;
+  }
+  Serial.print((char) STK_INSYNC);
+  if (memtype == 'F') result = flash_read_page(length);
+  if (memtype == 'E') result = eeprom_read_page(length);
+  Serial.print(result);
+  return;
+}
+
+void read_signature() {
+  if (CRC_EOP != getch()) {
+    error++;
+    Serial.print((char) STK_NOSYNC);
+    return;
+  }
+  Serial.print((char) STK_INSYNC);
+  uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00);
+  Serial.print((char) high);
+  uint8_t middle = spi_transaction(0x30, 0x00, 0x01, 0x00);
+  Serial.print((char) middle);
+  uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00);
+  Serial.print((char) low);
+  Serial.print((char) STK_OK);
+}
+//////////////////////////////////////////
+//////////////////////////////////////////
+
+
+////////////////////////////////////
+////////////////////////////////////
+int avrisp() {
+  uint8_t data, low, high;
+  uint8_t ch = getch();
+  switch (ch) {
+  case '0': // signon
+    error = 0;
+    empty_reply();
+    break;
+  case '1':
+    if (getch() == CRC_EOP) {
+      Serial.print((char) STK_INSYNC);
+      Serial.print("AVR ISP");
+      Serial.print((char) STK_OK);
+    }
+    break;
+  case 'A':
+    get_version(getch());
+    break;
+  case 'B':
+    fill(20);
+    set_parameters();
+    empty_reply();
+    break;
+  case 'E': // extended parameters - ignore for now
+    fill(5);
+    empty_reply();
+    break;
+
+  case 'P':
+    start_pmode();
+    empty_reply();
+    break;
+  case 'U': // set address (word)
+    here = getch();
+    here += 256 * getch();
+    empty_reply();
+    break;
+
+  case 0x60: //STK_PROG_FLASH
+    low = getch();
+    high = getch();
+    empty_reply();
+    break;
+  case 0x61: //STK_PROG_DATA
+    data = getch();
+    empty_reply();
+    break;
+
+  case 0x64: //STK_PROG_PAGE
+    program_page();
+    break;
+
+  case 0x74: //STK_READ_PAGE 't'
+    read_page();
+    break;
+
+  case 'V': //0x56
+    universal();
+    break;
+  case 'Q': //0x51
+    error=0;
+    end_pmode();
+    empty_reply();
+    break;
+
+  case 0x75: //STK_READ_SIGN 'u'
+    read_signature();
+    break;
+
+    // expecting a command, not CRC_EOP
+    // this is how we can get back in sync
+  case CRC_EOP:
+    error++;
+    Serial.print((char) STK_NOSYNC);
+    break;
+
+    // anything else we will return STK_UNKNOWN
+  default:
+    error++;
+    if (CRC_EOP == getch())
+      Serial.print((char)STK_UNKNOWN);
+    else
+      Serial.print((char)STK_NOSYNC);
+  }
+}
diff --git a/setup.py b/setup.py
index 7f63819..47444c5 100644
--- a/setup.py
+++ b/setup.py
@@ -126,7 +126,7 @@ def get_data_files():
         ('share/icons/hicolor/64x64/apps', ['pixmaps/64x64/gnoduino.png']),
         ('share/icons/hicolor/scalable/apps', ['pixmaps/gnoduino.svg']),
     ]
-    for subdir in ("hardware", "libraries", "reference"):
+    for subdir in ("hardware", "libraries", "examples", "reference"):
         # We ship hardware/libraries/reference modules if not already installed
         if forcesdk is True or not os.path.exists(os.path.join(sys.prefix, "share", "arduino", subdir)):
             for dirpath, dirnames, filenames in os.walk(subdir):


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]