Skip to content

Commit bc480b0

Browse files
author
Randall Bohn (Huckle)
committed
ArduinoISP 04 - fixes write to EEPROM
1 parent cefcc8c commit bc480b0

File tree

1 file changed

+103
-46
lines changed

1 file changed

+103
-46
lines changed

ArduinoISP/ArduinoISP.pde

Lines changed: 103 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@
1010
// 8: Error - Lights up if something goes wrong (use red if that makes sense)
1111
// 7: Programming - In communication with the slave
1212
//
13+
// October 2010 by Randall Bohn
14+
// - Write to EEPROM > 256 bytes
15+
// - Better use of LEDs:
16+
// -- Flash LED_PMODE on each flash commit
17+
// -- Flash LED_PMODE while writing EEPROM (both give visual feedback of writing progress)
18+
// - Light LED_ERR whenever we hit a STK_NOSYNC. Turn it off when back in sync.
19+
// - Use pins_arduino.h (should also work on Arduino Mega)
20+
//
1321
// October 2009 by David A. Mellis
1422
// - Added support for the read signature command
1523
//
@@ -24,12 +32,13 @@
2432
// - The SPI functions herein were developed for the AVR910_ARD programmer
2533
// - More information at http://code.google.com/p/mega-isp
2634

27-
#include "pins_arduino.h" // defines SS,MOSI,MISO,SCK
35+
#include "pins_arduino.h"
2836
#define RESET SS
2937

3038
#define LED_HB 9
3139
#define LED_ERR 8
3240
#define LED_PMODE 7
41+
#define PROG_FLICKER true
3342

3443
#define HWVER 2
3544
#define SWMAJ 1
@@ -47,12 +56,12 @@ void pulse(int pin, int times);
4756

4857
void setup() {
4958
Serial.begin(19200);
50-
pinMode(7, OUTPUT);
51-
pulse(7, 2);
52-
pinMode(8, OUTPUT);
53-
pulse(8, 2);
54-
pinMode(9, OUTPUT);
55-
pulse(9, 2);
59+
pinMode(LED_PMODE, OUTPUT);
60+
pulse(LED_PMODE, 2);
61+
pinMode(LED_ERR, OUTPUT);
62+
pulse(LED_ERR, 2);
63+
pinMode(LED_HB, OUTPUT);
64+
pulse(LED_HB, 2);
5665
}
5766

5867
int error=0;
@@ -112,9 +121,9 @@ uint8_t getch() {
112121
while(!Serial.available());
113122
return Serial.read();
114123
}
115-
void readbytes(int n) {
124+
void fill(int n) {
116125
for (int x = 0; x < n; x++) {
117-
buff[x] = Serial.read();
126+
buff[x] = getch();
118127
}
119128
}
120129

@@ -129,6 +138,11 @@ void pulse(int pin, int times) {
129138
while (times--);
130139
}
131140

141+
void prog_lamp(int state) {
142+
if (PROG_FLICKER)
143+
digitalWrite(LED_PMODE, state);
144+
}
145+
132146
void spi_init() {
133147
uint8_t x;
134148
SPCR = 0x53;
@@ -163,8 +177,8 @@ void empty_reply() {
163177
if (CRC_EOP == getch()) {
164178
Serial.print((char)STK_INSYNC);
165179
Serial.print((char)STK_OK);
166-
}
167-
else {
180+
} else {
181+
error++;
168182
Serial.print((char)STK_NOSYNC);
169183
}
170184
}
@@ -176,6 +190,7 @@ void breply(uint8_t b) {
176190
Serial.print((char)STK_OK);
177191
}
178192
else {
193+
error++;
179194
Serial.print((char)STK_NOSYNC);
180195
}
181196
}
@@ -211,9 +226,6 @@ void set_parameters() {
211226
param.fusebytes = buff[7];
212227
param.flashpoll = buff[8];
213228
// ignore buff[9] (= buff[8])
214-
//getch(); // discard second value
215-
216-
// WARNING: not sure about the byte order of the following
217229
// following are 16 bits (big endian)
218230
param.eeprompoll = beget16(&buff[10]);
219231
param.pagesize = beget16(&buff[12]);
@@ -255,9 +267,7 @@ void universal() {
255267
int w;
256268
uint8_t ch;
257269

258-
for (w = 0; w < 4; w++) {
259-
buff[w] = getch();
260-
}
270+
fill(4);
261271
ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
262272
breply(ch);
263273
}
@@ -269,7 +279,12 @@ void flash(uint8_t hilo, int addr, uint8_t data) {
269279
data);
270280
}
271281
void commit(int addr) {
282+
if (PROG_FLICKER) prog_lamp(LOW);
272283
spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
284+
if (PROG_FLICKER) {
285+
delay(PTIME);
286+
prog_lamp(HIGH);
287+
}
273288
}
274289

275290
//#define _current_page(x) (here & 0xFFFFE0)
@@ -280,11 +295,22 @@ int current_page(int addr) {
280295
if (param.pagesize == 256) return here & 0xFFFFFF80;
281296
return here;
282297
}
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);
298+
299+
300+
void write_flash(int length) {
301+
fill(length);
302+
if (CRC_EOP == getch()) {
303+
Serial.print((char) STK_INSYNC);
304+
Serial.print((char) write_flash_pages(length));
305+
} else {
306+
error++;
307+
Serial.print((char) STK_NOSYNC);
308+
}
309+
}
310+
311+
uint8_t write_flash_pages(int length) {
287312
int x = 0;
313+
int page = current_page(here);
288314
while (x < length) {
289315
if (page != current_page(here)) {
290316
commit(page);
@@ -300,38 +326,62 @@ uint8_t write_flash(int length) {
300326
return STK_OK;
301327
}
302328

329+
#define EECHUNK (32)
303330
uint8_t write_eeprom(int length) {
304-
// here is a word address, so we use here*2
331+
// here is a word address, get the byte address
332+
int start = here * 2;
333+
int remaining = length;
334+
if (length > param.eepromsize) {
335+
error++;
336+
return STK_FAILED;
337+
}
338+
while (remaining > EECHUNK) {
339+
write_eeprom_chunk(start, EECHUNK);
340+
start += EECHUNK;
341+
remaining -= EECHUNK;
342+
}
343+
write_eeprom_chunk(start, remaining);
344+
return STK_OK;
345+
}
346+
// write (length) bytes, (start) is a byte address
347+
uint8_t write_eeprom_chunk(int start, int length) {
305348
// this writes byte-by-byte,
306349
// page writing may be faster (4 bytes at a time)
350+
fill(length);
351+
prog_lamp(LOW);
307352
for (int x = 0; x < length; x++) {
308-
spi_transaction(0xC0, 0x00, here*2+x, buff[x]);
353+
int addr = start+x;
354+
spi_transaction(0xC0, (addr>>8) & 0xFF, addr & 0xFF, buff[x]);
309355
delay(45);
310-
}
356+
}
357+
prog_lamp(HIGH);
311358
return STK_OK;
312359
}
313360

314361
void program_page() {
315362
char result = (char) STK_FAILED;
316363
int length = 256 * getch() + getch();
317-
if (length > 256) {
318-
Serial.print((char) STK_FAILED);
319-
return;
320-
}
321364
char memtype = getch();
322-
for (int x = 0; x < length; x++) {
323-
buff[x] = getch();
365+
// flash memory @here, (length) bytes
366+
if (memtype == 'F') {
367+
write_flash(length);
368+
return;
324369
}
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);
330-
}
331-
else {
332-
Serial.print((char) STK_NOSYNC);
370+
if (memtype == 'E') {
371+
result = (char)write_eeprom(length);
372+
if (CRC_EOP == getch()) {
373+
Serial.print((char) STK_INSYNC);
374+
Serial.print(result);
375+
} else {
376+
error++;
377+
Serial.print((char) STK_NOSYNC);
378+
}
379+
return;
333380
}
381+
Serial.print((char)STK_FAILED);
382+
return;
334383
}
384+
335385
uint8_t flash_read(uint8_t hilo, int addr) {
336386
return spi_transaction(0x20 + hilo * 8,
337387
(addr >> 8) & 0xFF,
@@ -352,8 +402,10 @@ char flash_read_page(int length) {
352402

353403
char eeprom_read_page(int length) {
354404
// here again we have a word address
405+
int start = here * 2;
355406
for (int x = 0; x < length; x++) {
356-
uint8_t ee = spi_transaction(0xA0, 0x00, here*2+x, 0xFF);
407+
int addr = start + x;
408+
uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF);
357409
Serial.print((char) ee);
358410
}
359411
return STK_OK;
@@ -364,6 +416,7 @@ void read_page() {
364416
int length = 256 * getch() + getch();
365417
char memtype = getch();
366418
if (CRC_EOP != getch()) {
419+
error++;
367420
Serial.print((char) STK_NOSYNC);
368421
return;
369422
}
@@ -376,6 +429,7 @@ void read_page() {
376429

377430
void read_signature() {
378431
if (CRC_EOP != getch()) {
432+
error++;
379433
Serial.print((char) STK_NOSYNC);
380434
return;
381435
}
@@ -399,6 +453,7 @@ int avrisp() {
399453
uint8_t ch = getch();
400454
switch (ch) {
401455
case '0': // signon
456+
error = 0;
402457
empty_reply();
403458
break;
404459
case '1':
@@ -412,20 +467,20 @@ int avrisp() {
412467
get_version(getch());
413468
break;
414469
case 'B':
415-
readbytes(20);
470+
fill(20);
416471
set_parameters();
417472
empty_reply();
418473
break;
419474
case 'E': // extended parameters - ignore for now
420-
readbytes(5);
475+
fill(5);
421476
empty_reply();
422477
break;
423478

424479
case 'P':
425480
start_pmode();
426481
empty_reply();
427482
break;
428-
case 'U':
483+
case 'U': // set address (word)
429484
here = getch() + 256 * getch();
430485
empty_reply();
431486
break;
@@ -444,31 +499,33 @@ int avrisp() {
444499
program_page();
445500
break;
446501

447-
case 0x74: //STK_READ_PAGE
502+
case 0x74: //STK_READ_PAGE 't'
448503
read_page();
449504
break;
450505

451-
case 'V':
506+
case 'V': //0x56
452507
universal();
453508
break;
454-
case 'Q':
509+
case 'Q': //0x51
455510
error=0;
456511
end_pmode();
457512
empty_reply();
458513
break;
459514

460-
case 0x75: //STK_READ_SIGN
515+
case 0x75: //STK_READ_SIGN 'u'
461516
read_signature();
462517
break;
463518

464519
// expecting a command, not CRC_EOP
465520
// this is how we can get back in sync
466521
case CRC_EOP:
522+
error++;
467523
Serial.print((char) STK_NOSYNC);
468524
break;
469525

470526
// anything else we will return STK_UNKNOWN
471527
default:
528+
error++;
472529
if (CRC_EOP == getch())
473530
Serial.print((char)STK_UNKNOWN);
474531
else

0 commit comments

Comments
 (0)