Arduino as ISP 16u2 fix
This commit is contained in:
parent
4251522cf7
commit
4775b3881c
2 changed files with 173 additions and 172 deletions
15
Readme.md
15
Readme.md
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue