Merge pull request #2412 from jfischer-phytec-iot/pr@kinetis-startup
Add common startup.c for Kinetis MCUs.
This commit is contained in:
commit
f6ce0561ed
@ -3,3 +3,9 @@ export INCLUDES += -I$(RIOTCPU)/kinetis_common/include
|
|||||||
|
|
||||||
# Add search path for linker scripts
|
# Add search path for linker scripts
|
||||||
export LINKFLAGS += -L$(RIOTCPU)/kinetis_common/ldscripts
|
export LINKFLAGS += -L$(RIOTCPU)/kinetis_common/ldscripts
|
||||||
|
|
||||||
|
# add the CPU specific startup code for the linker
|
||||||
|
export UNDEF += $(BINDIR)kinetis_common/startup.o
|
||||||
|
|
||||||
|
# add the CPU specific fault handlers for the linker
|
||||||
|
export UNDEF += $(BINDIR)kinetis_common/fault_handlers.o
|
||||||
|
|||||||
60
cpu/kinetis_common/fault_handlers.c
Normal file
60
cpu/kinetis_common/fault_handlers.c
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Freie Universität Berlin
|
||||||
|
* Copyright (C) 2015 PHYTEC Messtechnik GmbH
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||||
|
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||||
|
* details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup cpu_kinetis_common_fhandlers
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Fault Handlers for Freescale Kinetis MCUs
|
||||||
|
*
|
||||||
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||||
|
* @author Johann Fischer <j.fischer@phytec.de>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "crash.h"
|
||||||
|
#include "fault_handlers.h"
|
||||||
|
|
||||||
|
void isr_nmi(void)
|
||||||
|
{
|
||||||
|
core_panic(PANIC_NMI_HANDLER, "NMI HANDLER");
|
||||||
|
}
|
||||||
|
|
||||||
|
void isr_hard_fault(void)
|
||||||
|
{
|
||||||
|
core_panic(PANIC_HARD_FAULT, "HARD FAULT");
|
||||||
|
}
|
||||||
|
|
||||||
|
void isr_mem_manage(void)
|
||||||
|
{
|
||||||
|
core_panic(PANIC_MEM_MANAGE, "MEM MANAGE HANDLER");
|
||||||
|
}
|
||||||
|
|
||||||
|
void isr_bus_fault(void)
|
||||||
|
{
|
||||||
|
core_panic(PANIC_BUS_FAULT, "BUS FAULT");
|
||||||
|
}
|
||||||
|
|
||||||
|
void isr_usage_fault(void)
|
||||||
|
{
|
||||||
|
core_panic(PANIC_USAGE_FAULT, "ISR USAGE FAULT");
|
||||||
|
}
|
||||||
|
|
||||||
|
void isr_debug_mon(void)
|
||||||
|
{
|
||||||
|
core_panic(PANIC_DEBUG_MON, "DEBUG MON HANDLER");
|
||||||
|
}
|
||||||
|
|
||||||
|
void isr_unhandled(void)
|
||||||
|
{
|
||||||
|
core_panic(PANIC_UNHANDLED_ISR, "UNHANDLED ISR");
|
||||||
|
}
|
||||||
85
cpu/kinetis_common/include/fault_handlers.h
Normal file
85
cpu/kinetis_common/include/fault_handlers.h
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Freie Universität Berlin
|
||||||
|
* Copyright (C) 2015 PHYTEC Messtechnik GmbH
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||||
|
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||||
|
* details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup cpu_kinetis_common_fhandlers Kinetis Fault Handlers
|
||||||
|
* @ingroup cpu_kinetis_common
|
||||||
|
* @brief Fault Handlers for Freescale Kinetis MCUs.
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
|
||||||
|
* @file
|
||||||
|
* @brief Interface definition for the Kinetis Fault Handlers.
|
||||||
|
*
|
||||||
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||||
|
* @author Johann Fischer <j.fischer@phytec.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FAULT_HANDLERS_H
|
||||||
|
#define FAULT_HANDLERS_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Non Maskable Interrupt
|
||||||
|
*/
|
||||||
|
void isr_nmi(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HardFault
|
||||||
|
*/
|
||||||
|
void isr_hard_fault(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief MemManage
|
||||||
|
*/
|
||||||
|
void isr_mem_manage(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief BusFault
|
||||||
|
*/
|
||||||
|
void isr_bus_fault(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UsageFault
|
||||||
|
*/
|
||||||
|
void isr_usage_fault(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Debug Interrupt
|
||||||
|
*/
|
||||||
|
void isr_debug_mon(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default handler, called in case no interrupt handler was defined.
|
||||||
|
*/
|
||||||
|
void isr_unhandled(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Definition of different panic modes
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
PANIC_NMI_HANDLER, /**< non maskable interrupt */
|
||||||
|
PANIC_HARD_FAULT, /**< hard fault */
|
||||||
|
PANIC_MEM_MANAGE, /**< memory controller interrupt */
|
||||||
|
PANIC_BUS_FAULT, /**< bus fault */
|
||||||
|
PANIC_USAGE_FAULT, /**< undefined instruction or unaligned access */
|
||||||
|
PANIC_DEBUG_MON, /**< debug interrupt */
|
||||||
|
PANIC_UNHANDLED_ISR, /**< unhandled interrupt */
|
||||||
|
} panic_t;
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* FAULT_HANDLERS_H */
|
||||||
|
/** @} */
|
||||||
57
cpu/kinetis_common/include/wdog.h
Normal file
57
cpu/kinetis_common/include/wdog.h
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 PHYTEC Messtechnik GmbH
|
||||||
|
* Copyright (C) 2015 Eistec AB
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||||
|
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||||
|
* details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup cpu_kinetis_common_wdog Kinetis WDOG
|
||||||
|
* @ingroup cpu_kinetis_common
|
||||||
|
* @brief Driver for Freescale WDOG device.
|
||||||
|
* There are different implementations of the Watchdog devices.
|
||||||
|
* Currently, it is only possible to turn the Watchdog off.
|
||||||
|
* It supports two types: an advanced Watchdog, mostly found
|
||||||
|
* on Kinetis MCUs with Cortex-M4 inside and a simpler
|
||||||
|
* COP Watchdog.
|
||||||
|
*
|
||||||
|
* ### WDOG Configuration Example (for periph_conf.h) ###
|
||||||
|
* The driver attempts to determine the type of the WDOG.
|
||||||
|
* Also you can force the use of advanced WDOG:
|
||||||
|
*
|
||||||
|
* #define KINETIS_WDOG_ADVANCED 1
|
||||||
|
*
|
||||||
|
* Or the use of COP WDOG:
|
||||||
|
*
|
||||||
|
* #define KINETIS_WDOG_ADVANCED 0
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
|
||||||
|
* @file
|
||||||
|
* @brief Interface definition for the Kinetis WDOG driver.
|
||||||
|
*
|
||||||
|
* @author Johann Fischer <j.fischer@phytec.de>
|
||||||
|
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WDOG_H
|
||||||
|
#define WDOG_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable hardware watchdog.
|
||||||
|
*/
|
||||||
|
void wdog_disable(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* WDOG_H */
|
||||||
|
/** @} */
|
||||||
129
cpu/kinetis_common/startup.c
Normal file
129
cpu/kinetis_common/startup.c
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2014 Freie Universität Berlin
|
||||||
|
* Copyright (C) 2015 PHYTEC Messtechnik GmbH
|
||||||
|
* Copyright (C) 2015 Eistec AB
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||||
|
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||||
|
* details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup cpu_kinetis_common
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Startup code for Freescale Kinetis MCUs
|
||||||
|
*
|
||||||
|
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||||
|
* @author Johann Fischer <j.fischer@phytec.de>
|
||||||
|
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "cpu-conf.h"
|
||||||
|
#include "wdog.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Memory markers as defined in the linker script
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
extern uint32_t _sfixed[];
|
||||||
|
extern uint32_t _efixed[];
|
||||||
|
extern uint32_t _etext[];
|
||||||
|
extern uint32_t _srelocate[];
|
||||||
|
extern uint32_t _erelocate[];
|
||||||
|
extern uint32_t _szero[];
|
||||||
|
extern uint32_t _ezero[];
|
||||||
|
extern uint32_t _sstack[];
|
||||||
|
extern uint32_t _ramcode_start[];
|
||||||
|
extern uint32_t _ramcode_end[];
|
||||||
|
extern uint32_t _ramcode_load[];
|
||||||
|
extern uint32_t _vector_ram_start[];
|
||||||
|
extern uint32_t _vector_ram_end[];
|
||||||
|
extern uint32_t _vector_rom[];
|
||||||
|
/** @} */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief functions for initializing the board, std-lib and kernel
|
||||||
|
*/
|
||||||
|
extern void board_init(void);
|
||||||
|
extern void kernel_init(void);
|
||||||
|
extern void __libc_init_array(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief This function is the entry point after a system reset
|
||||||
|
*
|
||||||
|
* After a system reset, the following steps are necessary and carried out:
|
||||||
|
* 0. disable the Watchdog Timer
|
||||||
|
* 1. load data section from flash to ram
|
||||||
|
* 2. overwrite uninitialized data section (BSS) with zeros
|
||||||
|
* 3. initialize the newlib
|
||||||
|
* 4. initialize the board (sync clock, setup std-IO)
|
||||||
|
* 5. initialize and start RIOTs kernel
|
||||||
|
*/
|
||||||
|
void reset_handler(void)
|
||||||
|
{
|
||||||
|
uint32_t *dst;
|
||||||
|
uint32_t *src = _etext;
|
||||||
|
|
||||||
|
/* disable the WDOG */
|
||||||
|
wdog_disable();
|
||||||
|
|
||||||
|
/* load .data section from flash to ram */
|
||||||
|
for (dst = _srelocate; dst < _erelocate;) {
|
||||||
|
*(dst++) = *(src++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* default .bss section to zero */
|
||||||
|
for (dst = _szero; dst < _ezero;) {
|
||||||
|
*(dst++) = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* copy .ramcode from flash to RAM */
|
||||||
|
src = _ramcode_load;
|
||||||
|
for (dst = _ramcode_start; dst < _ramcode_end;) {
|
||||||
|
*(dst++) = *(src++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy ISR vector from flash to RAM.
|
||||||
|
*
|
||||||
|
* To use this CPU feature, define RAMVECT_SIZE=0x400 when building and write
|
||||||
|
* the new vector table address in RAM to SCB->VTOR.
|
||||||
|
*/
|
||||||
|
src = _vector_rom;
|
||||||
|
for (dst = _vector_ram_start; dst < _vector_ram_end;) {
|
||||||
|
*(dst++) = *(src++);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize the board and startup the kernel */
|
||||||
|
board_init();
|
||||||
|
/* initialize std-c library (this should be done after board_init) */
|
||||||
|
__libc_init_array();
|
||||||
|
/* startup the kernel */
|
||||||
|
kernel_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* fcfield table */
|
||||||
|
__attribute__((weak, section(".fcfield")))
|
||||||
|
const uint8_t flash_configuration_field[] = {
|
||||||
|
0xff, /* backdoor comparison key 3., offset: 0x0 */
|
||||||
|
0xff, /* backdoor comparison key 2., offset: 0x1 */
|
||||||
|
0xff, /* backdoor comparison key 1., offset: 0x2 */
|
||||||
|
0xff, /* backdoor comparison key 0., offset: 0x3 */
|
||||||
|
0xff, /* backdoor comparison key 7., offset: 0x4 */
|
||||||
|
0xff, /* backdoor comparison key 6., offset: 0x5 */
|
||||||
|
0xff, /* backdoor comparison key 5., offset: 0x6 */
|
||||||
|
0xff, /* backdoor comparison key 4., offset: 0x7 */
|
||||||
|
0xff, /* non-volatile p-flash protection 1 - low register, offset: 0x8 */
|
||||||
|
0xff, /* non-volatile p-flash protection 1 - high register, offset: 0x9 */
|
||||||
|
0xff, /* non-volatile p-flash protection 0 - low register, offset: 0xa */
|
||||||
|
0xff, /* non-volatile p-flash protection 0 - high register, offset: 0xb */
|
||||||
|
0xfe, /* non-volatile flash security register, offset: 0xc */
|
||||||
|
0xff, /* non-volatile flash option register, offset: 0xd */
|
||||||
|
0xff, /* non-volatile eeram protection register, offset: 0xe */
|
||||||
|
0xff, /* non-volatile d-flash protection register, offset: 0xf */
|
||||||
|
};
|
||||||
75
cpu/kinetis_common/wdog.c
Normal file
75
cpu/kinetis_common/wdog.c
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2015 PHYTEC Messtechnik GmbH
|
||||||
|
* Copyright (C) 2015 Eistec AB
|
||||||
|
*
|
||||||
|
* This file is subject to the terms and conditions of the GNU Lesser General
|
||||||
|
* Public License v2.1. See the file LICENSE in the top level directory for more
|
||||||
|
* details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup cpu_kinetis_common_wdog
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @file
|
||||||
|
* @brief Low-level WDOG driver implementation
|
||||||
|
*
|
||||||
|
* @author Johann Fischer <j.fischer@phytec.de>
|
||||||
|
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "wdog.h"
|
||||||
|
#include "cpu-conf.h"
|
||||||
|
#include "periph_conf.h"
|
||||||
|
|
||||||
|
#ifndef KINETIS_WDOG_ADVANCED
|
||||||
|
/**
|
||||||
|
* Attempts to determine the type of the WDOG,
|
||||||
|
* using the WDOG_STCTRLH_CLKSRC_MASK field.
|
||||||
|
*/
|
||||||
|
#ifdef WDOG_STCTRLH_CLKSRC_MASK
|
||||||
|
#define KINETIS_WDOG_ADVANCED 1
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disable hardware watchdog.
|
||||||
|
*
|
||||||
|
* For advanced WDOG (mostly Kinetis MCUs with Cortex-M4 inside):
|
||||||
|
* The following unlock sequence must be completed within 256 bus cycles or
|
||||||
|
* the watchdog will reset the system. The watchdog is enabled by default at
|
||||||
|
* power on.
|
||||||
|
*
|
||||||
|
* The sequence is:
|
||||||
|
* 1. Write 0xC520 to the unlock register
|
||||||
|
* 2. Write 0xD928 to the unlock register
|
||||||
|
*
|
||||||
|
* Watchdog is now unlocked to allow us to change its settings
|
||||||
|
*
|
||||||
|
* 3. Clear the WDOGEN bit of the WDOG_STCTRLH register to completely disable
|
||||||
|
* the watchdog.
|
||||||
|
*
|
||||||
|
* It is now possible to single step through the code without the watchdog
|
||||||
|
* resetting the system.
|
||||||
|
*
|
||||||
|
* TODO: Only disable watchdog on debug builds.
|
||||||
|
*/
|
||||||
|
void wdog_disable(void)
|
||||||
|
{
|
||||||
|
#if KINETIS_WDOG_ADVANCED
|
||||||
|
/* unlock and disable the WDOG */
|
||||||
|
WDOG->UNLOCK = (uint16_t)0xc520;
|
||||||
|
WDOG->UNLOCK = (uint16_t)0xd928;
|
||||||
|
WDOG->STCTRLH = (uint16_t)(WDOG_STCTRLH_WAITEN_MASK
|
||||||
|
| WDOG_STCTRLH_STOPEN_MASK
|
||||||
|
| WDOG_STCTRLH_ALLOWUPDATE_MASK
|
||||||
|
| WDOG_STCTRLH_CLKSRC_MASK);
|
||||||
|
#else
|
||||||
|
/* disable the COP WDOG */
|
||||||
|
SIM->COPC = (uint32_t)0x00u;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user