10
10
// 8: Error - Lights up if something goes wrong (use red if that makes sense)
11
11
// 7: Programming - In communication with the slave
12
12
//
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
+ //
13
21
// October 2009 by David A. Mellis
14
22
// - Added support for the read signature command
15
23
//
24
32
// - The SPI functions herein were developed for the AVR910_ARD programmer
25
33
// - More information at http://code.google.com/p/mega-isp
26
34
27
- #include " pins_arduino.h" // defines SS,MOSI,MISO,SCK
35
+ #include " pins_arduino.h"
28
36
#define RESET SS
29
37
30
38
#define LED_HB 9
31
39
#define LED_ERR 8
32
40
#define LED_PMODE 7
41
+ #define PROG_FLICKER true
33
42
34
43
#define HWVER 2
35
44
#define SWMAJ 1
@@ -47,12 +56,12 @@ void pulse(int pin, int times);
47
56
48
57
void setup () {
49
58
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 );
56
65
}
57
66
58
67
int error= 0 ;
@@ -112,9 +121,9 @@ uint8_t getch() {
112
121
while (! Serial . available());
113
122
return Serial . read();
114
123
}
115
- void readbytes (int n ) {
124
+ void fill (int n ) {
116
125
for (int x = 0 ; x < n; x++ ) {
117
- buff[x] = Serial . read ();
126
+ buff[x] = getch ();
118
127
}
119
128
}
120
129
@@ -129,6 +138,11 @@ void pulse(int pin, int times) {
129
138
while (times-- );
130
139
}
131
140
141
+ void prog_lamp (int state ) {
142
+ if (PROG_FLICKER )
143
+ digitalWrite(LED_PMODE , state);
144
+ }
145
+
132
146
void spi_init () {
133
147
uint8_t x;
134
148
SPCR = 0x53 ;
@@ -163,8 +177,8 @@ void empty_reply() {
163
177
if (CRC_EOP == getch()) {
164
178
Serial . print((char )STK_INSYNC );
165
179
Serial . print((char )STK_OK );
166
- }
167
- else {
180
+ } else {
181
+ error ++ ;
168
182
Serial . print((char )STK_NOSYNC );
169
183
}
170
184
}
@@ -176,6 +190,7 @@ void breply(uint8_t b) {
176
190
Serial . print((char )STK_OK );
177
191
}
178
192
else {
193
+ error++ ;
179
194
Serial . print((char )STK_NOSYNC );
180
195
}
181
196
}
@@ -211,9 +226,6 @@ void set_parameters() {
211
226
param. fusebytes = buff[7 ];
212
227
param. flashpoll = buff[8 ];
213
228
// ignore buff[9] (= buff[8])
214
- // getch(); // discard second value
215
-
216
- // WARNING: not sure about the byte order of the following
217
229
// following are 16 bits (big endian)
218
230
param. eeprompoll = beget16(& buff[10 ]);
219
231
param. pagesize = beget16(& buff[12 ]);
@@ -255,9 +267,7 @@ void universal() {
255
267
int w;
256
268
uint8_t ch;
257
269
258
- for (w = 0 ; w < 4 ; w++ ) {
259
- buff[w] = getch();
260
- }
270
+ fill (4 );
261
271
ch = spi_transaction(buff[0 ], buff[1 ], buff[2 ], buff[3 ]);
262
272
breply(ch);
263
273
}
@@ -269,7 +279,12 @@ void flash(uint8_t hilo, int addr, uint8_t data) {
269
279
data);
270
280
}
271
281
void commit (int addr ) {
282
+ if (PROG_FLICKER ) prog_lamp(LOW );
272
283
spi_transaction(0x4C , (addr >> 8 ) & 0xFF , addr & 0xFF , 0 );
284
+ if (PROG_FLICKER ) {
285
+ delay (PTIME );
286
+ prog_lamp(HIGH );
287
+ }
273
288
}
274
289
275
290
// #define _current_page(x) (here & 0xFFFFE0)
@@ -280,11 +295,22 @@ int current_page(int addr) {
280
295
if (param. pagesize == 256 ) return here & 0xFFFFFF80 ;
281
296
return here;
282
297
}
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 ) {
287
312
int x = 0 ;
313
+ int page = current_page(here);
288
314
while (x < length) {
289
315
if (page != current_page(here)) {
290
316
commit(page);
@@ -300,38 +326,62 @@ uint8_t write_flash(int length) {
300
326
return STK_OK ;
301
327
}
302
328
329
+ #define EECHUNK (32 )
303
330
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 ) {
305
348
// this writes byte-by-byte,
306
349
// page writing may be faster (4 bytes at a time)
350
+ fill (length);
351
+ prog_lamp(LOW );
307
352
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]);
309
355
delay (45 );
310
- }
356
+ }
357
+ prog_lamp(HIGH );
311
358
return STK_OK ;
312
359
}
313
360
314
361
void program_page () {
315
362
char result = (char ) STK_FAILED ;
316
363
int length = 256 * getch() + getch();
317
- if (length > 256 ) {
318
- Serial . print((char ) STK_FAILED );
319
- return ;
320
- }
321
364
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 ;
324
369
}
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 ;
333
380
}
381
+ Serial . print((char )STK_FAILED );
382
+ return ;
334
383
}
384
+
335
385
uint8_t flash_read (uint8_t hilo , int addr ) {
336
386
return spi_transaction(0x20 + hilo * 8 ,
337
387
(addr >> 8 ) & 0xFF ,
@@ -352,8 +402,10 @@ char flash_read_page(int length) {
352
402
353
403
char eeprom_read_page (int length ) {
354
404
// here again we have a word address
405
+ int start = here * 2 ;
355
406
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 );
357
409
Serial . print((char ) ee);
358
410
}
359
411
return STK_OK ;
@@ -364,6 +416,7 @@ void read_page() {
364
416
int length = 256 * getch() + getch();
365
417
char memtype = getch();
366
418
if (CRC_EOP != getch()) {
419
+ error++ ;
367
420
Serial . print((char ) STK_NOSYNC );
368
421
return ;
369
422
}
@@ -376,6 +429,7 @@ void read_page() {
376
429
377
430
void read_signature () {
378
431
if (CRC_EOP != getch()) {
432
+ error++ ;
379
433
Serial . print((char ) STK_NOSYNC );
380
434
return ;
381
435
}
@@ -399,6 +453,7 @@ int avrisp() {
399
453
uint8_t ch = getch();
400
454
switch (ch) {
401
455
case ' 0' : // signon
456
+ error = 0 ;
402
457
empty_reply();
403
458
break ;
404
459
case ' 1' :
@@ -412,20 +467,20 @@ int avrisp() {
412
467
get_version(getch());
413
468
break ;
414
469
case ' B' :
415
- readbytes (20 );
470
+ fill (20 );
416
471
set_parameters();
417
472
empty_reply();
418
473
break ;
419
474
case ' E' : // extended parameters - ignore for now
420
- readbytes (5 );
475
+ fill (5 );
421
476
empty_reply();
422
477
break ;
423
478
424
479
case ' P' :
425
480
start_pmode();
426
481
empty_reply();
427
482
break ;
428
- case ' U' :
483
+ case ' U' : // set address (word)
429
484
here = getch() + 256 * getch();
430
485
empty_reply();
431
486
break ;
@@ -444,31 +499,33 @@ int avrisp() {
444
499
program_page();
445
500
break ;
446
501
447
- case 0x74 : // STK_READ_PAGE
502
+ case 0x74 : // STK_READ_PAGE 't'
448
503
read_page();
449
504
break ;
450
505
451
- case ' V' :
506
+ case ' V' : // 0x56
452
507
universal();
453
508
break ;
454
- case ' Q' :
509
+ case ' Q' : // 0x51
455
510
error= 0 ;
456
511
end_pmode();
457
512
empty_reply();
458
513
break ;
459
514
460
- case 0x75 : // STK_READ_SIGN
515
+ case 0x75 : // STK_READ_SIGN 'u'
461
516
read_signature();
462
517
break ;
463
518
464
519
// expecting a command, not CRC_EOP
465
520
// this is how we can get back in sync
466
521
case CRC_EOP :
522
+ error++ ;
467
523
Serial . print((char ) STK_NOSYNC );
468
524
break ;
469
525
470
526
// anything else we will return STK_UNKNOWN
471
527
default :
528
+ error++ ;
472
529
if (CRC_EOP == getch())
473
530
Serial . print((char )STK_UNKNOWN );
474
531
else
0 commit comments