diff options
| author | Bluebie <a@creativepony.com> | 2012-10-04 13:59:25 +1000 | 
|---|---|---|
| committer | Bluebie <a@creativepony.com> | 2012-10-04 13:59:25 +1000 | 
| commit | 66b662fc71061e874bef879820112b397f04e746 (patch) | |
| tree | 77f1b9b44964e29064a75936e28126f36b6a6cd8 | |
| parent | 239ed251b8adbeff9225e1fbabf04a73ecd9f1a1 (diff) | |
| download | micronucleus-66b662fc71061e874bef879820112b397f04e746.tar.gz micronucleus-66b662fc71061e874bef879820112b397f04e746.tar.bz2 micronucleus-66b662fc71061e874bef879820112b397f04e746.zip | |
Added low power mode, for chips which need to start with clkdiv8 and only switch to 16.5mhz when usb connection is detected somehow.
| -rw-r--r-- | firmware/bootloaderconfig.h | 16 | ||||
| -rw-r--r-- | firmware/main.c | 31 | 
2 files changed, 44 insertions, 3 deletions
| diff --git a/firmware/bootloaderconfig.h b/firmware/bootloaderconfig.h index 9869b72..b443d6e 100644 --- a/firmware/bootloaderconfig.h +++ b/firmware/bootloaderconfig.h @@ -16,7 +16,6 @@  #define BOOTLOADER_ADDRESS 0  #endif -  /*  General Description:  This file (together with some settings in Makefile) configures the boot loader @@ -207,9 +206,22 @@ these macros are defined, the boot loader uses them.  #define AUTO_EXIT_MS    2500  //#define AUTO_EXIT_CONDITION()   (idlePolls > (AUTO_EXIT_MS * 10UL)) +// uncomment for chips with clkdiv8 enabled in fuses +//#define LOW_POWER_MODE 1 +// restore cpu speed calibration back to 8/16mhz instead of 8.25/16.5mhz +//#define RESTORE_OSCCAL 1 +// set clock prescaler to a value before running user program +//#define SET_CLOCK_PRESCALER _BV(CLKPS0) /* divide by 2 for 8mhz */  #define bootLoaderCondition()   (idlePolls < (AUTO_EXIT_MS * 10UL)) - +#if LOW_POWER_MODE +  // only starts bootloader if USB D- is pulled high on startup - by putting your pullup in to an external connector +  // you can avoid ever entering an out of spec clock speed or waiting on bootloader when that pullup isn't there +  #define bootLoaderStartCondition() \ +    (PINB & (_BV(USB_CFG_DMINUS_BIT) | _BV(USB_CFG_DMINUS_BIT))) == _BV(USB_CFG_DMINUS_BIT) +#else +  #define bootLoaderStartCondition() 1 +#endif  /* ----------------------- Optional MCU Description ------------------------ */ diff --git a/firmware/main.c b/firmware/main.c index 08ec1db..62097b8 100644 --- a/firmware/main.c +++ b/firmware/main.c @@ -375,12 +375,26 @@ static inline void leaveBootloader(void) {  int __attribute__((noreturn)) main(void) {      /* initialize  */ +    #ifdef RESTORE_OSCCAL +        uint8_t osccal_default = OSCCAL; +    #endif +    #if (!SET_CLOCK_PRESCALER) && LOW_POWER_MODE +        uint8_t prescaler_default = CLKPR; +    #endif +          wdt_disable();      /* main app may have enabled watchdog */      tiny85FlashInit();      bootLoaderInit(); -    if (bootLoaderCondition()) { +    if (bootLoaderStartCondition()) { +        #if LOW_POWER_MODE +            // turn off clock prescalling - chip must run at full speed for usb +            // if you might run chip at lower voltages, detect that in bootLoaderStartCondition +            CLKPR = 1 << CLKPCE; +            CLKPR = 0; +        #endif +                  initForUsbConnectivity();          do {              usbPoll(); @@ -404,6 +418,21 @@ int __attribute__((noreturn)) main(void) {          } while(bootLoaderCondition());  /* main event loop runs so long as bootLoaderCondition remains truthy */      } +    // set clock prescaler to desired clock speed (changing from clkdiv8, or no division, depending on fuses) +    #if LOW_POWER_MODE +        #ifdef SET_CLOCK_PRESCALER +            CLKPR = 1 << CLKPCE; +            CLKPR = SET_CLOCK_PRESCALER; +        #else +            CLKPR = 1 << CLKPCE; +            CLKPR = prescaler_default; +        #endif +    #endif +     +    // slowly bring down OSCCAL to it's original value before launching in to user program +    #ifdef RESTORE_OSCCAL +        while (OSCCAL > osccal_default) { OSCCAL -= 1; } +    #endif      leaveBootloader();  } | 
