diff --git a/optiboot/bootloaders/optiboot/Makefile b/optiboot/bootloaders/optiboot/Makefile index 92a53d983..ec3a0918c 100644 --- a/optiboot/bootloaders/optiboot/Makefile +++ b/optiboot/bootloaders/optiboot/Makefile @@ -60,7 +60,7 @@ export # defaults # Set this explicitly in your make rules! # 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 @@ -198,8 +198,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 @@ -248,7 +259,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 @@ -257,7 +268,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 @@ -272,7 +283,6 @@ virboot328_isp: LFUSE ?= FF virboot328_isp: EFUSE ?= 05 virboot328_isp: isp - #--------------------------------------------------------------------------- # "Board-level Platform" targets. # A "Board-level Platform" implies a manufactured platform with a particular @@ -474,10 +484,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 a218d9782..e3378117a 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 @@ -519,6 +536,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