Skip to content
Browse files

cleaned up fuse management, added fuse mask bits, and added success/e…

…rror beeping
  • Loading branch information...
1 parent 54c2aee commit f8264cd9fb2b08779d8669774236b8f706053b9d @ladyada ladyada committed Sep 5, 2011
Showing with 91 additions and 69 deletions.
  1. +31 −9 adaLoader.pde
  2. +51 −54 code.cpp
  3. +3 −2 images.cpp
  4. +6 −4 optiLoader.h
View
40 adaLoader.pde
@@ -60,12 +60,14 @@ byte pageBuffer[128]; /* One page of flash */
#define CLOCK 9 // self-generate 8mhz clock - handy!
#define BUTTON A1
-
+#define PIEZOPIN 2
void setup () {
Serial.begin(9600); /* Initialize serial for status msgs */
Serial.println("\nAdaBootLoader Bootstrap programmer (originally OptiLoader Bill Westfield (WestfW))");
+ pinMode(PIEZOPIN, OUTPUT);
+ pinMode(PIEZOPIN2, OUTPUT);
pinMode(LED_PROGMODE, OUTPUT);
pulse(LED_PROGMODE,2);
@@ -103,11 +105,15 @@ void loop (void) {
if (! (targetimage = findImage(signature))) // look for an image
error("Image fail");
- if (! programmingFuses(targetimage)) // get fuses ready to program
- error("Programming Fuses fail");
-
eraseChip();
+ if (! programFuses(targetimage->image_progfuses)) // get fuses ready to program
+ error("Programming Fuses fail");
+
+ if (! verifyFuses(targetimage->image_progfuses, targetimage->fusemask) ) {
+ error("Failed to verify fuses");
+ }
+
byte *hextext = targetimage->image_hexcode;
uint16_t pageaddr = 0;
uint8_t pagesize = pgm_read_byte(&targetimage->image_pagesize);
@@ -129,21 +135,37 @@ void loop (void) {
pageaddr += pagesize;
}
- //normalFuses(targetimage); // reset fuses to normal mode
+ // Set fuses to 'final' state
+ if (! programFuses(targetimage->image_normfuses))
+ error("Programming Fuses fail");
+
end_pmode();
start_pmode();
- Serial.println("\nVerifing chip flash");
+ Serial.println("\nVerifing flash...");
if (! verifyImage(targetimage->image_hexcode) ) {
error("Failed to verify chip");
} else {
- Serial.println("Chip flash verified correctly!");
+ Serial.println("\tFlash verified correctly!");
}
+ if (! verifyFuses(targetimage->image_normfuses, targetimage->fusemask) ) {
+ error("Failed to verify fuses");
+ } else {
+ Serial.println("Fuses verified correctly!");
+ }
target_poweroff(); /* turn power off */
+ tone(PIEZOPIN, 4000, 200);
}
+void error(char *string) {
+ Serial.println(string);
+ digitalWrite(LED_ERR, HIGH);
+ while(1) {
+ tone(PIEZOPIN, 4000, 500);
+ }
+}
void start_pmode () {
pinMode(13, INPUT); // restore to default
@@ -193,9 +215,9 @@ boolean target_poweron ()
digitalWrite(RESET, LOW); // reset it right away.
pinMode(RESET, OUTPUT);
delay(200);
- fp("Starting Program Mode");
+ Serial.print("Starting Program Mode");
start_pmode();
- fp(" [OK]\n");
+ Serial.println(" [OK]");
return true;
}
View
105 code.cpp
@@ -21,7 +21,7 @@ uint16_t readSignature (void)
SPI.setClockDivider(CLOCKSPEED_FUSES);
uint16_t target_type = 0;
- fp("\nReading signature:");
+ Serial.print("\nReading signature:");
target_type = spi_transaction(0x30, 0x00, 0x01, 0x00);
target_type <<= 8;
@@ -30,7 +30,7 @@ uint16_t readSignature (void)
Serial.println(target_type, HEX);
if (target_type == 0 || target_type == 0xFFFF) {
if (target_type == 0) {
- fp(" (no target attached?)\n");
+ Serial.println(" (no target attached?)");
}
}
return target_type;
@@ -46,111 +46,108 @@ uint16_t readSignature (void)
image_t *findImage (uint16_t signature)
{
image_t *ip;
- fp("Searching for image...\n");
+ Serial.println("Searching for image...");
for (byte i=0; i < NUMIMAGES; i++) {
ip = images[i];
if (ip && (pgm_read_word(&ip->image_chipsig) == signature)) {
- fp(" Found \"");
+ Serial.print(" Found \"");
flashprint(&ip->image_name[0]);
- fp("\" for ");
+ Serial.print("\" for ");
flashprint(&ip->image_chipname[0]);
- fp("\n");
+ Serial.println();
return ip;
}
}
- fp(" Not Found\n");
+ Serial.println(" Not Found");
return 0;
}
/*
* programmingFuses
- * reprogram the fuses to the state we want during chip programming.
- * This is not necessarily the same as the
- * 'final' fuses due to changes in clock speed, lock byte, etc
+ * Program the fuse/lock bits
*/
-boolean programmingFuses (image_t *target)
+boolean programFuses (const byte *fuses)
{
SPI.setClockDivider(CLOCKSPEED_FUSES);
byte f;
- fp("\nSetting fuses for programming");
+ Serial.print("\nSetting fuses");
- f = pgm_read_byte(target->image_progfuses[FUSE_PROT]);
+ f = pgm_read_byte(&fuses[FUSE_PROT]);
if (f) {
- fp("\n Lock: ");
+ Serial.print("\n Set Lock Fuse to: ");
Serial.print(f, HEX);
- fp(" ");
+ Serial.print(" -> ");
Serial.print(spi_transaction(0xAC, 0xE0, 0x00, f), HEX);
}
- f = pgm_read_byte(target->image_progfuses[FUSE_LOW]);
+ f = pgm_read_byte(&fuses[FUSE_LOW]);
if (f) {
- fp(" Low: ");
+ Serial.print(" Set Low Fuse to: ");
Serial.print(f, HEX);
- fp(" ");
+ Serial.print(" -> ");
Serial.print(spi_transaction(0xAC, 0xA0, 0x00, f), HEX);
}
- f = pgm_read_byte(target->image_progfuses[FUSE_HIGH]);
+ f = pgm_read_byte(&fuses[FUSE_HIGH]);
if (f) {
- fp(" High: ");
+ Serial.print(" Set High Fuse to: ");
Serial.print(f, HEX);
- fp(" ");
+ Serial.print(" -> ");
Serial.print(spi_transaction(0xAC, 0xA8, 0x00, f), HEX);
}
- f = pgm_read_byte(target->image_progfuses[FUSE_EXT]);
+ f = pgm_read_byte(&fuses[FUSE_EXT]);
if (f) {
- fp(" Ext: ");
+ Serial.print(" Set Ext Fuse to: ");
Serial.print(f, HEX);
- fp(" ");
+ Serial.print(" -> ");
Serial.print(spi_transaction(0xAC, 0xA4, 0x00, f), HEX);
}
Serial.println();
return true; /* */
}
-
/*
- * normalFuses
- * reprogram the fuses to the state we want after the chip has
- * been programmed - this is not necessarily the same as the
- * 'programming' fuses due to changes in clock speed, lock byte, etc
+ * verifyFuses
+ * Verifies a fuse set
*/
-boolean normalFuses (image_t *target)
+boolean verifyFuses (const byte *fuses, const byte *fusemask)
{
SPI.setClockDivider(CLOCKSPEED_FUSES);
-
byte f;
- fp("\nRestoring normal fuses");
-
- f = pgm_read_byte(target->image_normfuses[FUSE_PROT]);
+ Serial.println("Verifying fuses...");
+ f = pgm_read_byte(&fuses[FUSE_PROT]);
if (f) {
- fp("\n Lock: ");
- Serial.print(f, HEX);
- fp(" ");
- Serial.print(spi_transaction(0xAC, 0xE0, 0x00, f), HEX);
+ uint8_t readfuse = spi_transaction(0x58, 0x00, 0x00, 0x00); // lock fuse
+ readfuse &= pgm_read_byte(&fusemask[FUSE_PROT]);
+ Serial.print("\tLock Fuse: "); Serial.print(f, HEX); Serial.print(" is "); Serial.print(readfuse, HEX);
+ if (readfuse != f)
+ return false;
}
- f = pgm_read_byte(target->image_normfuses[FUSE_LOW]);
+ f = pgm_read_byte(&fuses[FUSE_LOW]);
if (f) {
- fp(" Low: ");
- Serial.print(f, HEX);
- fp(" ");
- Serial.print(spi_transaction(0xAC, 0xA0, 0x00, f), HEX);
+ uint8_t readfuse = spi_transaction(0x50, 0x00, 0x00, 0x00); // low fuse
+ Serial.print("\tLow Fuse: 0x"); Serial.print(f, HEX); Serial.print(" is 0x"); Serial.print(readfuse, HEX);
+ readfuse &= pgm_read_byte(&fusemask[FUSE_LOW]);
+ if (readfuse != f)
+ return false;
}
- f = pgm_read_byte(target->image_normfuses[FUSE_HIGH]);
+ f = pgm_read_byte(&fuses[FUSE_HIGH]);
if (f) {
- fp(" High: ");
- Serial.print(f, HEX);
- fp(" ");
- Serial.print(spi_transaction(0xAC, 0xA8, 0x00, f), HEX);
+ uint8_t readfuse = spi_transaction(0x58, 0x08, 0x00, 0x00); // high fuse
+ readfuse &= pgm_read_byte(&fusemask[FUSE_HIGH]);
+ Serial.print("\tHigh Fuse: 0x"); Serial.print(f, HEX); Serial.print(" is 0x"); Serial.print(readfuse, HEX);
+ if (readfuse != f)
+ return false;
}
- f = pgm_read_byte(target->image_normfuses[FUSE_EXT]);
+ f = pgm_read_byte(&fuses[FUSE_EXT]);
if (f) {
- fp(" Ext: ");
- Serial.print(f, HEX);
- fp(" ");
- Serial.print(spi_transaction(0xAC, 0xA4, 0x00, f), HEX);
+ uint8_t readfuse = spi_transaction(0x50, 0x08, 0x00, 0x00); // ext fuse
+ readfuse &= pgm_read_byte(&fusemask[FUSE_EXT]);
+ Serial.print("\tExt Fuse: 0x"); Serial.print(f, HEX); Serial.print(" is 0x"); Serial.print(readfuse, HEX);
+ if (readfuse != f)
+ return false;
}
Serial.println();
return true; /* */
@@ -260,7 +257,7 @@ byte * readImagePage (byte *hextext, uint16_t pageaddr, uint8_t pagesize, byte *
break;
}
#if VERBOSE
- fp("\n Total bytes read: ");
+ Serial.print("\n Total bytes read: ");
Serial.println(page_idx, DEC);
#endif
return hextext;
View
5 images.cpp
@@ -4,8 +4,9 @@ image_t PROGMEM image_328 = {
{"adaboot_atmega328.hex"},
{"atmega328"},
0x950F, /* Signature bytes for 328P */
- {0x3F,0xFF,0xDA,0x05,0}, // pre program fuses (prot/lock, low, high, ext)
- {0x0F,0,0,0,0}, // post program fuses
+ {0x3F, 0xFF, 0xDA, 0x05}, // pre program fuses (prot/lock, low, high, ext)
+ {0x0F, 0x0, 0x0, 0x0}, // post program fuses
+ {0x3F, 0xFF, 0xFF, 0x07}, // fuse mask
32768, // size of chip flash in bytes
128, // size in bytes of flash page
{
View
10 optiLoader.h
@@ -21,6 +21,7 @@ typedef struct image {
uint16_t image_chipsig; /* Low two bytes of signature */
byte image_progfuses[5]; /* fuses to set during programming */
byte image_normfuses[5]; /* fuses to set after programming */
+ byte fusemask[4];
uint16_t chipsize;
byte image_pagesize; /* page size for flash programming */
byte image_hexcode[5000]; /* intel hex format image (text) */
@@ -33,9 +34,9 @@ typedef struct alias {
} alias_t;
// Useful message printing definitions
-#define fp(string) flashprint(PSTR(string));
+
#define debug(string) // flashprint(PSTR(string));
-#define error(string) { flashprint(PSTR(string)); digitalWrite(LED_ERR, HIGH); while(1); }
+
void pulse (int pin, int times);
void flashprint (const char p[]);
@@ -46,13 +47,14 @@ image_t *findImage (uint16_t signature);
uint16_t readSignature (void);
-boolean programmingFuses (image_t *target);
-boolean normalFuses (image_t *target);
+boolean programFuses (const byte *fuses);
void eraseChip(void);
boolean verifyImage (byte *hextext);
void busyWait(void);
boolean flashPage (byte *pagebuff, uint16_t pageaddr, uint8_t pagesize);
byte hexton (byte h);
byte * readImagePage (byte *hextext, uint16_t pageaddr, uint8_t pagesize, byte *page);
+boolean verifyFuses (const byte *fuses, const byte *fusemask);
+void error(char *string);
#endif

0 comments on commit f8264cd

Please sign in to comment.
Something went wrong with that request. Please try again.