[gnoduino] examples: include common ArduinoISP
- From: Lucian Langa <lucilanga src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnoduino] examples: include common ArduinoISP
- Date: Wed, 24 Sep 2014 19:57:31 +0000 (UTC)
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]