diff --git a/bootloader/README.md b/bootloader/README.md index 78a919f5a594ab17ca82d182992a7c68d85e0984..d26124c5b71ea21b37cdc24aa03f14546d610329 100644 --- a/bootloader/README.md +++ b/bootloader/README.md @@ -17,7 +17,7 @@ This section describes the programming interface that exists between the bootloa The bootloader uses the smallest possible protected region on the MK20DX128's flash, a 4KB block. It uses a tiny amount of RAM for a "token" which is used to force entry into the bootloader on system reset. -When entering the application firmware, the system clocks will already be configured, and the watchdog timer is already enabled with a 10ms timeout, as timed by the system low-power oscillator. The application may disable the watchdog timer if desired. +When entering the application firmware, the system clocks will already be configured, and the watchdog timer is already enabled with a 10ms timeout. The application may disable the watchdog timer if desired. The bootloader normally transfers control to the application early in boot, before setting up the USB controller. It will skip this step and run the DFU implementation if any of the following conditions are true: diff --git a/bootloader/bootloader.c b/bootloader/bootloader.c index 80b9ed590abc4814c26c90f53a672da1c8e02243..f20c4d0cbbe160b39534c8661ba8f2b04e4e2b5a 100644 --- a/bootloader/bootloader.c +++ b/bootloader/bootloader.c @@ -116,8 +116,8 @@ int main() // We're doing DFU mode! led_on(); - dfu_init(); - usb_init(); +// dfu_init(); +// usb_init(); // XXX debug serial_begin(BAUD2DIV(115200)); @@ -125,8 +125,11 @@ int main() serial_phex32(WDOG_RSTCNT); while (1) { + serial_print("foo"); + serial_flush(); + __disable_irq(); - watchdog_refresh(); + //watchdog_refresh(); __enable_irq(); } } diff --git a/bootloader/mk20dx128.c b/bootloader/mk20dx128.c index d0530e87f7631c035c93487db39d1bd0a4d220fd..be1ad2ecded3fcea53e16e89871bcf39264a98c8 100644 --- a/bootloader/mk20dx128.c +++ b/bootloader/mk20dx128.c @@ -194,36 +194,38 @@ void ResetHandler(void) { uint32_t *src = &_etext; uint32_t *dest = &_sdata; + const uint32_t watchdog_timeout = F_BUS / 100; // 10ms - // Enable watchdog timer. Allow settings to be changed later, in case the - // application firmware wants to adjust its settings or disable it. + /* + * Enable watchdog timer. Allow settings to be changed later, in case the + * application firmware wants to adjust its settings or disable it. + * + * Originally I tried using the 1 kHz low-power oscillator here, but that seemed to + * run into an issue where refreshes weren't taking effect. It seems similar to + * this problem on the Freescale forums, which didn't really have a satisfactory + * solution: + * + * https://community.freescale.com/thread/309519 + * + * As a workaround, I'm using the "alternate" system clock. + */ WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; asm volatile ("nop"); + asm volatile ("nop"); WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE | WDOG_STCTRLH_WDOGEN | - WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN; + WDOG_STCTRLH_WAITEN | WDOG_STCTRLH_STOPEN | WDOG_STCTRLH_CLKSRC; WDOG_PRESC = 0; - WDOG_TOVALH = 0; - WDOG_TOVALL = 10; // Milliseconds (1 kHz LPO clock) + WDOG_TOVALH = watchdog_timeout >> 16; + WDOG_TOVALL = watchdog_timeout; // enable clocks to always-used peripherals SIM_SCGC5 = 0x00043F82; // clocks active to all GPIO SIM_SCGC6 = SIM_SCGC6_RTC | SIM_SCGC6_FTM0 | SIM_SCGC6_FTM1 | SIM_SCGC6_ADC0 | SIM_SCGC6_FTFL; - // if the RTC oscillator isn't enabled, get it started early - if (!(RTC_CR & RTC_CR_OSCE)) { - RTC_SR = 0; - RTC_CR = RTC_CR_SC16P | RTC_CR_SC4P | RTC_CR_OSCE; - } // release I/O pins hold, if we woke up from VLLS mode if (PMC_REGSC & PMC_REGSC_ACKISO) PMC_REGSC |= PMC_REGSC_ACKISO; - // TODO: do this while the PLL is waiting to lock.... - while (dest < &_edata) *dest++ = *src++; - dest = &_sbss; - while (dest < &_ebss) *dest++ = 0; - SCB_VTOR = 0; // use vector table in flash - // start in FEI mode // enable capacitors for crystal OSC0_CR = OSC_SC8P | OSC_SC2P; @@ -242,6 +244,13 @@ void ResetHandler(void) MCG_C5 = MCG_C5_PRDIV0(3); // config PLL for 96 MHz output MCG_C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); + + // Copy data segment while we're waiting on the PLL + while (dest < &_edata) *dest++ = *src++; + dest = &_sbss; + while (dest < &_ebss) *dest++ = 0; + SCB_VTOR = 0; // use vector table in flash + // wait for PLL to start using xtal as its input while (!(MCG_S & MCG_S_PLLST)) ; // wait for PLL to lock