Skip to content
This repository was archived by the owner on Apr 4, 2023. It is now read-only.

Commit f8264cd

Browse files
committed
cleaned up fuse management, added fuse mask bits, and added success/error beeping
1 parent 54c2aee commit f8264cd

File tree

4 files changed

+91
-69
lines changed

4 files changed

+91
-69
lines changed

adaLoader.pde

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ byte pageBuffer[128]; /* One page of flash */
6060
#define CLOCK 9 // self-generate 8mhz clock - handy!
6161

6262
#define BUTTON A1
63-
63+
#define PIEZOPIN 2
6464

6565
void setup () {
6666
Serial.begin(9600); /* Initialize serial for status msgs */
6767
Serial.println("\nAdaBootLoader Bootstrap programmer (originally OptiLoader Bill Westfield (WestfW))");
6868

69+
pinMode(PIEZOPIN, OUTPUT);
70+
pinMode(PIEZOPIN2, OUTPUT);
6971

7072
pinMode(LED_PROGMODE, OUTPUT);
7173
pulse(LED_PROGMODE,2);
@@ -103,11 +105,15 @@ void loop (void) {
103105
if (! (targetimage = findImage(signature))) // look for an image
104106
error("Image fail");
105107

106-
if (! programmingFuses(targetimage)) // get fuses ready to program
107-
error("Programming Fuses fail");
108-
109108
eraseChip();
110109

110+
if (! programFuses(targetimage->image_progfuses)) // get fuses ready to program
111+
error("Programming Fuses fail");
112+
113+
if (! verifyFuses(targetimage->image_progfuses, targetimage->fusemask) ) {
114+
error("Failed to verify fuses");
115+
}
116+
111117
byte *hextext = targetimage->image_hexcode;
112118
uint16_t pageaddr = 0;
113119
uint8_t pagesize = pgm_read_byte(&targetimage->image_pagesize);
@@ -129,21 +135,37 @@ void loop (void) {
129135
pageaddr += pagesize;
130136
}
131137

132-
//normalFuses(targetimage); // reset fuses to normal mode
138+
// Set fuses to 'final' state
139+
if (! programFuses(targetimage->image_normfuses))
140+
error("Programming Fuses fail");
141+
133142
end_pmode();
134143
start_pmode();
135-
Serial.println("\nVerifing chip flash");
144+
Serial.println("\nVerifing flash...");
136145
if (! verifyImage(targetimage->image_hexcode) ) {
137146
error("Failed to verify chip");
138147
} else {
139-
Serial.println("Chip flash verified correctly!");
148+
Serial.println("\tFlash verified correctly!");
140149
}
141150

151+
if (! verifyFuses(targetimage->image_normfuses, targetimage->fusemask) ) {
152+
error("Failed to verify fuses");
153+
} else {
154+
Serial.println("Fuses verified correctly!");
155+
}
142156
target_poweroff(); /* turn power off */
157+
tone(PIEZOPIN, 4000, 200);
143158
}
144159

145160

146161

162+
void error(char *string) {
163+
Serial.println(string);
164+
digitalWrite(LED_ERR, HIGH);
165+
while(1) {
166+
tone(PIEZOPIN, 4000, 500);
167+
}
168+
}
147169

148170
void start_pmode () {
149171
pinMode(13, INPUT); // restore to default
@@ -193,9 +215,9 @@ boolean target_poweron ()
193215
digitalWrite(RESET, LOW); // reset it right away.
194216
pinMode(RESET, OUTPUT);
195217
delay(200);
196-
fp("Starting Program Mode");
218+
Serial.print("Starting Program Mode");
197219
start_pmode();
198-
fp(" [OK]\n");
220+
Serial.println(" [OK]");
199221
return true;
200222
}
201223

code.cpp

Lines changed: 51 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ uint16_t readSignature (void)
2121
SPI.setClockDivider(CLOCKSPEED_FUSES);
2222

2323
uint16_t target_type = 0;
24-
fp("\nReading signature:");
24+
Serial.print("\nReading signature:");
2525

2626
target_type = spi_transaction(0x30, 0x00, 0x01, 0x00);
2727
target_type <<= 8;
@@ -30,7 +30,7 @@ uint16_t readSignature (void)
3030
Serial.println(target_type, HEX);
3131
if (target_type == 0 || target_type == 0xFFFF) {
3232
if (target_type == 0) {
33-
fp(" (no target attached?)\n");
33+
Serial.println(" (no target attached?)");
3434
}
3535
}
3636
return target_type;
@@ -46,111 +46,108 @@ uint16_t readSignature (void)
4646
image_t *findImage (uint16_t signature)
4747
{
4848
image_t *ip;
49-
fp("Searching for image...\n");
49+
Serial.println("Searching for image...");
5050

5151
for (byte i=0; i < NUMIMAGES; i++) {
5252
ip = images[i];
5353

5454
if (ip && (pgm_read_word(&ip->image_chipsig) == signature)) {
55-
fp(" Found \"");
55+
Serial.print(" Found \"");
5656
flashprint(&ip->image_name[0]);
57-
fp("\" for ");
57+
Serial.print("\" for ");
5858
flashprint(&ip->image_chipname[0]);
59-
fp("\n");
59+
Serial.println();
6060

6161
return ip;
6262
}
6363
}
64-
fp(" Not Found\n");
64+
Serial.println(" Not Found");
6565
return 0;
6666
}
6767

6868
/*
6969
* programmingFuses
70-
* reprogram the fuses to the state we want during chip programming.
71-
* This is not necessarily the same as the
72-
* 'final' fuses due to changes in clock speed, lock byte, etc
70+
* Program the fuse/lock bits
7371
*/
74-
boolean programmingFuses (image_t *target)
72+
boolean programFuses (const byte *fuses)
7573
{
7674
SPI.setClockDivider(CLOCKSPEED_FUSES);
7775

7876
byte f;
79-
fp("\nSetting fuses for programming");
77+
Serial.print("\nSetting fuses");
8078

81-
f = pgm_read_byte(target->image_progfuses[FUSE_PROT]);
79+
f = pgm_read_byte(&fuses[FUSE_PROT]);
8280
if (f) {
83-
fp("\n Lock: ");
81+
Serial.print("\n Set Lock Fuse to: ");
8482
Serial.print(f, HEX);
85-
fp(" ");
83+
Serial.print(" -> ");
8684
Serial.print(spi_transaction(0xAC, 0xE0, 0x00, f), HEX);
8785
}
88-
f = pgm_read_byte(target->image_progfuses[FUSE_LOW]);
86+
f = pgm_read_byte(&fuses[FUSE_LOW]);
8987
if (f) {
90-
fp(" Low: ");
88+
Serial.print(" Set Low Fuse to: ");
9189
Serial.print(f, HEX);
92-
fp(" ");
90+
Serial.print(" -> ");
9391
Serial.print(spi_transaction(0xAC, 0xA0, 0x00, f), HEX);
9492
}
95-
f = pgm_read_byte(target->image_progfuses[FUSE_HIGH]);
93+
f = pgm_read_byte(&fuses[FUSE_HIGH]);
9694
if (f) {
97-
fp(" High: ");
95+
Serial.print(" Set High Fuse to: ");
9896
Serial.print(f, HEX);
99-
fp(" ");
97+
Serial.print(" -> ");
10098
Serial.print(spi_transaction(0xAC, 0xA8, 0x00, f), HEX);
10199
}
102-
f = pgm_read_byte(target->image_progfuses[FUSE_EXT]);
100+
f = pgm_read_byte(&fuses[FUSE_EXT]);
103101
if (f) {
104-
fp(" Ext: ");
102+
Serial.print(" Set Ext Fuse to: ");
105103
Serial.print(f, HEX);
106-
fp(" ");
104+
Serial.print(" -> ");
107105
Serial.print(spi_transaction(0xAC, 0xA4, 0x00, f), HEX);
108106
}
109107
Serial.println();
110108
return true; /* */
111109
}
112110

113-
114111
/*
115-
* normalFuses
116-
* reprogram the fuses to the state we want after the chip has
117-
* been programmed - this is not necessarily the same as the
118-
* 'programming' fuses due to changes in clock speed, lock byte, etc
112+
* verifyFuses
113+
* Verifies a fuse set
119114
*/
120-
boolean normalFuses (image_t *target)
115+
boolean verifyFuses (const byte *fuses, const byte *fusemask)
121116
{
122117
SPI.setClockDivider(CLOCKSPEED_FUSES);
123-
124118
byte f;
125-
fp("\nRestoring normal fuses");
126-
127-
f = pgm_read_byte(target->image_normfuses[FUSE_PROT]);
119+
Serial.println("Verifying fuses...");
120+
f = pgm_read_byte(&fuses[FUSE_PROT]);
128121
if (f) {
129-
fp("\n Lock: ");
130-
Serial.print(f, HEX);
131-
fp(" ");
132-
Serial.print(spi_transaction(0xAC, 0xE0, 0x00, f), HEX);
122+
uint8_t readfuse = spi_transaction(0x58, 0x00, 0x00, 0x00); // lock fuse
123+
readfuse &= pgm_read_byte(&fusemask[FUSE_PROT]);
124+
Serial.print("\tLock Fuse: "); Serial.print(f, HEX); Serial.print(" is "); Serial.print(readfuse, HEX);
125+
if (readfuse != f)
126+
return false;
133127
}
134-
f = pgm_read_byte(target->image_normfuses[FUSE_LOW]);
128+
f = pgm_read_byte(&fuses[FUSE_LOW]);
135129
if (f) {
136-
fp(" Low: ");
137-
Serial.print(f, HEX);
138-
fp(" ");
139-
Serial.print(spi_transaction(0xAC, 0xA0, 0x00, f), HEX);
130+
uint8_t readfuse = spi_transaction(0x50, 0x00, 0x00, 0x00); // low fuse
131+
Serial.print("\tLow Fuse: 0x"); Serial.print(f, HEX); Serial.print(" is 0x"); Serial.print(readfuse, HEX);
132+
readfuse &= pgm_read_byte(&fusemask[FUSE_LOW]);
133+
if (readfuse != f)
134+
return false;
140135
}
141-
f = pgm_read_byte(target->image_normfuses[FUSE_HIGH]);
136+
f = pgm_read_byte(&fuses[FUSE_HIGH]);
142137
if (f) {
143-
fp(" High: ");
144-
Serial.print(f, HEX);
145-
fp(" ");
146-
Serial.print(spi_transaction(0xAC, 0xA8, 0x00, f), HEX);
138+
uint8_t readfuse = spi_transaction(0x58, 0x08, 0x00, 0x00); // high fuse
139+
readfuse &= pgm_read_byte(&fusemask[FUSE_HIGH]);
140+
Serial.print("\tHigh Fuse: 0x"); Serial.print(f, HEX); Serial.print(" is 0x"); Serial.print(readfuse, HEX);
141+
if (readfuse != f)
142+
return false;
147143
}
148-
f = pgm_read_byte(target->image_normfuses[FUSE_EXT]);
144+
f = pgm_read_byte(&fuses[FUSE_EXT]);
149145
if (f) {
150-
fp(" Ext: ");
151-
Serial.print(f, HEX);
152-
fp(" ");
153-
Serial.print(spi_transaction(0xAC, 0xA4, 0x00, f), HEX);
146+
uint8_t readfuse = spi_transaction(0x50, 0x08, 0x00, 0x00); // ext fuse
147+
readfuse &= pgm_read_byte(&fusemask[FUSE_EXT]);
148+
Serial.print("\tExt Fuse: 0x"); Serial.print(f, HEX); Serial.print(" is 0x"); Serial.print(readfuse, HEX);
149+
if (readfuse != f)
150+
return false;
154151
}
155152
Serial.println();
156153
return true; /* */
@@ -260,7 +257,7 @@ byte * readImagePage (byte *hextext, uint16_t pageaddr, uint8_t pagesize, byte *
260257
break;
261258
}
262259
#if VERBOSE
263-
fp("\n Total bytes read: ");
260+
Serial.print("\n Total bytes read: ");
264261
Serial.println(page_idx, DEC);
265262
#endif
266263
return hextext;

images.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ image_t PROGMEM image_328 = {
44
{"adaboot_atmega328.hex"},
55
{"atmega328"},
66
0x950F, /* Signature bytes for 328P */
7-
{0x3F,0xFF,0xDA,0x05,0}, // pre program fuses (prot/lock, low, high, ext)
8-
{0x0F,0,0,0,0}, // post program fuses
7+
{0x3F, 0xFF, 0xDA, 0x05}, // pre program fuses (prot/lock, low, high, ext)
8+
{0x0F, 0x0, 0x0, 0x0}, // post program fuses
9+
{0x3F, 0xFF, 0xFF, 0x07}, // fuse mask
910
32768, // size of chip flash in bytes
1011
128, // size in bytes of flash page
1112
{

optiLoader.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ typedef struct image {
2121
uint16_t image_chipsig; /* Low two bytes of signature */
2222
byte image_progfuses[5]; /* fuses to set during programming */
2323
byte image_normfuses[5]; /* fuses to set after programming */
24+
byte fusemask[4];
2425
uint16_t chipsize;
2526
byte image_pagesize; /* page size for flash programming */
2627
byte image_hexcode[5000]; /* intel hex format image (text) */
@@ -33,9 +34,9 @@ typedef struct alias {
3334
} alias_t;
3435

3536
// Useful message printing definitions
36-
#define fp(string) flashprint(PSTR(string));
37+
3738
#define debug(string) // flashprint(PSTR(string));
38-
#define error(string) { flashprint(PSTR(string)); digitalWrite(LED_ERR, HIGH); while(1); }
39+
3940

4041
void pulse (int pin, int times);
4142
void flashprint (const char p[]);
@@ -46,13 +47,14 @@ image_t *findImage (uint16_t signature);
4647

4748

4849
uint16_t readSignature (void);
49-
boolean programmingFuses (image_t *target);
50-
boolean normalFuses (image_t *target);
50+
boolean programFuses (const byte *fuses);
5151
void eraseChip(void);
5252
boolean verifyImage (byte *hextext);
5353
void busyWait(void);
5454
boolean flashPage (byte *pagebuff, uint16_t pageaddr, uint8_t pagesize);
5555
byte hexton (byte h);
5656
byte * readImagePage (byte *hextext, uint16_t pageaddr, uint8_t pagesize, byte *page);
57+
boolean verifyFuses (const byte *fuses, const byte *fusemask);
58+
void error(char *string);
5759

5860
#endif

0 commit comments

Comments
 (0)