From 2c7542e2e7f0b8a99edf563dc53164fe1a439483 Mon Sep 17 00:00:00 2001 From: Jacob Alexander Date: Sat, 10 Jan 2015 19:53:46 -0800 Subject: [PATCH] Fixing device bricking bug - When loading a garbage image onto the device, the chip hangs and refuses to jump to the bootloader and start dfu Fix - Check if chip was in locked state and jump to dfu - Check if watchdog timer fired and jump to dfu --- Bootloader/CMakeLists.txt | 19 +++++++++++++++++-- Bootloader/flash.c | 1 - Lib/mk20dx.c | 36 +++++++++++++++++++++--------------- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/Bootloader/CMakeLists.txt b/Bootloader/CMakeLists.txt index ebe5ff4..704115d 100644 --- a/Bootloader/CMakeLists.txt +++ b/Bootloader/CMakeLists.txt @@ -20,11 +20,26 @@ #| You _MUST_ clean the build directory if you change this value #| set( CHIP - "mk20dx128vlf5" # McHCK mk20dx128vlf5 -# "mk20dx256vlh7" # Kiibohd-dfu + "mk20dx128vlf5" # McHCK mk20dx128vlf5 +# "mk20dx256vlh7" # Kiibohd-dfu mk20dx256vlh7 ) + +### +# Compiler Selection +# + +#| *** EXPERIMENTAL *** +#| Stick with gcc unless you know what you're doing +#| Currently only arm is supported with clang +set( COMPILER + "gcc" # arm-none-eabi-gcc / avr-gcc - Default +# "clang" # arm-none-eabi + CACHE STRING "Compiler Type" ) + + + ### # Bootloader Configuration # diff --git a/Bootloader/flash.c b/Bootloader/flash.c index 9ae6dae..db2ef8f 100644 --- a/Bootloader/flash.c +++ b/Bootloader/flash.c @@ -68,7 +68,6 @@ int flash_erase_sector(uintptr_t addr) int flash_program_section(uintptr_t addr, size_t num_words) { - GPIOA_PSOR |= (1<<19); FTFL.fccob.program_section.fcmd = FTFL_FCMD_PROGRAM_SECTION; FTFL.fccob.program_section.addr = addr; FTFL.fccob.program_section.num_words = num_words; diff --git a/Lib/mk20dx.c b/Lib/mk20dx.c index 9b31949..d7a8cde 100644 --- a/Lib/mk20dx.c +++ b/Lib/mk20dx.c @@ -1,7 +1,7 @@ /* Teensyduino Core Library * http://www.pjrc.com/teensy/ * Copyright (c) 2013 PJRC.COM, LLC. - * Modifications by Jacob Alexander 2014 + * Modifications by Jacob Alexander 2014-2015 * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -29,6 +29,8 @@ * SOFTWARE. */ +// ----- Includes ----- + // Local Includes #include "mk20dx.h" @@ -246,7 +248,7 @@ void (* const gVectors[])() = portd_isr, // 59 Pin detect (Port D) porte_isr, // 60 Pin detect (Port E) software_isr, // 61 Software interrupt -#elif defined(_mk20dx256_) +#elif defined(_mk20dx256_) || defined(_mk20dx256vlh7_) dma_ch0_isr, // 16 DMA channel 0 transfer complete dma_ch1_isr, // 17 DMA channel 1 transfer complete dma_ch2_isr, // 18 DMA channel 2 transfer complete @@ -404,7 +406,7 @@ const uint8_t flashconfigbytes[16] = { // ----- Functions ----- -#if defined(_mk20dx128vlf5_) && defined(_bootloader_) // Bootloader Section +#if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section __attribute__((noreturn)) static inline void jump_to_app( uintptr_t addr ) { @@ -453,18 +455,20 @@ void *memcpy( void *dst, const void *src, unsigned int len ) __attribute__ ((section(".startup"))) void ResetHandler() { - // Disable Watchdog - WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; - WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; - WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE; - -#if defined(_mk20dx128vlf5_) && defined(_bootloader_) // Bootloader Section +#if ( defined(_mk20dx128vlf5_) || defined(_mk20dx256vlh7_) ) && defined(_bootloader_) // Bootloader Section extern uint32_t _app_rom; // We treat _app_rom as pointer to directly read the stack // pointer and check for valid app code. This is no fool // proof method, but it should help for the first flash. - if ( RCM_SRS0 & 0x40 || _app_rom == 0xffffffff || + // + // Purposefully disabling the watchdog *after* the reset check this way + // if the chip goes into an odd state we'll reset to the bootloader (invalid firmware image) + // RCM_SRS0 & 0x20 + // + // Also checking for ARM lock-up signal (invalid firmware image) + // RCM_SRS1 & 0x02 + if ( RCM_SRS0 & 0x40 || RCM_SRS0 & 0x20 || RCM_SRS1 & 0x02 || _app_rom == 0xffffffff || memcmp( (uint8_t*)&VBAT, sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic) ) == 0 ) // Check for soft reload { memset( (uint8_t*)&VBAT, 0, sizeof(VBAT) ); @@ -476,6 +480,10 @@ void ResetHandler() jump_to_app( addr ); } #endif + // Disable Watchdog + WDOG_UNLOCK = WDOG_UNLOCK_SEQ1; + WDOG_UNLOCK = WDOG_UNLOCK_SEQ2; + WDOG_STCTRLH = WDOG_STCTRLH_ALLOWUPDATE; uint32_t *src = (uint32_t*)&_etext; uint32_t *dest = (uint32_t*)&_sdata; @@ -510,7 +518,7 @@ void ResetHandler() dest = (uint32_t*)&_sbss; while ( dest < (uint32_t*)&_ebss ) *dest++ = 0; -// MCHCK +// MCHCK / Kiibohd-dfu #if defined(_mk20dx128vlf5_) // Default all interrupts to medium priority level for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ ) @@ -524,14 +532,12 @@ void ResetHandler() // USB Clock and FLL select SIM_SOPT2 = SIM_SOPT2_USBSRC | SIM_SOPT2_TRACECLKSEL; -// Teensy 3.0 and 3.1 +// Teensy 3.0 and 3.1 and Kiibohd-dfu (mk20dx256vlh7) #else - unsigned int i; - SCB_VTOR = 0; // use vector table in flash // default all interrupts to medium priority level - for ( i = 0; i < NVIC_NUM_INTERRUPTS; i++ ) + for ( unsigned int i = 0; i < NVIC_NUM_INTERRUPTS; i++ ) { NVIC_SET_PRIORITY( i, 128 ); } -- 2.39.2