From 49502d928146f5b0224ce4faef61af9b9ac9ca6e Mon Sep 17 00:00:00 2001 From: Micah Elizabeth Scott <micah@scanlime.org> Date: Mon, 7 Oct 2013 23:55:04 -0700 Subject: [PATCH] Fuck the LPO clock. Watchdog now working as advertised. --- bootloader/README.md | 2 +- bootloader/bootloader.c | 9 ++++++--- bootloader/mk20dx128.c | 41 +++++++++++++++++++++++++---------------- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/bootloader/README.md b/bootloader/README.md index 78a919f..d26124c 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 80b9ed5..f20c4d0 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 d0530e8..be1ad2e 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 -- GitLab