Skip to content

Commit f959062

Browse files
committed
Added support for chips with bootloader bits in extFuse
1 parent 78b8e92 commit f959062

File tree

3 files changed

+46
-12
lines changed

3 files changed

+46
-12
lines changed

firmware-programmer/helper.cpp

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -352,21 +352,23 @@ byte flashFile(SdFile* file, programmer::BBProgrammer* bbprogrammer)
352352
}
353353
else
354354
{
355-
// Change bootloader fuse
356-
if (signature->fuseWithBootloaderSize != highFuse)
355+
// Change bootloader fuse in correct fuse byte
356+
if (signature->fuseWithBootloaderSize != highFuse &&
357+
signature->fuseWithBootloaderSize != extFuse)
357358
{
358359
// Bootloader setting not supported for current chip
359360
bbprogrammer->stopProgramming();
360361
return error_bootloaderSupport;
361362
}
362363

363-
// Bootloader fuse:
364+
// Bootloader fuse bits appear to be the same on all AVR chips:
364365
// http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-7810-Automotive-Microcontrollers-ATmega328P_Datasheet.pdf page 243 and 239
365366
byte newBootloaderFuse = 0x0;
367+
byte oldBootloaderFuse = fuse.get(signature->fuseWithBootloaderSize);
366368
if (lowestBootLoader == signature->flashSize)
367369
{
368370
Debugln(DEBUG_INFO, F("No bootlaoder detected."));
369-
newBootloaderFuse = (fuse.high & 0b11111000) | 0b001; // Application reset at 0x0000
371+
newBootloaderFuse = (oldBootloaderFuse & 0b11111000) | 0b001; // Application reset at 0x0000
370372
}
371373
else
372374
{
@@ -375,27 +377,37 @@ byte flashFile(SdFile* file, programmer::BBProgrammer* bbprogrammer)
375377

376378
// bootloader fuse depending on bootloader location
377379
if (lowestBootLoader == (signature->flashSize - signature->baseBootSize))
378-
newBootloaderFuse = (fuse.high & 0b11111000) | 0b110;
380+
newBootloaderFuse = (oldBootloaderFuse & 0b11111000) | 0b110;
379381
else if (lowestBootLoader == (signature->flashSize - signature->baseBootSize * 2))
380-
newBootloaderFuse = (fuse.high & 0b11111000) | 0b100;
382+
newBootloaderFuse = (oldBootloaderFuse & 0b11111000) | 0b100;
381383
else if (lowestBootLoader == (signature->flashSize - signature->baseBootSize * 4))
382-
newBootloaderFuse = (fuse.high & 0b11111000) | 0b010;
384+
newBootloaderFuse = (oldBootloaderFuse & 0b11111000) | 0b010;
383385
else if (lowestBootLoader == (signature->flashSize - signature->baseBootSize * 8))
384-
newBootloaderFuse = (fuse.high & 0b11111000) | 0b000;
386+
newBootloaderFuse = (oldBootloaderFuse & 0b11111000) | 0b000;
385387
}
386-
Debug(DEBUG_INFO, F("Changing high fuse: "));
387-
Debug(DEBUG_INFO, fuse.high, BIN);
388+
389+
// Can only be highFuse or extFuse due to earlier checks.
390+
if (signature->fuseWithBootloaderSize == highFuse)
391+
Debug(DEBUG_INFO, F("Changing bootloader bits (high fuse): "));
392+
if (signature->fuseWithBootloaderSize == extFuse)
393+
Debug(DEBUG_INFO, F("Changing bootloader bits (ext fuse): "));
394+
Debug(DEBUG_INFO, oldBootloaderFuse, BIN);
388395
Debug(DEBUG_INFO, F(" -> "));
389396
Debug(DEBUG_INFO, newBootloaderFuse, BIN);
390397
Debug(DEBUG_INFO, F("..."));
391398

392399
// Write new fuse
393-
bbprogrammer->setHighFuse(newBootloaderFuse);
400+
if (signature->fuseWithBootloaderSize == highFuse)
401+
bbprogrammer->setHighFuse(newBootloaderFuse);
402+
if (signature->fuseWithBootloaderSize == extFuse)
403+
bbprogrammer->setExtFuse(newBootloaderFuse);
394404
Debugln(DEBUG_INFO, F(" [OK]"));
395405
}
396406

397407
// Change low fuse for external clock
398-
Debug(DEBUG_INFO, F("Changing low fuse: "));
408+
// This should be same position in low fuse for all AVR chips?
409+
// Please report if this is incorrect!
410+
Debug(DEBUG_INFO, F("Changing low fuse for external 16Mhz clock: "));
399411
Debug(DEBUG_INFO, fuse.low, BIN);
400412
Debug(DEBUG_INFO, F(" -> "));
401413
Debug(DEBUG_INFO, 0xff, BIN);

firmware-programmer/src/programmer/bbprogrammer.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@
22

33
namespace programmer
44
{
5+
byte BBProgrammer::Fuse::get(byte fuse) const
6+
{
7+
switch (fuse)
8+
{
9+
case lowFuse:
10+
return this->low;
11+
case highFuse:
12+
return this->high;
13+
case extFuse:
14+
return this->extended;
15+
case lockFuse:
16+
return this->lock;
17+
case calibrationFuse:
18+
return this->calibration;
19+
default:
20+
HaltError(F("Invalid fuse requested at Fuse::get()!"));
21+
}
22+
}
23+
524
BBProgrammer::BBProgrammer(byte p_sck, byte p_mosi, byte p_miso, byte p_reset)
625
{
726
// Setup software SPI

firmware-programmer/src/programmer/bbprogrammer.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ namespace programmer
6565
byte extended;
6666
byte lock;
6767
byte calibration;
68+
69+
// Get fuse by signature.h fuse enum
70+
byte get(byte fuse) const;
6871
} Fuse;
6972

7073
private:

0 commit comments

Comments
 (0)