diff options
author | cpldcpu <cpldcpu@gmail.com> | 2013-12-28 23:24:23 +0100 |
---|---|---|
committer | cpldcpu <cpldcpu@gmail.com> | 2013-12-28 23:24:23 +0100 |
commit | e7d1d1347cd6c220af783972a064d782047e2c56 (patch) | |
tree | a4acdfefaf9d8dd829ed59b0f9480b0121587446 | |
parent | 92c012796d2235e264f6cb3f3082e4a86dd74f59 (diff) | |
download | micronucleus-e7d1d1347cd6c220af783972a064d782047e2c56.tar.gz micronucleus-e7d1d1347cd6c220af783972a064d782047e2c56.tar.bz2 micronucleus-e7d1d1347cd6c220af783972a064d782047e2c56.zip |
firmware: code clean up, consolidated wait loops to save 4 bytes
-rw-r--r-- | firmware/bootloaderconfig.h | 4 | ||||
-rw-r--r-- | firmware/main.c | 65 |
2 files changed, 32 insertions, 37 deletions
diff --git a/firmware/bootloaderconfig.h b/firmware/bootloaderconfig.h index 137fb9b..e6c44da 100644 --- a/firmware/bootloaderconfig.h +++ b/firmware/bootloaderconfig.h @@ -142,8 +142,8 @@ these macros are defined, the boot loader uses them. /* * Define Bootloader entry condition * - * If the entry condition is not met, the bootloader will not be activated and the userprogram - * is executed directly after a reset. If no userprogram has been loaded, the bootloader + * If the entry condition is not met, the bootloader will not be activated and the user program + * is executed directly after a reset. If no user program has been loaded, the bootloader * is always active. * * ENTRY_ALWAYS Always activate the bootloader after reset. Requires the least diff --git a/firmware/main.c b/firmware/main.c index 4ceb19e..8394e7e 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -239,7 +239,12 @@ static void initHardware (void) MCUSR=0; WDTCR = 1<<WDCE | 1<<WDE; WDTCR = 1<<WDP2 | 1<<WDP1 | 1<<WDP0; - + + /* initialize */ + #if OSCCAL_RESTORE + osccal_default = OSCCAL; + #endif + usbDeviceDisconnect(); /* do this while interrupts are disabled */ _delay_ms(500); usbDeviceConnect(); @@ -252,7 +257,6 @@ static void initHardware (void) // reset system to a normal state and launch user program static void leaveBootloader(void) __attribute__((__noreturn__)); static inline void leaveBootloader(void) { - _delay_ms(10); // removing delay causes USB errors bootLoaderExit(); cli(); @@ -264,25 +268,24 @@ static inline void leaveBootloader(void) { // clear magic word from bottom of stack before jumping to the app *(uint8_t*)(RAMEND) = 0x00; // A single write is sufficient to invalidate magic word -#if (!OSCCAL_RESTORE) && OSCCAL_16_5MHz - // adjust clock to previous calibration value, so user program always starts with same calibration - // as when it was uploaded originally - unsigned char stored_osc_calibration = pgm_read_byte(BOOTLOADER_ADDRESS - TINYVECTOR_OSCCAL_OFFSET); - if (stored_osc_calibration != 0xFF && stored_osc_calibration != 0x00) { - OSCCAL=stored_osc_calibration; - nop(); - } -#endif + #if OSCCAL_RESTORE + OSCCAL=osccal_default; + nop(); // NOP to avoid CPU hickup during oscillator stabilization + #elif OSCCAL_16_5MHz + // adjust clock to previous calibration value, so user program always starts with same calibration + // as when it was uploaded originally + unsigned char stored_osc_calibration = pgm_read_byte(BOOTLOADER_ADDRESS - TINYVECTOR_OSCCAL_OFFSET); + if (stored_osc_calibration != 0xFF && stored_osc_calibration != 0x00) { + OSCCAL=stored_osc_calibration; + nop(); + } + #endif + // jump to application reset vector at end of flash asm volatile ("rjmp __vectors - 4"); } int main(void) { - - /* initialize */ - #if OSCCAL_RESTORE - osccal_default = OSCCAL; - #endif bootLoaderInit(); @@ -301,34 +304,26 @@ int main(void) { clearEvents(); usbPoll(); - - - // these next two freeze the chip for ~ 4.5ms, breaking usb protocol - // and usually both of these will activate in the same loop, so host - // needs to wait > 9ms before next usb request - if (isEvent(EVENT_ERASE_APPLICATION)) eraseApplication(); - if (isEvent(EVENT_WRITE_PAGE)) { - _delay_us(2000); // Wait for USB traffic to finish before halting CPU with write- - writeFlashPage(); - } - - LED_MACRO( ((uint8_t*)&idlePolls)[1] ); + idlePolls++; // Try to execute program if bootloader exit condition is met if (AUTO_EXIT_MS&&(idlePolls>AUTO_EXIT_MS*10L)) fireEvent(EVENT_EXECUTE); + LED_MACRO( ((uint8_t*)&idlePolls)[1] ); + + // Wait for USB traffic to finish before a blocking event is executed + // All events will render the MCU unresponsive to USB traffic for a while. + if (events) _delay_ms(2); + if (isEvent(EVENT_ERASE_APPLICATION)) eraseApplication(); + if (isEvent(EVENT_WRITE_PAGE)) writeFlashPage(); + /* main event loop runs as long as no problem is uploaded or existing program is not executed */ } while((!isEvent(EVENT_EXECUTE))||(pgm_read_byte(BOOTLOADER_ADDRESS - TINYVECTOR_RESET_OFFSET + 1)==0xff)); + + LED_EXIT(); } - LED_EXIT(); - - #if OSCCAL_RESTORE - OSCCAL=osccal_default; - nop(); // NOP to avoid CPU hickup during oscillator stabilization - #endif - leaveBootloader(); } /* ------------------------------------------------------------------------ */ |