diff --git a/optiboot/bootloaders/optiboot/Makefile b/optiboot/bootloaders/optiboot/Makefile index a886411e81..e9bb265345 100644 --- a/optiboot/bootloaders/optiboot/Makefile +++ b/optiboot/bootloaders/optiboot/Makefile @@ -59,7 +59,7 @@ export # defaults MCU_TARGET = atmega168 -LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.version=0x3ffe +LDSECTIONS = -Wl,--section-start=.text=0x3e00 -Wl,--section-start=.osccal=0x3ffd -Wl,--section-start=.version=0x3ffe # Build environments # Start of some ugly makefile-isms to allow optiboot to be built @@ -190,8 +190,19 @@ ifdef SINGLESPEED SS_CMD = -DSINGLESPEED=1 endif +ifdef OSCCAL_EEPROM_ADDR +OSCCAL_CMD = -DOSCCAL_EEPROM_ADDR=$(OSCCAL_EEPROM_ADDR) +dummy = FORCE +endif + +ifdef OSCCAL_PROGMEM +OSCCAL_CMD = -DOSCCAL_PROGMEM +dummy = FORCE +endif + COMMON_OPTIONS = $(BAUD_RATE_CMD) $(LED_START_FLASHES_CMD) $(BIGBOOT_CMD) COMMON_OPTIONS += $(SOFT_UART_CMD) $(LED_DATA_FLASH_CMD) $(LED_CMD) $(SS_CMD) +COMMON_OPTIONS += $(OSCCAL_CMD) #UART is handled separately and only passed for devices with more than one. ifdef UART @@ -240,7 +251,7 @@ virboot8: TARGET = atmega8 virboot8: MCU_TARGET = atmega8 virboot8: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION' '-Dsave_vect_num=EE_RDY_vect_num' virboot8: AVR_FREQ ?= 16000000L -virboot8: LDSECTIONS = -Wl,--section-start=.text=0x1c00 -Wl,--section-start=.version=0x1ffe +virboot8: LDSECTIONS = -Wl,--section-start=.text=0x1c00 -Wl,--section-start=.osccal=0x1ffd -Wl,--section-start=.version=0x1ffe virboot8: $(PROGRAM)_virboot8.hex virboot8: $(PROGRAM)_virboot8.lst @@ -249,7 +260,7 @@ virboot328: TARGET = atmega328 virboot328: MCU_TARGET = atmega328p virboot328: CFLAGS += $(COMMON_OPTIONS) '-DVIRTUAL_BOOT_PARTITION' virboot328: AVR_FREQ ?= 16000000L -virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7d80 -Wl,--section-start=.version=0x7ffe +virboot328: LDSECTIONS = -Wl,--section-start=.text=0x7d80 -Wl,--section-start=.osccal=0x7ffd -Wl,--section-start=.version=0x7ffe virboot328: $(PROGRAM)_virboot328.hex virboot328: $(PROGRAM)_virboot328.lst @@ -297,7 +308,7 @@ atmega328: TARGET = atmega328 atmega328: MCU_TARGET = atmega328p atmega328: CFLAGS += $(COMMON_OPTIONS) atmega328: AVR_FREQ ?= 16000000L -atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.version=0x7ffe +atmega328: LDSECTIONS = -Wl,--section-start=.text=0x7e00 -Wl,--section-start=.osccal=0x7ffd -Wl,--section-start=.version=0x7ffe atmega328: $(PROGRAM)_atmega328.hex atmega328: $(PROGRAM)_atmega328.lst @@ -316,7 +327,7 @@ atmega328_isp: isp atmega1280: MCU_TARGET = atmega1280 atmega1280: CFLAGS += $(COMMON_OPTIONS) -DBIGBOOT $(UART_CMD) atmega1280: AVR_FREQ ?= 16000000L -atmega1280: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.version=0x1fffe +atmega1280: LDSECTIONS = -Wl,--section-start=.text=0x1fc00 -Wl,--section-start=.osccal=0x1fffd -Wl,--section-start=.version=0x1fffe atmega1280: $(PROGRAM)_atmega1280.hex atmega1280: $(PROGRAM)_atmega1280.lst @@ -327,7 +338,7 @@ atmega8: TARGET = atmega8 atmega8: MCU_TARGET = atmega8 atmega8: CFLAGS += $(COMMON_OPTIONS) atmega8: AVR_FREQ ?= 16000000L -atmega8: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.version=0x1ffe -Wl,--gc-sections -Wl,--undefined=optiboot_version +atmega8: LDSECTIONS = -Wl,--section-start=.text=0x1e00 -Wl,--section-start=.osccal=0x1ffd -Wl,--section-start=.version=0x1ffe -Wl,--gc-sections -Wl,--undefined=optiboot_version atmega8: $(PROGRAM)_atmega8.hex atmega8: $(PROGRAM)_atmega8.lst @@ -538,10 +549,10 @@ clean: $(OBJDUMP) -h -S $< > $@ %.hex: %.elf - $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O ihex $< $@ + $(OBJCOPY) -j .text -j .data -j .version -j .osccal --set-section-flags .version=alloc,load --set-section-flags .osccal=alloc,load -O ihex $< $@ %.srec: %.elf - $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O srec $< $@ + $(OBJCOPY) -j .text -j .data -j .version -j .osccal -set-section-flags .version=alloc,load --set-section-flags .osccal=alloc,load -O srec $< $@ %.bin: %.elf - $(OBJCOPY) -j .text -j .data -j .version --set-section-flags .version=alloc,load -O binary $< $@ + $(OBJCOPY) -j .text -j .data -j .version -j .osccal --set-section-flags .version=alloc,load --set-section-flags .osccal=alloc,load -O binary $< $@ diff --git a/optiboot/bootloaders/optiboot/optiboot.c b/optiboot/bootloaders/optiboot/optiboot.c index df807ab13a..fb2beb32c9 100644 --- a/optiboot/bootloaders/optiboot/optiboot.c +++ b/optiboot/bootloaders/optiboot/optiboot.c @@ -128,6 +128,18 @@ /* UART number (0..n) for devices with more than */ /* one hardware uart (644P, 1284P, etc) */ /* */ +/* OSCCAL_EEPROM_ADDR */ +/* On startup, load an oscillator calibration value from */ +/* this address in EEPROM and write it to OSCCAL (unless */ +/* it is 0xff). */ +/* */ +/* OSCCAL_PROGMEM */ +/* On startup, load an oscillator calibration value from */ +/* the top of the flash memory (unless it is 0xff, which */ +/* is the default). This byte is put into its own .osccal */ +/* section, so its address should be set through the */ +/* linker. */ +/* */ /**********************************************************/ /**********************************************************/ @@ -239,6 +251,11 @@ unsigned const int __attribute__((section(".version"))) optiboot_version = 256*(OPTIBOOT_MAJVER + OPTIBOOT_CUSTOMVER) + OPTIBOOT_MINVER; +#if defined(OSCCAL_PROGMEM) +unsigned const char __attribute__((section(".osccal"))) +optiboot_osccal = 0xff; +#endif + #include #include @@ -468,6 +485,19 @@ int main(void) { SP=RAMEND; // This is done by hardware reset #endif +#if defined(OSCCAL_EEPROM_ADDR) + // Load OSCCAL before app start, so the app does not have to + ch = eeprom_read_byte((uint8_t*)OSCCAL_EEPROM_ADDR); + if (ch != 0xff) + OSCCAL = ch; +#endif + +#if defined(OSCCAL_PROGMEM) + // Load OSCCAL before app start, so the app does not have to + ch = pgm_read_byte(&optiboot_osccal); + if (ch != 0xff) + OSCCAL = ch; +#endif /* * modified Adaboot no-wait mod. * Pass the reset reason to app. Also, it appears that an Uno poweron