1
// this sketch turns the Arduino into a AVRISP
2
// using the following pins:
8
// Put an LED (with resistor) on the following pins:
9
// 9: Heartbeat - shows the programmer is running
10
// 8: Error - Lights up if something goes wrong (use red if that makes sense)
11
// 7: Programming - In communication with the slave
13
// October 2009 by David A. Mellis
14
// - Added support for the read signature command
16
// February 2009 by Randall Bohn
17
// - Added support for writing to EEPROM (what took so long?)
18
// Windows users should consider WinAVR's avrdude instead of the
19
// avrdude included with Arduino software.
21
// January 2008 by Randall Bohn
22
// - Thanks to Amplificar for helping me with the STK500 protocol
23
// - The AVRISP/STK500 (mk I) protocol is used in the arduino bootloader
24
// - The SPI functions herein were developed for the AVR910_ARD programmer
25
// - More information at http://code.google.com/p/mega-isp
27
#include "pins_arduino.h" // defines SS,MOSI,MISO,SCK
40
#define STK_FAILED 0x11
41
#define STK_UNKNOWN 0x12
42
#define STK_INSYNC 0x14
43
#define STK_NOSYNC 0x15
44
#define CRC_EOP 0x20 //ok it is a space...
46
void pulse(int pin, int times);
60
// address for reading and writing, set by 'U' command
62
uint8_t buff[256]; // global block storage
64
#define beget16(addr) (*addr * 256 + *(addr+1) )
65
typedef struct param {
84
// this provides a heartbeat on pin 9, so you can tell the software is running.
88
if (hbval > 192) hbdelta = -hbdelta;
89
if (hbval < 32) hbdelta = -hbdelta;
91
analogWrite(LED_HB, hbval);
98
if (pmode) digitalWrite(LED_PMODE, HIGH);
99
else digitalWrite(LED_PMODE, LOW);
100
// is there an error?
101
if (error) digitalWrite(LED_ERR, HIGH);
102
else digitalWrite(LED_ERR, LOW);
104
// light the heartbeat LED
106
if (Serial.available()) {
112
while(!Serial.available());
113
return Serial.read();
115
void readbytes(int n) {
116
for (int x = 0; x < n; x++) {
117
buff[x] = Serial.read();
122
void pulse(int pin, int times) {
124
digitalWrite(pin, HIGH);
126
digitalWrite(pin, LOW);
142
while (!(SPSR & (1 << SPIF)));
145
uint8_t spi_send(uint8_t b) {
153
uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
157
//if (n != a) error = -1;
163
if (CRC_EOP == getch()) {
164
Serial.print((char)STK_INSYNC);
165
Serial.print((char)STK_OK);
168
Serial.print((char)STK_NOSYNC);
172
void breply(uint8_t b) {
173
if (CRC_EOP == getch()) {
174
Serial.print((char)STK_INSYNC);
175
Serial.print((char)b);
176
Serial.print((char)STK_OK);
179
Serial.print((char)STK_NOSYNC);
183
void get_version(uint8_t c) {
195
breply('S'); // serial programmer
202
void set_parameters() {
203
// call this after reading paramter packet into buff[]
204
param.devicecode = buff[0];
205
param.revision = buff[1];
206
param.progtype = buff[2];
207
param.parmode = buff[3];
208
param.polling = buff[4];
209
param.selftimed = buff[5];
210
param.lockbytes = buff[6];
211
param.fusebytes = buff[7];
212
param.flashpoll = buff[8];
213
// ignore buff[9] (= buff[8])
214
//getch(); // discard second value
216
// WARNING: not sure about the byte order of the following
217
// following are 16 bits (big endian)
218
param.eeprompoll = beget16(&buff[10]);
219
param.pagesize = beget16(&buff[12]);
220
param.eepromsize = beget16(&buff[14]);
222
// 32 bits flashsize (big endian)
223
param.flashsize = buff[16] * 0x01000000
224
+ buff[17] * 0x00010000
225
+ buff[18] * 0x00000100
232
// following delays may not work on all targets...
233
pinMode(RESET, OUTPUT);
234
digitalWrite(RESET, HIGH);
235
pinMode(SCK, OUTPUT);
236
digitalWrite(SCK, LOW);
238
digitalWrite(RESET, LOW);
240
pinMode(MISO, INPUT);
241
pinMode(MOSI, OUTPUT);
242
spi_transaction(0xAC, 0x53, 0x00, 0x00);
247
pinMode(MISO, INPUT);
248
pinMode(MOSI, INPUT);
250
pinMode(RESET, INPUT);
258
for (w = 0; w < 4; w++) {
261
ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
265
void flash(uint8_t hilo, int addr, uint8_t data) {
266
spi_transaction(0x40+8*hilo,
271
void commit(int addr) {
272
spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
275
//#define _current_page(x) (here & 0xFFFFE0)
276
int current_page(int addr) {
277
if (param.pagesize == 32) return here & 0xFFFFFFF0;
278
if (param.pagesize == 64) return here & 0xFFFFFFE0;
279
if (param.pagesize == 128) return here & 0xFFFFFFC0;
280
if (param.pagesize == 256) return here & 0xFFFFFF80;
283
uint8_t write_flash(int length) {
284
if (param.pagesize < 1) return STK_FAILED;
285
//if (param.pagesize != 64) return STK_FAILED;
286
int page = current_page(here);
289
if (page != current_page(here)) {
291
page = current_page(here);
293
flash(LOW, here, buff[x++]);
294
flash(HIGH, here, buff[x++]);
303
uint8_t write_eeprom(int length) {
304
// here is a word address, so we use here*2
305
// this writes byte-by-byte,
306
// page writing may be faster (4 bytes at a time)
307
for (int x = 0; x < length; x++) {
308
spi_transaction(0xC0, 0x00, here*2+x, buff[x]);
314
void program_page() {
315
char result = (char) STK_FAILED;
316
int length = 256 * getch() + getch();
318
Serial.print((char) STK_FAILED);
321
char memtype = getch();
322
for (int x = 0; x < length; x++) {
325
if (CRC_EOP == getch()) {
326
Serial.print((char) STK_INSYNC);
327
if (memtype == 'F') result = (char)write_flash(length);
328
if (memtype == 'E') result = (char)write_eeprom(length);
329
Serial.print(result);
332
Serial.print((char) STK_NOSYNC);
335
uint8_t flash_read(uint8_t hilo, int addr) {
336
return spi_transaction(0x20 + hilo * 8,
342
char flash_read_page(int length) {
343
for (int x = 0; x < length; x+=2) {
344
uint8_t low = flash_read(LOW, here);
345
Serial.print((char) low);
346
uint8_t high = flash_read(HIGH, here);
347
Serial.print((char) high);
353
char eeprom_read_page(int length) {
354
// here again we have a word address
355
for (int x = 0; x < length; x++) {
356
uint8_t ee = spi_transaction(0xA0, 0x00, here*2+x, 0xFF);
357
Serial.print((char) ee);
363
char result = (char)STK_FAILED;
364
int length = 256 * getch() + getch();
365
char memtype = getch();
366
if (CRC_EOP != getch()) {
367
Serial.print((char) STK_NOSYNC);
370
Serial.print((char) STK_INSYNC);
371
if (memtype == 'F') result = flash_read_page(length);
372
if (memtype == 'E') result = eeprom_read_page(length);
373
Serial.print(result);
377
void read_signature() {
378
if (CRC_EOP != getch()) {
379
Serial.print((char) STK_NOSYNC);
382
Serial.print((char) STK_INSYNC);
383
uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00);
384
Serial.print((char) high);
385
uint8_t middle = spi_transaction(0x30, 0x00, 0x01, 0x00);
386
Serial.print((char) middle);
387
uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00);
388
Serial.print((char) low);
389
Serial.print((char) STK_OK);
391
//////////////////////////////////////////
392
//////////////////////////////////////////
395
////////////////////////////////////
396
////////////////////////////////////
398
uint8_t data, low, high;
399
uint8_t ch = getch();
405
if (getch() == CRC_EOP) {
406
Serial.print((char) STK_INSYNC);
407
Serial.print("AVR ISP");
408
Serial.print((char) STK_OK);
412
get_version(getch());
419
case 'E': // extended parameters - ignore for now
429
here = getch() + 256 * getch();
433
case 0x60: //STK_PROG_FLASH
438
case 0x61: //STK_PROG_DATA
443
case 0x64: //STK_PROG_PAGE
447
case 0x74: //STK_READ_PAGE
460
case 0x75: //STK_READ_SIGN
464
// expecting a command, not CRC_EOP
465
// this is how we can get back in sync
467
Serial.print((char) STK_NOSYNC);
470
// anything else we will return STK_UNKNOWN
472
if (CRC_EOP == getch())
473
Serial.print((char)STK_UNKNOWN);
475
Serial.print((char)STK_NOSYNC);