From 49cd4b4c7b5214e349889c033411da323d9acfe8 Mon Sep 17 00:00:00 2001 From: Sylvan Butler Date: Thu, 26 Jan 2012 21:51:02 -0700 Subject: [PATCH 01/13] implement bitbang SPI for slow clock devices, cleanup SPI pin handling --- ArduinoISP/ArduinoISP.ino | 85 ++++++++++++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 19 deletions(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index 1b460139..a24009c4 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -44,7 +44,10 @@ // - More information at http://code.google.com/p/mega-isp #include "pins_arduino.h" -#define RESET SS +#define PIN_RESET SS +#define PIN_SCK SCK +#define PIN_MOSI MOSI +#define PIN_MISO MISO #define LED_HB 9 #define LED_ERR 8 @@ -55,6 +58,22 @@ #define SWMAJ 1 #define SWMIN 18 +#define BAUDRATE 19200 +//#define BAUDRATE 115200 +// comment USE_SPI to use bitbang (digitalWrite()) +//#define USE_SPI + +#ifdef USE_SPI +// normal settings +#define RESETDELAY 0 +#define SPICR 0x53 +#define SPISR (SPSR & 0xfe) +#else // USE_SPI +// bitbang to make it work with very slow attiny2313 +#define RESETDELAY 0 + +#endif + // STK Definitions #define STK_OK 0x10 #define STK_FAILED 0x11 @@ -66,7 +85,7 @@ void pulse(int pin, int times); void setup() { - Serial.begin(19200); + Serial.begin(BAUDRATE); pinMode(LED_PMODE, OUTPUT); pulse(LED_PMODE, 2); pinMode(LED_ERR, OUTPUT); @@ -154,9 +173,14 @@ void prog_lamp(int state) { digitalWrite(LED_PMODE, state); } + +#ifdef USE_SPI void spi_init() { uint8_t x; - SPCR = 0x53; + SPCR = SPICR; +#ifdef SPISR + SPSR = SPISR; +#endif x=SPSR; x=SPDR; } @@ -175,15 +199,33 @@ uint8_t spi_send(uint8_t b) { return reply; } +#else // USE_SPI + +void spi_init() { +} + +uint8_t spi_send(uint8_t b) { + byte r = 0; + for (byte i = 0; i < 8; ++i, b<<=1) { + digitalWrite(PIN_MOSI, b & 0x80); + digitalWrite(PIN_SCK, LOW); // slow pulse + digitalWrite(PIN_SCK, HIGH); + r = (r << 1) | digitalRead(PIN_MISO); + } + digitalWrite(PIN_SCK, LOW); // slow pulse + return r; +} + +#endif // USE_SPI + 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); + spi_send(b); + spi_send(c); return spi_send(d); } + void empty_reply() { if (CRC_EOP == getch()) { Serial.print((char)STK_INSYNC); @@ -253,25 +295,30 @@ void set_parameters() { void start_pmode() { spi_init(); + + digitalWrite(PIN_RESET, HIGH); + digitalWrite(PIN_SCK, LOW); + digitalWrite(PIN_MOSI, HIGH); + + pinMode(PIN_MISO, INPUT); + pinMode(PIN_RESET, OUTPUT); + pinMode(PIN_SCK, OUTPUT); + pinMode(PIN_MOSI, OUTPUT); + // 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); + digitalWrite(PIN_RESET, LOW); delay(50); - pinMode(MISO, INPUT); - pinMode(MOSI, OUTPUT); + + if (RESETDELAY) delay(RESETDELAY); spi_transaction(0xAC, 0x53, 0x00, 0x00); pmode = 1; } void end_pmode() { - pinMode(MISO, INPUT); - pinMode(MOSI, INPUT); - pinMode(SCK, INPUT); - pinMode(RESET, INPUT); + pinMode(PIN_MOSI, INPUT); + pinMode(PIN_SCK, INPUT); + pinMode(PIN_RESET, INPUT); pmode = 0; } From a5d34dfde4675dd82792da6efc2f8dbcd2ac81a6 Mon Sep 17 00:00:00 2001 From: Sylvan Butler Date: Thu, 9 Feb 2012 21:38:04 -0700 Subject: [PATCH 02/13] add Lady Ada's PWM clock on pin 9 --- ArduinoISP/ArduinoISP.ino | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index a24009c4..9ce32c14 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -10,7 +10,7 @@ // slave reset: 10: 53 // MOSI: 11: 51 // MISO: 12: 50 -// SCK: 13: 52 +// SCK: 13: (std LED) 52 // // Put an LED (with resistor) on the following pins: // 9: Heartbeat - shows the programmer is running @@ -62,6 +62,16 @@ //#define BAUDRATE 115200 // comment USE_SPI to use bitbang (digitalWrite()) //#define USE_SPI +// create clock on digital 9 using pwm (timer1), LED_HB must move +#define LADYADA_CLOCK + +#ifdef LADYADA_CLOCK +// needs timer1 PWM +#define CLOCK_PIN 9 +#undef LED_HB +#define LED_HB 6 +#endif + #ifdef USE_SPI // normal settings @@ -91,6 +101,17 @@ void setup() { pinMode(LED_ERR, OUTPUT); pulse(LED_ERR, 2); pinMode(LED_HB, OUTPUT); + +#ifdef LADYADA_CLOCK + // setup high freq PWM (timer 1) + pinMode(CLOCK_PIN, OUTPUT); + // 50% duty cycle -> 8 MHz + OCR1A = 0; + ICR1 = 1; + // OC1A output, fast PWM + TCCR1A = _BV(WGM11) | _BV(COM1A1); + TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // no clock prescale +#endif pulse(LED_HB, 2); } From 14cb24b2a12c94a05b3c92b77af4257d130cb0e1 Mon Sep 17 00:00:00 2001 From: Sylvan Butler Date: Thu, 9 Feb 2012 21:41:01 -0700 Subject: [PATCH 03/13] eliminate unneeded variables, use correct variable types, big cleanup --- ArduinoISP/ArduinoISP.ino | 296 +++++++++++++++++++------------------- 1 file changed, 149 insertions(+), 147 deletions(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index 9ce32c14..62dff936 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -1,15 +1,15 @@ // ArduinoISP version 04m3 // Copyright (c) 2008-2011 Randall Bohn -// If you require a license, see +// 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 +// slave reset: 10: 53 +// MOSI: 11: 51 +// MISO: 12: 50 // SCK: 13: (std LED) 52 // // Put an LED (with resistor) on the following pins: @@ -26,12 +26,12 @@ // - 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. +// -- 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 @@ -40,9 +40,34 @@ // 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 +// - The SPI functions herein were developed for the AVR910_ARD programmer // - More information at http://code.google.com/p/mega-isp + +// versions need to be above Atmel programmer to avoid fw update attempts +#define HWVER 2 +#define SWMAJ 1 +#define SWMIN 18 + + +#define BAUDRATE 19200 +//#define BAUDRATE 38400 +//#define BAUDRATE 115200 + +// comment USE_SPI to use bitbang (digitalWrite()) +//#define USE_SPI + +// create clock on digital 9 using pwm (timer1), LED_HB must move +#define LADYADA_CLOCK + + + +/////////////////////////////////////////////// +// ideally won't need to edit below here // +/////////////////////////////////////////////// + + + #include "pins_arduino.h" #define PIN_RESET SS #define PIN_SCK SCK @@ -54,16 +79,7 @@ #define LED_PMODE 7 #define PROG_FLICKER true -#define HWVER 2 -#define SWMAJ 1 -#define SWMIN 18 -#define BAUDRATE 19200 -//#define BAUDRATE 115200 -// comment USE_SPI to use bitbang (digitalWrite()) -//#define USE_SPI -// create clock on digital 9 using pwm (timer1), LED_HB must move -#define LADYADA_CLOCK #ifdef LADYADA_CLOCK // needs timer1 PWM @@ -76,14 +92,15 @@ #ifdef USE_SPI // normal settings #define RESETDELAY 0 -#define SPICR 0x53 +#define SPICR 0x53 #define SPISR (SPSR & 0xfe) #else // USE_SPI // bitbang to make it work with very slow attiny2313 #define RESETDELAY 0 - #endif + + // STK Definitions #define STK_OK 0x10 #define STK_FAILED 0x11 @@ -92,15 +109,16 @@ #define STK_NOSYNC 0x15 #define CRC_EOP 0x20 //ok it is a space... -void pulse(int pin, int times); +void pulse(uint8_t pin, uint8_t times); -void setup() { +void setup(void) { Serial.begin(BAUDRATE); pinMode(LED_PMODE, OUTPUT); pulse(LED_PMODE, 2); pinMode(LED_ERR, OUTPUT); pulse(LED_ERR, 2); pinMode(LED_HB, OUTPUT); + pulse(LED_HB, 2); #ifdef LADYADA_CLOCK // setup high freq PWM (timer 1) @@ -112,17 +130,19 @@ void setup() { TCCR1A = _BV(WGM11) | _BV(COM1A1); TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // no clock prescale #endif - pulse(LED_HB, 2); } -int error=0; -int pmode=0; -// address for reading and writing, set by 'U' command -int here; +uint8_t error=0; +uint8_t pmode=0; uint8_t buff[256]; // global block storage +// address for reading and writing, set by 'U' command +uint16_t here; -#define beget16(addr) (*addr * 256 + *(addr+1) ) -typedef struct param { +// get multi-byte Big Endian values +#define beget16(addr) ((uint16_t)*(addr) << 8 | (uint16_t)*((addr)+1) ) +#define beget32(a) ((uint32_t)beget16(a) << 16 | (uint32_t)beget16((a)+2) ) + +struct param { uint8_t devicecode; uint8_t revision; uint8_t progtype; @@ -131,72 +151,75 @@ typedef struct param { uint8_t selftimed; uint8_t lockbytes; uint8_t fusebytes; - int flashpoll; - int eeprompoll; - int pagesize; - int eepromsize; - int flashsize; -} -parameter; + uint8_t flashpoll; + //uint8_t ignored; + uint16_t eeprompoll; + uint16_t pagesize; + uint16_t eepromsize; + uint32_t flashsize; +} param; -parameter param; -// this provides a heartbeat on pin 9, so you can tell the software is running. +// this provides a heartbeat, 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; +unsigned long hbprev=0; +void heartbeat(void) { + if (hbval > 192 || hbval < 32) hbdelta = -hbdelta; hbval += hbdelta; + while (millis()-hbprev < 40); // wait a bit if came back too soon analogWrite(LED_HB, hbval); - delay(40); + hbprev=millis(); } void loop(void) { // is pmode active? - if (pmode) digitalWrite(LED_PMODE, HIGH); + if (pmode) digitalWrite(LED_PMODE, HIGH); else digitalWrite(LED_PMODE, LOW); + // is there an error? - if (error) digitalWrite(LED_ERR, HIGH); + if (error) digitalWrite(LED_ERR, HIGH); else digitalWrite(LED_ERR, LOW); // light the heartbeat LED heartbeat(); + if (Serial.available()) { avrisp(); } } -uint8_t getch() { + +uint8_t getch(void) { while(!Serial.available()); return Serial.read(); } -void fill(int n) { - for (int x = 0; x < n; x++) { +void fill(unsigned n) { + for (unsigned x = 0; x < n; x++) { buff[x] = getch(); } } #define PTIME 30 -void pulse(int pin, int times) { +void pulse(uint8_t pin, uint8_t times) { do { digitalWrite(pin, HIGH); delay(PTIME); digitalWrite(pin, LOW); delay(PTIME); - } + } while (times--); } -void prog_lamp(int state) { +void prog_lamp(uint8_t state) { if (PROG_FLICKER) digitalWrite(LED_PMODE, state); } #ifdef USE_SPI -void spi_init() { +void spi_init(void) { uint8_t x; SPCR = SPICR; #ifdef SPISR @@ -206,9 +229,7 @@ void spi_init() { x=SPDR; } -void spi_wait() { - do { - } +inline void spi_wait(void) { while (!(SPSR & (1 << SPIF))); } @@ -220,9 +241,9 @@ uint8_t spi_send(uint8_t b) { return reply; } -#else // USE_SPI +#else // no USE_SPI -void spi_init() { +inline void spi_init(void) { } uint8_t spi_send(uint8_t b) { @@ -240,18 +261,18 @@ uint8_t spi_send(uint8_t b) { #endif // USE_SPI uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { - spi_send(a); + spi_send(a); spi_send(b); spi_send(c); return spi_send(d); } -void empty_reply() { +void empty_reply(void) { if (CRC_EOP == getch()) { Serial.print((char)STK_INSYNC); Serial.print((char)STK_OK); - } + } else { error++; Serial.print((char)STK_NOSYNC); @@ -263,7 +284,7 @@ void breply(uint8_t b) { Serial.print((char)STK_INSYNC); Serial.print((char)b); Serial.print((char)STK_OK); - } + } else { error++; Serial.print((char)STK_NOSYNC); @@ -289,7 +310,7 @@ void get_version(uint8_t c) { } } -void set_parameters() { +void set_parameters(void) { // call this after reading paramter packet into buff[] param.devicecode = buff[0]; param.revision = buff[1]; @@ -299,66 +320,60 @@ void set_parameters() { param.selftimed = buff[5]; param.lockbytes = buff[6]; param.fusebytes = buff[7]; - param.flashpoll = buff[8]; + 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]; - + param.flashsize = beget32(&buff[16]); } -void start_pmode() { +void start_pmode(void) { + pmode = 1; spi_init(); - + digitalWrite(PIN_RESET, HIGH); digitalWrite(PIN_SCK, LOW); digitalWrite(PIN_MOSI, HIGH); - + pinMode(PIN_MISO, INPUT); pinMode(PIN_RESET, OUTPUT); pinMode(PIN_SCK, OUTPUT); pinMode(PIN_MOSI, OUTPUT); - + // following delays may not work on all targets... - delay(50); + delay(50); digitalWrite(PIN_RESET, LOW); delay(50); - + if (RESETDELAY) delay(RESETDELAY); spi_transaction(0xAC, 0x53, 0x00, 0x00); - pmode = 1; } -void end_pmode() { +void end_pmode(void) { pinMode(PIN_MOSI, INPUT); pinMode(PIN_SCK, INPUT); pinMode(PIN_RESET, INPUT); pmode = 0; } -void universal() { - int w; +void universal(void) { 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) { +#define flash_write_cmd(hilo, addr, data) \ + spi_transaction(0x40|((hilo)<<3), (addr)>>8 & 0xFF, (addr) & 0xFF, (data)) + +#define flash_read_cmd(hilo, addr) \ + spi_transaction(0x20|((hilo)<<3), (addr)>>8 & 0xFF, (addr) & 0xFF, 0) + + +void commit(uint16_t addr) { if (PROG_FLICKER) prog_lamp(LOW); spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0); if (PROG_FLICKER) { @@ -367,38 +382,37 @@ void commit(int addr) { } } -//#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; +uint16_t current_page(uint16_t addr) { + if (param.pagesize == 32) return here & 0xFFF0; + if (param.pagesize == 64) return here & 0xFFE0; + if (param.pagesize == 128) return here & 0xFFC0; + if (param.pagesize == 256) return here & 0xFF80; return here; } -void write_flash(int length) { +void write_flash(unsigned 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); +uint8_t write_flash_pages(unsigned length) { + unsigned x = 0; + uint16_t 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++]); + flash_write_cmd(LOW, here, buff[x++]); + flash_write_cmd(HIGH, here, buff[x++]); here++; } @@ -408,41 +422,39 @@ uint8_t write_flash_pages(int length) { } #define EECHUNK (32) -uint8_t write_eeprom(int length) { +uint8_t write_eeprom(unsigned length) { // here is a word address, get the byte address - int start = here * 2; - int remaining = length; + uint16_t start = here << 1; if (length > param.eepromsize) { error++; return STK_FAILED; } - while (remaining > EECHUNK) { + while (length > EECHUNK) { write_eeprom_chunk(start, EECHUNK); start += EECHUNK; - remaining -= EECHUNK; + length -= EECHUNK; } - write_eeprom_chunk(start, remaining); + write_eeprom_chunk(start, length); return STK_OK; } // write (length) bytes, (start) is a byte address -uint8_t write_eeprom_chunk(int start, int length) { +uint8_t write_eeprom_chunk(uint16_t addr, unsigned 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; + for (unsigned x = 0; x < length; x++, addr++) { spi_transaction(0xC0, (addr>>8) & 0xFF, addr & 0xFF, buff[x]); delay(45); } - prog_lamp(HIGH); + prog_lamp(HIGH); return STK_OK; } -void program_page() { +void program_page(void) { char result = (char) STK_FAILED; - int length = 256 * getch(); - length += getch(); + unsigned length = getch()<<8; + length |= getch(); char memtype = getch(); // flash memory @here, (length) bytes if (memtype == 'F') { @@ -454,7 +466,7 @@ void program_page() { if (CRC_EOP == getch()) { Serial.print((char) STK_INSYNC); Serial.print(result); - } + } else { error++; Serial.print((char) STK_NOSYNC); @@ -462,42 +474,34 @@ void program_page() { 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); +char flash_read_page(unsigned length) { + for (unsigned x = 0; x < length; x+=2) { + char ch; + ch = flash_read_cmd(LOW, here); + Serial.print(ch); + ch = flash_read_cmd(HIGH, here); + Serial.print(ch); here++; } return STK_OK; } -char eeprom_read_page(int length) { +char eeprom_read_page(unsigned length) { // here again we have a word address - int start = here * 2; - for (int x = 0; x < length; x++) { - int addr = start + x; + uint16_t addr = here << 1; + for (unsigned x = 0; x < length; x++, addr++) { uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF); Serial.print((char) ee); } return STK_OK; } -void read_page() { +void read_page(void) { char result = (char)STK_FAILED; - int length = 256 * getch(); - length += getch(); + unsigned length = getch() << 8; + length |= getch(); char memtype = getch(); if (CRC_EOP != getch()) { error++; @@ -508,31 +512,32 @@ void read_page() { if (memtype == 'F') result = flash_read_page(length); if (memtype == 'E') result = eeprom_read_page(length); Serial.print(result); - return; } -void read_signature() { +void read_signature(void) { 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); + char ch; + ch = spi_transaction(0x30, 0x00, 0x00, 0x00); + Serial.print(ch); + ch = spi_transaction(0x30, 0x00, 0x01, 0x00); + Serial.print(ch); + ch = spi_transaction(0x30, 0x00, 0x02, 0x00); + Serial.print(ch); Serial.print((char) STK_OK); } ////////////////////////////////////////// ////////////////////////////////////////// + //////////////////////////////////// //////////////////////////////////// -int avrisp() { +void avrisp(void) { uint8_t data, low, high; uint8_t ch = getch(); switch (ch) { @@ -566,7 +571,7 @@ int avrisp() { break; case 'U': // set address (word) here = getch(); - here += 256 * getch(); + here |= getch()<<8; empty_reply(); break; @@ -585,7 +590,7 @@ int avrisp() { break; case 0x74: //STK_READ_PAGE 't' - read_page(); + read_page(); break; case 'V': //0x56 @@ -611,12 +616,9 @@ int avrisp() { // anything else we will return STK_UNKNOWN default: error++; - if (CRC_EOP == getch()) + if (CRC_EOP == getch()) Serial.print((char)STK_UNKNOWN); else Serial.print((char)STK_NOSYNC); } } - - - From e0ab11606181ab578f7b393be9573348454e244c Mon Sep 17 00:00:00 2001 From: Sylvan Butler Date: Sun, 12 Feb 2012 20:32:04 -0700 Subject: [PATCH 04/13] simplify both spi_send() --- ArduinoISP/ArduinoISP.ino | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index 62dff936..ce33caf4 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -229,16 +229,10 @@ void spi_init(void) { x=SPDR; } -inline void spi_wait(void) { - while (!(SPSR & (1 << SPIF))); -} - uint8_t spi_send(uint8_t b) { - uint8_t reply; SPDR=b; - spi_wait(); - reply = SPDR; - return reply; + while (!(SPSR & (1 << SPIF))); + return SPDR; } #else // no USE_SPI @@ -247,15 +241,13 @@ inline void spi_init(void) { } uint8_t spi_send(uint8_t b) { - byte r = 0; - for (byte i = 0; i < 8; ++i, b<<=1) { + for (uint8_t i = 0; i < 8; ++i) { digitalWrite(PIN_MOSI, b & 0x80); - digitalWrite(PIN_SCK, LOW); // slow pulse digitalWrite(PIN_SCK, HIGH); - r = (r << 1) | digitalRead(PIN_MISO); + b = (b << 1) | digitalRead(PIN_MISO); + digitalWrite(PIN_SCK, LOW); // slow pulse } - digitalWrite(PIN_SCK, LOW); // slow pulse - return r; + return b; } #endif // USE_SPI From 59e6b7ba2c47be3b012aa4f4360018c1e7705809 Mon Sep 17 00:00:00 2001 From: Sylvan Butler Date: Sat, 25 Feb 2012 14:53:18 -0700 Subject: [PATCH 05/13] disable interrupts before programming timer1 --- ArduinoISP/ArduinoISP.ino | 3 +++ 1 file changed, 3 insertions(+) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index ce33caf4..eabda243 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -123,12 +123,15 @@ void setup(void) { #ifdef LADYADA_CLOCK // setup high freq PWM (timer 1) pinMode(CLOCK_PIN, OUTPUT); + uint8_t sreg = SREG; + cli(); // disable interrupts to access TCNT1, OCR1A,B // 50% duty cycle -> 8 MHz OCR1A = 0; ICR1 = 1; // OC1A output, fast PWM TCCR1A = _BV(WGM11) | _BV(COM1A1); TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // no clock prescale + SREG = sreg; // restore interrupts #endif } From e8fbbf777a11bdfb1421df35e6c56d073804ff9c Mon Sep 17 00:00:00 2001 From: Peter Van Hoyweghen Date: Fri, 31 May 2013 17:47:16 +0200 Subject: [PATCH 06/13] Use SPI lib for the USE_SPI case --- ArduinoISP/ArduinoISP.ino | 39 +++++++++++++-------------------------- 1 file changed, 13 insertions(+), 26 deletions(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index b44699b0..f82b701c 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -68,6 +68,7 @@ +#include "SPI.h" #include "pins_arduino.h" #define PIN_RESET SS #define PIN_SCK SCK @@ -113,6 +114,12 @@ void pulse(uint8_t pin, uint8_t times); void setup(void) { Serial.begin(BAUDRATE); + + SPI.setDataMode(0); + SPI.setBitOrder(MSBFIRST); + // Clock Div can be 2,4,8,16,32,64, or 128 + SPI.setClockDivider(SPI_CLOCK_DIV128); + pinMode(LED_PMODE, OUTPUT); pulse(LED_PMODE, 2); pinMode(LED_ERR, OUTPUT); @@ -220,29 +227,10 @@ void prog_lamp(uint8_t state) { digitalWrite(LED_PMODE, state); } - #ifdef USE_SPI -void spi_init(void) { - uint8_t x; - SPCR = SPICR; -#ifdef SPISR - SPSR = SPISR; -#endif - x=SPSR; - x=SPDR; -} - -uint8_t spi_send(uint8_t b) { - SPDR=b; - while (!(SPSR & (1 << SPIF))); - return SPDR; -} #else // no USE_SPI -inline void spi_init(void) { -} - uint8_t spi_send(uint8_t b) { for (uint8_t i = 0; i < 8; ++i) { digitalWrite(PIN_MOSI, b & 0x80); @@ -256,10 +244,10 @@ uint8_t spi_send(uint8_t b) { #endif // USE_SPI uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { - spi_send(a); - spi_send(b); - spi_send(c); - return spi_send(d); + SPI.transfer(a); + SPI.transfer(b); + SPI.transfer(c); + return SPI.transfer(d); } @@ -327,16 +315,14 @@ void set_parameters(void) { void start_pmode(void) { pmode = 1; - spi_init(); digitalWrite(PIN_RESET, HIGH); digitalWrite(PIN_SCK, LOW); digitalWrite(PIN_MOSI, HIGH); pinMode(PIN_MISO, INPUT); + SPI.begin(); // now SS, MOSI and SCK are output pinMode(PIN_RESET, OUTPUT); - pinMode(PIN_SCK, OUTPUT); - pinMode(PIN_MOSI, OUTPUT); // following delays may not work on all targets... delay(50); @@ -348,6 +334,7 @@ void start_pmode(void) { } void end_pmode(void) { + SPI.end(); pinMode(PIN_MOSI, INPUT); pinMode(PIN_SCK, INPUT); pinMode(PIN_RESET, INPUT); From 992508ebf7a9890d98ec071a8fd6cee5a8b5f5cf Mon Sep 17 00:00:00 2001 From: Peter Van Hoyweghen Date: Fri, 31 May 2013 21:43:11 +0200 Subject: [PATCH 07/13] factor bit bang code in a (minimal) class mimicing the one from SPI lib --- ArduinoISP/ArduinoISP.ino | 55 +++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index f82b701c..651acc4a 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -58,7 +58,7 @@ //#define USE_SPI // create clock on digital 9 using pwm (timer1), LED_HB must move -#define LADYADA_CLOCK +//#define LADYADA_CLOCK @@ -68,7 +68,9 @@ +#ifdef USE_SPI #include "SPI.h" +#endif #include "pins_arduino.h" #define PIN_RESET SS #define PIN_SCK SCK @@ -112,14 +114,45 @@ void pulse(uint8_t pin, uint8_t times); +#ifndef USE_SPI + +class BitBangedSPI { +public: + + void begin() { + pinMode(PIN_MISO, INPUT); + pinMode(PIN_RESET, OUTPUT); + pinMode(PIN_SCK, OUTPUT); + pinMode(PIN_MOSI, OUTPUT); + } + + void end() {} + + uint8_t transfer (uint8_t b) { + for (unsigned int i = 0; i < 8; ++i) { + digitalWrite(PIN_MOSI, b & 0x80); + digitalWrite(PIN_SCK, HIGH); + b = (b << 1) | digitalRead(PIN_MISO); + digitalWrite(PIN_SCK, LOW); // slow pulse + } + return b; + } +}; + +static BitBangedSPI SPI; + +#endif + void setup(void) { Serial.begin(BAUDRATE); +#ifdef USE_SPI SPI.setDataMode(0); SPI.setBitOrder(MSBFIRST); // Clock Div can be 2,4,8,16,32,64, or 128 SPI.setClockDivider(SPI_CLOCK_DIV128); - +#endif + pinMode(LED_PMODE, OUTPUT); pulse(LED_PMODE, 2); pinMode(LED_ERR, OUTPUT); @@ -227,22 +260,6 @@ void prog_lamp(uint8_t state) { digitalWrite(LED_PMODE, state); } -#ifdef USE_SPI - -#else // no USE_SPI - -uint8_t spi_send(uint8_t b) { - for (uint8_t i = 0; i < 8; ++i) { - digitalWrite(PIN_MOSI, b & 0x80); - digitalWrite(PIN_SCK, HIGH); - b = (b << 1) | digitalRead(PIN_MISO); - digitalWrite(PIN_SCK, LOW); // slow pulse - } - return b; -} - -#endif // USE_SPI - uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { SPI.transfer(a); SPI.transfer(b); @@ -321,8 +338,8 @@ void start_pmode(void) { digitalWrite(PIN_MOSI, HIGH); pinMode(PIN_MISO, INPUT); - SPI.begin(); // now SS, MOSI and SCK are output pinMode(PIN_RESET, OUTPUT); + SPI.begin(); // now SS, MOSI and SCK are output // following delays may not work on all targets... delay(50); From a750d46127ecf10106e05ca460b048c263b705fb Mon Sep 17 00:00:00 2001 From: Peter Van Hoyweghen Date: Fri, 31 May 2013 21:54:49 +0200 Subject: [PATCH 08/13] rm last references to AVR SPI regs, set new defaults: USE_SPI=yes, LADYADA_CLOCK=no (don't break existing ArduinoISP shields) --- ArduinoISP/ArduinoISP.ino | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index 651acc4a..03fc37b6 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -55,12 +55,13 @@ //#define BAUDRATE 115200 // comment USE_SPI to use bitbang (digitalWrite()) -//#define USE_SPI +// use bitbang to make it work with very slow attiny2313 +#define USE_SPI // create clock on digital 9 using pwm (timer1), LED_HB must move //#define LADYADA_CLOCK - +#define RESETDELAY 0 /////////////////////////////////////////////// // ideally won't need to edit below here // @@ -92,17 +93,6 @@ #endif -#ifdef USE_SPI -// normal settings -#define RESETDELAY 0 -#define SPICR 0x53 -#define SPISR (SPSR & 0xfe) -#else // USE_SPI -// bitbang to make it work with very slow attiny2313 -#define RESETDELAY 0 -#endif - - // STK Definitions #define STK_OK 0x10 From 581749aca42e090e07796cadd4e3c204f0ec538a Mon Sep 17 00:00:00 2001 From: Peter Van Hoyweghen Date: Fri, 31 May 2013 22:24:16 +0200 Subject: [PATCH 09/13] compile for Due: introduce SPI_CLOCK_DIV_MAX; error if LADYADA_CLOCK is selected (not yet implemented) --- ArduinoISP/ArduinoISP.ino | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index 03fc37b6..812bd785 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -71,7 +71,15 @@ #ifdef USE_SPI #include "SPI.h" + +#ifdef __AVR__ // this would better go into SPI lib +#define SPI_CLOCK_DIV_MAX SPI_CLOCK_DIV128 +#else +#define SPI_CLOCK_DIV_MAX 255 +#endif + #endif + #include "pins_arduino.h" #define PIN_RESET SS #define PIN_SCK SCK @@ -86,6 +94,9 @@ #ifdef LADYADA_CLOCK +#ifndef __AVR__ +#error "Not yet implemented for non AVR's." +#endif // needs timer1 PWM #define CLOCK_PIN 9 #undef LED_HB @@ -140,7 +151,7 @@ void setup(void) { SPI.setDataMode(0); SPI.setBitOrder(MSBFIRST); // Clock Div can be 2,4,8,16,32,64, or 128 - SPI.setClockDivider(SPI_CLOCK_DIV128); + SPI.setClockDivider(SPI_CLOCK_DIV_MAX); #endif pinMode(LED_PMODE, OUTPUT); From bb341173e025eee06634b783ad4fa2eeeed59ea6 Mon Sep 17 00:00:00 2001 From: Peter Van Hoyweghen Date: Sun, 2 Jun 2013 21:24:57 +0200 Subject: [PATCH 10/13] reset target before driving SCM or MOSI, reset sequence as in AVR datasheets under "Serial Programming Algorithm" --- ArduinoISP/ArduinoISP.ino | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index 812bd785..410a8a0a 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -334,19 +334,22 @@ void set_parameters(void) { void start_pmode(void) { pmode = 1; - digitalWrite(PIN_RESET, HIGH); + // reset target before driving SCK or MOSI + digitalWrite(PIN_RESET, LOW); digitalWrite(PIN_SCK, LOW); digitalWrite(PIN_MOSI, HIGH); pinMode(PIN_MISO, INPUT); - pinMode(PIN_RESET, OUTPUT); + pinMode(PIN_RESET, OUTPUT); // PIN_RESET not always SS: Leonardo, Due... SPI.begin(); // now SS, MOSI and SCK are output - // following delays may not work on all targets... - delay(50); + // See datasheets: "Serial Programming Algorithm": + delay(5); // choosen arbitrarilly + // pulse RESET high after SCK is low + digitalWrite(PIN_RESET, HIGH); + delay(1); // must be minimum 2 CPU clock cycles digitalWrite(PIN_RESET, LOW); - delay(50); - + delay(50); // minimum 20 ms if (RESETDELAY) delay(RESETDELAY); spi_transaction(0xAC, 0x53, 0x00, 0x00); } From 126a7034b0c43a88f16a3858b0104143f7b70a0a Mon Sep 17 00:00:00 2001 From: Peter Van Hoyweghen Date: Sun, 2 Jun 2013 21:42:24 +0200 Subject: [PATCH 11/13] introduce SERIAL_PRG to flexibly select which serial port to use for programming; on Due, SerialUSB will be used by default (does not autoreset) --- ArduinoISP/ArduinoISP.ino | 87 ++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 38 deletions(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index 410a8a0a..7dad5597 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -63,6 +63,17 @@ #define RESETDELAY 0 + +#ifdef __SAM3X8E__ + +#define SERIAL_PRG SerialUSB + +#else + +#define SERIAL_PRG Serial + +#endif + /////////////////////////////////////////////// // ideally won't need to edit below here // /////////////////////////////////////////////// @@ -145,7 +156,7 @@ static BitBangedSPI SPI; #endif void setup(void) { - Serial.begin(BAUDRATE); + SERIAL_PRG.begin(BAUDRATE); #ifdef USE_SPI SPI.setDataMode(0); @@ -229,15 +240,15 @@ void loop(void) { // light the heartbeat LED heartbeat(); - if (Serial.available()) { + if (SERIAL_PRG.available()) { avrisp(); } } uint8_t getch(void) { - while(!Serial.available()); - return Serial.read(); + while(!SERIAL_PRG.available()); + return SERIAL_PRG.read(); } void fill(unsigned n) { for (unsigned x = 0; x < n; x++) { @@ -271,24 +282,24 @@ uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) { void empty_reply(void) { if (CRC_EOP == getch()) { - Serial.print((char)STK_INSYNC); - Serial.print((char)STK_OK); + SERIAL_PRG.print((char)STK_INSYNC); + SERIAL_PRG.print((char)STK_OK); } else { error++; - Serial.print((char)STK_NOSYNC); + SERIAL_PRG.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); + SERIAL_PRG.print((char)STK_INSYNC); + SERIAL_PRG.print((char)b); + SERIAL_PRG.print((char)STK_OK); } else { error++; - Serial.print((char)STK_NOSYNC); + SERIAL_PRG.print((char)STK_NOSYNC); } } @@ -343,7 +354,7 @@ void start_pmode(void) { pinMode(PIN_RESET, OUTPUT); // PIN_RESET not always SS: Leonardo, Due... SPI.begin(); // now SS, MOSI and SCK are output - // See datasheets: "Serial Programming Algorithm": + // See datasheets: "SERIAL_PRG Programming Algorithm": delay(5); // choosen arbitrarilly // pulse RESET high after SCK is low digitalWrite(PIN_RESET, HIGH); @@ -397,12 +408,12 @@ uint16_t current_page(uint16_t addr) { void write_flash(unsigned length) { fill(length); if (CRC_EOP == getch()) { - Serial.print((char) STK_INSYNC); - Serial.print((char) write_flash_pages(length)); + SERIAL_PRG.print((char) STK_INSYNC); + SERIAL_PRG.print((char) write_flash_pages(length)); } else { error++; - Serial.print((char) STK_NOSYNC); + SERIAL_PRG.print((char) STK_NOSYNC); } } @@ -467,25 +478,25 @@ void program_page(void) { if (memtype == 'E') { result = (char)write_eeprom(length); if (CRC_EOP == getch()) { - Serial.print((char) STK_INSYNC); - Serial.print(result); + SERIAL_PRG.print((char) STK_INSYNC); + SERIAL_PRG.print(result); } else { error++; - Serial.print((char) STK_NOSYNC); + SERIAL_PRG.print((char) STK_NOSYNC); } return; } - Serial.print((char)STK_FAILED); + SERIAL_PRG.print((char)STK_FAILED); } char flash_read_page(unsigned length) { for (unsigned x = 0; x < length; x+=2) { char ch; ch = flash_read_cmd(LOW, here); - Serial.print(ch); + SERIAL_PRG.print(ch); ch = flash_read_cmd(HIGH, here); - Serial.print(ch); + SERIAL_PRG.print(ch); here++; } return STK_OK; @@ -496,7 +507,7 @@ char eeprom_read_page(unsigned length) { uint16_t addr = here << 1; for (unsigned x = 0; x < length; x++, addr++) { uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF); - Serial.print((char) ee); + SERIAL_PRG.print((char) ee); } return STK_OK; } @@ -508,30 +519,30 @@ void read_page(void) { char memtype = getch(); if (CRC_EOP != getch()) { error++; - Serial.print((char) STK_NOSYNC); + SERIAL_PRG.print((char) STK_NOSYNC); return; } - Serial.print((char) STK_INSYNC); + SERIAL_PRG.print((char) STK_INSYNC); if (memtype == 'F') result = flash_read_page(length); if (memtype == 'E') result = eeprom_read_page(length); - Serial.print(result); + SERIAL_PRG.print(result); } void read_signature(void) { if (CRC_EOP != getch()) { error++; - Serial.print((char) STK_NOSYNC); + SERIAL_PRG.print((char) STK_NOSYNC); return; } - Serial.print((char) STK_INSYNC); + SERIAL_PRG.print((char) STK_INSYNC); char ch; ch = spi_transaction(0x30, 0x00, 0x00, 0x00); - Serial.print(ch); + SERIAL_PRG.print(ch); ch = spi_transaction(0x30, 0x00, 0x01, 0x00); - Serial.print(ch); + SERIAL_PRG.print(ch); ch = spi_transaction(0x30, 0x00, 0x02, 0x00); - Serial.print(ch); - Serial.print((char) STK_OK); + SERIAL_PRG.print(ch); + SERIAL_PRG.print((char) STK_OK); } ////////////////////////////////////////// ////////////////////////////////////////// @@ -550,12 +561,12 @@ void avrisp(void) { break; case '1': if (getch() == CRC_EOP) { - Serial.print((char) STK_INSYNC); - Serial.print("AVR ISP"); - Serial.print((char) STK_OK); + SERIAL_PRG.print((char) STK_INSYNC); + SERIAL_PRG.print("AVR ISP"); + SERIAL_PRG.print((char) STK_OK); } else { error++; - Serial.print((char) STK_NOSYNC); + SERIAL_PRG.print((char) STK_NOSYNC); } break; case 'A': @@ -620,15 +631,15 @@ void avrisp(void) { // this is how we can get back in sync case CRC_EOP: error++; - Serial.print((char) STK_NOSYNC); + SERIAL_PRG.print((char) STK_NOSYNC); break; // anything else we will return STK_UNKNOWN default: error++; if (CRC_EOP == getch()) - Serial.print((char)STK_UNKNOWN); + SERIAL_PRG.print((char)STK_UNKNOWN); else - Serial.print((char)STK_NOSYNC); + SERIAL_PRG.print((char)STK_NOSYNC); } } From c1cfe818e407d4927f92e821793ba7cd54be4b61 Mon Sep 17 00:00:00 2001 From: Peter Van Hoyweghen Date: Sun, 2 Jun 2013 22:05:09 +0200 Subject: [PATCH 12/13] add TRACE macro's (printf debugging on second uart) --- ArduinoISP/ArduinoISP.ino | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index 7dad5597..d5dd8cdf 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -63,14 +63,21 @@ #define RESETDELAY 0 +// uncomment if you want to have debug traces +// (needs a separate uart so works only on Sanguino, Leonardo, Due...) +//#define TRACES #ifdef __SAM3X8E__ +// Select uart to use for programming and debugging: #define SERIAL_PRG SerialUSB +#define SERIAL_DBG Serial #else +// Select uart to use for programming and debugging: #define SERIAL_PRG Serial +#define SERIAL_DBG Serial1 #endif @@ -114,6 +121,19 @@ #define LED_HB 6 #endif +#ifdef TRACES +#define TRACE_BEGIN(baud) SERIAL_DBG.begin(baud) +#define TRACE(x) SERIAL_DBG.print(x) +#define TRACELN(x) SERIAL_DBG.println(x) +#define TRACE2(x, format) SERIAL_DBG.print(x, format) +#define TRACE2LN(x, format) SERIAL_DBG.println(x, format) +#else +#define TRACE_BEGIN(baud) +#define TRACE(x) +#define TRACELN(x) +#define TRACE2(x, format) +#define TRACE2LN(x, format) +#endif // STK Definitions @@ -185,6 +205,9 @@ void setup(void) { TCCR1B = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // no clock prescale SREG = sreg; // restore interrupts #endif + + TRACE_BEGIN(115200); + TRACELN("*** setup ***"); } uint8_t error=0; @@ -554,6 +577,8 @@ void read_signature(void) { void avrisp(void) { uint8_t data, low, high; uint8_t ch = getch(); + TRACE("> "); + TRACELN((char) ch); switch (ch) { case '0': // signon error = 0; From efd3e7a1f9f88bbe328a9ee22f9ab45e2b9d6313 Mon Sep 17 00:00:00 2001 From: Peter Van Hoyweghen Date: Tue, 4 Jun 2013 22:19:42 +0200 Subject: [PATCH 13/13] rename USE_SPI to USE_HARDWARE_SPI; by default don't use hardware spi on Due --- ArduinoISP/ArduinoISP.ino | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/ArduinoISP/ArduinoISP.ino b/ArduinoISP/ArduinoISP.ino index d5dd8cdf..91c33b66 100644 --- a/ArduinoISP/ArduinoISP.ino +++ b/ArduinoISP/ArduinoISP.ino @@ -54,10 +54,6 @@ //#define BAUDRATE 38400 //#define BAUDRATE 115200 -// comment USE_SPI to use bitbang (digitalWrite()) -// use bitbang to make it work with very slow attiny2313 -#define USE_SPI - // create clock on digital 9 using pwm (timer1), LED_HB must move //#define LADYADA_CLOCK @@ -67,18 +63,28 @@ // (needs a separate uart so works only on Sanguino, Leonardo, Due...) //#define TRACES +// following settings have different defaults on SAM vs. AVR + #ifdef __SAM3X8E__ // Select uart to use for programming and debugging: #define SERIAL_PRG SerialUSB #define SERIAL_DBG Serial +// comment USE_HARDWARE_SPI to use bitbang spi +// use bitbang to make it work with very slow attiny2313 +// #define USE_HARDWARE_SPI + #else // Select uart to use for programming and debugging: #define SERIAL_PRG Serial #define SERIAL_DBG Serial1 +// comment USE_HARDWARE_SPI to use bitbang spi +// use bitbang to make it work with very slow attiny2313 +#define USE_HARDWARE_SPI + #endif /////////////////////////////////////////////// @@ -87,7 +93,7 @@ -#ifdef USE_SPI +#ifdef USE_HARDWARE_SPI #include "SPI.h" #ifdef __AVR__ // this would better go into SPI lib @@ -146,7 +152,7 @@ void pulse(uint8_t pin, uint8_t times); -#ifndef USE_SPI +#ifndef USE_HARDWARE_SPI class BitBangedSPI { public: @@ -178,7 +184,7 @@ static BitBangedSPI SPI; void setup(void) { SERIAL_PRG.begin(BAUDRATE); -#ifdef USE_SPI +#ifdef USE_HARDWARE_SPI SPI.setDataMode(0); SPI.setBitOrder(MSBFIRST); // Clock Div can be 2,4,8,16,32,64, or 128