Arduino as ISP 16u2 fix

This commit is contained in:
Nico 2015-01-24 22:12:54 +01:00
parent 4251522cf7
commit 4775b3881c
2 changed files with 173 additions and 172 deletions

View file

@ -13,6 +13,13 @@ All documentation moved to the [wiki page](https://github.com/NicoHood/HID/wiki)
An offline version will be available soon.
Contact
=======
You can contact me on my wordpress blog in the contact section.
www.nicohood.de
TODO
====
@ -31,12 +38,14 @@ update Burning via ISP for HL2
Test with Android phone (HL1)
"Emulate" HL1 protocol
remove dev HL2 link
HL2 usb hub fix (try with a bare cdc bootloader?)
```
Version History
===============
```
2.1 Release (xx.01.2015)
2.1 Release (28.01.2015)
* Reworked the whole USB-Core from scratch
* Uses less flash if HID or Serial is not used
* Extended and compacter(flash) HID Report Descriptors
@ -64,8 +73,8 @@ Version History
* Added HID Tables
* USB-Serial now fully reprogrammable
* Easy USB-Core selection via Tools->USB-Core
* Added Arduino as ISP fix for 32u4 (u2 Series doesn't work at the moment)
* Updated USB-Serial
* Added Arduino as ISP fix for 32u4 and 16u2
* Moved documentation to the wiki
2.0 Release (29.11.2014)
* Added HoodLoader2

View file

@ -1,16 +1,16 @@
// 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
// SCK: 13: 52
// 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
@ -31,7 +31,7 @@
//
// 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,11 +40,17 @@
// 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
#include "SPI.h"
#include "pins_arduino.h"
#ifdef ARDUINO_HOODLOADER2
#define RESET 4
#else
#define RESET 10
#endif
#define LED_HB 9
#define LED_ERR 8
@ -67,16 +73,21 @@ void pulse(int pin, int times);
void setup() {
Serial.begin(19200);
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);
pulse(LED_ERR, 2);
pinMode(LED_HB, OUTPUT);
pulse(LED_HB, 2);
}
int error = 0;
int pmode = 0;
int error=0;
int pmode=0;
// address for reading and writing, set by 'U' command
int here;
uint8_t buff[256]; // global block storage
@ -91,34 +102,34 @@ typedef struct param {
uint8_t selftimed;
uint8_t lockbytes;
uint8_t fusebytes;
int flashpoll;
int eeprompoll;
int pagesize;
int eepromsize;
int flashsize;
}
uint8_t flashpoll;
uint16_t eeprompoll;
uint16_t pagesize;
uint16_t eepromsize;
uint32_t 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;
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);
delay(40);
}
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
@ -129,7 +140,7 @@ void loop(void) {
}
uint8_t getch() {
while (!Serial.available());
while(!Serial.available());
return Serial.read();
}
void fill(int n) {
@ -145,7 +156,7 @@ void pulse(int pin, int times) {
delay(PTIME);
digitalWrite(pin, LOW);
delay(PTIME);
}
}
while (times--);
}
@ -154,41 +165,20 @@ void prog_lamp(int state) {
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);
SPI.transfer(a);
n=SPI.transfer(b);
//if (n != a) error = -1;
n = spi_send(c);
return spi_send(d);
n=SPI.transfer(c);
return SPI.transfer(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);
@ -200,7 +190,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);
@ -208,21 +198,21 @@ void breply(uint8_t b) {
}
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);
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);
}
}
@ -236,7 +226,7 @@ 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]);
@ -245,32 +235,26 @@ void set_parameters() {
// 32 bits flashsize (big endian)
param.flashsize = buff[16] * 0x01000000
+ buff[17] * 0x00010000
+ buff[18] * 0x00000100
+ buff[19];
+ buff[17] * 0x00010000
+ buff[18] * 0x00000100
+ buff[19];
}
void start_pmode() {
spi_init();
// following delays may not work on all targets...
pinMode(RESET, OUTPUT);
SPI.begin();
digitalWrite(RESET, HIGH);
pinMode(SCK, OUTPUT);
pinMode(RESET, OUTPUT);
digitalWrite(SCK, LOW);
delay(50);
delay(20);
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);
SPI.end();
digitalWrite(RESET, HIGH);
pinMode(RESET, INPUT);
pmode = 0;
}
@ -285,10 +269,10 @@ void universal() {
}
void flash(uint8_t hilo, int addr, uint8_t data) {
spi_transaction(0x40 + 8 * hilo,
addr >> 8 & 0xFF,
addr & 0xFF,
data);
spi_transaction(0x40+8*hilo,
addr>>8 & 0xFF,
addr & 0xFF,
data);
}
void commit(int addr) {
if (PROG_FLICKER) prog_lamp(LOW);
@ -314,7 +298,7 @@ void write_flash(int length) {
if (CRC_EOP == getch()) {
Serial.print((char) STK_INSYNC);
Serial.print((char) write_flash_pages(length));
}
}
else {
error++;
Serial.print((char) STK_NOSYNC);
@ -363,11 +347,11 @@ uint8_t write_eeprom_chunk(int start, int length) {
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]);
int addr = start+x;
spi_transaction(0xC0, (addr>>8) & 0xFF, addr & 0xFF, buff[x]);
delay(45);
}
prog_lamp(HIGH);
prog_lamp(HIGH);
return STK_OK;
}
@ -386,7 +370,7 @@ void program_page() {
if (CRC_EOP == getch()) {
Serial.print((char) STK_INSYNC);
Serial.print(result);
}
}
else {
error++;
Serial.print((char) STK_NOSYNC);
@ -399,13 +383,13 @@ void program_page() {
uint8_t flash_read(uint8_t hilo, int addr) {
return spi_transaction(0x20 + hilo * 8,
(addr >> 8) & 0xFF,
addr & 0xFF,
0);
(addr >> 8) & 0xFF,
addr & 0xFF,
0);
}
char flash_read_page(int length) {
for (int x = 0; x < length; x += 2) {
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);
@ -464,91 +448,99 @@ void read_signature() {
////////////////////////////////////
////////////////////////////////////
int avrisp() {
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:
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);
} else {
error++;
Serial.print((char) STK_NOSYNC);
break;
}
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;
// anything else we will return STK_UNKNOWN
default:
error++;
if (CRC_EOP == getch())
Serial.print((char)STK_UNKNOWN);
else
Serial.print((char)STK_NOSYNC);
case 'P':
if (pmode) {
pulse(LED_ERR, 3);
} else {
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);
}
}