k60: Initial commit of K60 CPU.
Tested on the following Freescale Kinetis K60 CPUs: - MK60DN512VLL10 The port should with a high probability also support the following variations of the above CPUs (untested): - MK60DN256VLL10 And possibly also: - MK60DX256VLL10 - MK60DX512VLL10 - MK60DN512VLQ10 - MK60DN256VLQ10 - MK60DX256VLQ10 - MK60DN512VMC10 - MK60DN256VMC10 - MK60DX256VMC10 - MK60DN512VMD10 - MK60DX256VMD10 - MK60DN256VMD10 Currently not working on the following CPUs (Missing PIT channel chaining necessary for kinetis_common/periph/timer implementation): - MK60DN256ZVLL10 - MK60DN512ZVLL10 - MK60DX256ZVLL10 - MK60DX512ZVLL10 - MK60DN512ZVLQ10 - MK60DN256ZVLQ10 - MK60DX256ZVLQ10 - MK60DN512ZVMC10 - MK60DN256ZVMC10 - MK60DX256ZVMC10 - MK60DN512ZVMD10 - MK60DX256ZVMD10 - MK60DN256ZVMD10 Regarding header files from Freescale: dist/tools/licenses: Add Freescale CMSIS PAL license pattern Redistribution is OK according to: https://community.freescale.com/message/477976?et=watches.email.thread#477976 Archive copy in case the above link disappears: https://web.archive.org/web/20150328073057/https://community.freescale.com/message/477976?et=watches.email.thread Applies to: - MK60DZ10.h (K60 variant)dev/timer
parent
6e948ddde7
commit
de486ff79f
@ -0,0 +1,7 @@
|
||||
# define the module that is build
|
||||
MODULE = cpu
|
||||
|
||||
# add a list of subdirectories, that should also be build
|
||||
DIRS = periph $(CORTEX_M4_COMMON) devio $(KINETIS_COMMON)
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -0,0 +1,42 @@
|
||||
# this CPU implementation is using the explicit core/CPU interface
|
||||
export CFLAGS += -DCOREIF_NG=1
|
||||
|
||||
# export the peripheral drivers to be linked into the final binary
|
||||
export USEMODULE += periph
|
||||
|
||||
# Posix device I/O interface
|
||||
export USEMODULE += devio
|
||||
|
||||
# tell the build system that the CPU depends on the Cortex-M common files
|
||||
export USEMODULE += cortex-m4_common
|
||||
|
||||
# tell the build system that the CPU depends on the Kinetis common files
|
||||
export USEMODULE += kinetis_common
|
||||
|
||||
# define path to cortex-m common module, which is needed for this CPU
|
||||
export CORTEX_M4_COMMON = $(RIOTCPU)/cortex-m4_common/
|
||||
|
||||
# define path to kinetis module, which is needed for this CPU
|
||||
export KINETIS_COMMON = $(RIOTCPU)/kinetis_common/
|
||||
|
||||
# CPU depends on the cortex-m common module, so include it
|
||||
include $(CORTEX_M4_COMMON)Makefile.include
|
||||
|
||||
# CPU depends on the kinetis module, so include it
|
||||
include $(KINETIS_COMMON)Makefile.include
|
||||
|
||||
# define the linker script to use for this CPU
|
||||
export LINKFLAGS += -L$(RIOTCPU)/$(CPU)/ldscripts
|
||||
export LINKERSCRIPT = $(CPU_MODEL).ld
|
||||
|
||||
#export the CPU model
|
||||
MODEL = $(shell echo $(CPU_MODEL)|tr 'a-z' 'A-Z')
|
||||
export CFLAGS += -DCPU_MODEL_$(MODEL)
|
||||
|
||||
# include CPU specific includes
|
||||
export INCLUDES += -I$(RIOTCPU)/$(CPU)/include
|
||||
|
||||
# add the CPU specific system calls implementations for the linker
|
||||
export UNDEF += $(BINDIR)cpu/syscalls.o
|
||||
export UNDEF += $(BINDIR)cpu/ssp.o
|
||||
export UNDEF += $(BINDIR)cpu/interrupt_vector.o
|
@ -0,0 +1,248 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include "cpu.h"
|
||||
#include "board.h"
|
||||
|
||||
/**
|
||||
* @ingroup cpu_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation of K60 CPU initialization.
|
||||
*
|
||||
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||
*/
|
||||
|
||||
extern void *_vector_rom[];
|
||||
|
||||
/** @brief Current core clock frequency */
|
||||
uint32_t SystemCoreClock = DEFAULT_SYSTEM_CLOCK;
|
||||
/** @brief Current system clock frequency */
|
||||
uint32_t SystemSysClock = DEFAULT_SYSTEM_CLOCK;
|
||||
/** @brief Current bus clock frequency */
|
||||
uint32_t SystemBusClock = DEFAULT_SYSTEM_CLOCK;
|
||||
/** @brief Current FlexBus clock frequency */
|
||||
uint32_t SystemFlexBusClock = DEFAULT_SYSTEM_CLOCK;
|
||||
/** @brief Current flash clock frequency */
|
||||
uint32_t SystemFlashClock = DEFAULT_SYSTEM_CLOCK;
|
||||
/** @brief Number of full PIT ticks in one microsecond. */
|
||||
uint32_t PIT_ticks_per_usec = (DEFAULT_SYSTEM_CLOCK / 1000000ul);
|
||||
|
||||
/**
|
||||
* @brief Check the running CPU identification to find if we are running on the
|
||||
* wrong hardware.
|
||||
*/
|
||||
static void check_running_cpu_revision(void);
|
||||
|
||||
/**
|
||||
* @brief Initialize the CPU, set IRQ priorities
|
||||
*/
|
||||
void cpu_init(void)
|
||||
{
|
||||
/* Check that we are running on the CPU that this code was built for */
|
||||
check_running_cpu_revision();
|
||||
|
||||
/* configure the vector table location to internal flash */
|
||||
SCB->VTOR = (uint32_t)_vector_rom;
|
||||
|
||||
/* set pendSV interrupt to lowest possible priority */
|
||||
NVIC_SetPriority(PendSV_IRQn, 0xff);
|
||||
|
||||
}
|
||||
|
||||
static void check_running_cpu_revision(void)
|
||||
{
|
||||
/* Check that the running CPU revision matches the compiled revision */
|
||||
if (SCB->CPUID != K60_EXPECTED_CPUID) {
|
||||
uint32_t CPUID = SCB->CPUID; /* This is only to ease debugging, type
|
||||
* "print /x CPUID" in gdb */
|
||||
uint32_t SILICON_REVISION = (SCB->CPUID & SCB_CPUID_REVISION_Msk) + 1;
|
||||
(void)CPUID; /* prevents compiler warnings about an unused variable. */
|
||||
(void)SILICON_REVISION;
|
||||
|
||||
/* Running on the wrong CPU, the clock initialization is different
|
||||
* between silicon revision 1.x and 2.x (LSB of CPUID) */
|
||||
/* If you unexpectedly end up on this line when debugging:
|
||||
* Rebuild the code using the correct value for K60_CPU_REV */
|
||||
__ASM volatile ("bkpt #99\n");
|
||||
|
||||
while (1);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemCoreClockUpdate(void)
|
||||
{
|
||||
/* Variable to store output clock frequency of the MCG module */
|
||||
uint32_t MCGOUT_clock;
|
||||
|
||||
if ((MCG->C1 & MCG_C1_CLKS_MASK) == 0x0u) {
|
||||
/* Output of FLL or PLL is selected */
|
||||
if ((MCG->C6 & MCG_C6_PLLS_MASK) == 0x0u) {
|
||||
/* FLL is selected */
|
||||
if ((MCG->C1 & MCG_C1_IREFS_MASK) == 0x0u) {
|
||||
/* External reference clock is selected */
|
||||
#if K60_CPU_REV == 1
|
||||
/* rev.1 silicon */
|
||||
if ((SIM->SOPT2 & SIM_SOPT2_MCGCLKSEL_MASK) == 0x0u) {
|
||||
/* System oscillator drives MCG clock */
|
||||
MCGOUT_clock = CPU_XTAL_CLK_HZ;
|
||||
}
|
||||
else {
|
||||
/* RTC 32 kHz oscillator drives MCG clock */
|
||||
MCGOUT_clock = CPU_XTAL32k_CLK_HZ;
|
||||
}
|
||||
|
||||
#else /* K60_CPU_REV */
|
||||
|
||||
/* rev.2 silicon */
|
||||
if ((MCG->C7 & MCG_C7_OSCSEL_MASK) == 0x0u) {
|
||||
/* System oscillator drives MCG clock */
|
||||
MCGOUT_clock = CPU_XTAL_CLK_HZ;
|
||||
}
|
||||
else {
|
||||
/* RTC 32 kHz oscillator drives MCG clock */
|
||||
MCGOUT_clock = CPU_XTAL32k_CLK_HZ;
|
||||
}
|
||||
|
||||
#endif /* K60_CPU_REV */
|
||||
uint8_t divider = (uint8_t)(1u << ((MCG->C1 & MCG_C1_FRDIV_MASK) >> MCG_C1_FRDIV_SHIFT));
|
||||
/* Calculate the divided FLL reference clock */
|
||||
MCGOUT_clock /= divider;
|
||||
|
||||
if ((MCG->C2 & MCG_C2_RANGE0_MASK) != 0x0u) {
|
||||
/* If high range is enabled, additional 32 divider is active */
|
||||
MCGOUT_clock /= 32u;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* The slow internal reference clock is selected */
|
||||
MCGOUT_clock = CPU_INT_SLOW_CLK_HZ;
|
||||
}
|
||||
|
||||
/* Select correct multiplier to calculate the MCG output clock */
|
||||
switch (MCG->C4 & (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS_MASK)) {
|
||||
case (0x0u):
|
||||
MCGOUT_clock *= 640u;
|
||||
break;
|
||||
|
||||
case (MCG_C4_DRST_DRS(0b01)): /* 0x20u */
|
||||
MCGOUT_clock *= 1280u;
|
||||
break;
|
||||
|
||||
case (MCG_C4_DRST_DRS(0b10)): /* 0x40u */
|
||||
MCGOUT_clock *= 1920u;
|
||||
break;
|
||||
|
||||
case (MCG_C4_DRST_DRS(0b11)): /* 0x60u */
|
||||
MCGOUT_clock *= 2560u;
|
||||
break;
|
||||
|
||||
case (MCG_C4_DMX32_MASK): /* 0x80u */
|
||||
MCGOUT_clock *= 732u;
|
||||
break;
|
||||
|
||||
case (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0b01)): /* 0xA0u */
|
||||
MCGOUT_clock *= 1464u;
|
||||
break;
|
||||
|
||||
case (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0b10)): /* 0xC0u */
|
||||
MCGOUT_clock *= 2197u;
|
||||
break;
|
||||
|
||||
case (MCG_C4_DMX32_MASK | MCG_C4_DRST_DRS(0b11)): /* 0xE0u */
|
||||
MCGOUT_clock *= 2929u;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* PLL is selected */
|
||||
/* Calculate the PLL reference clock */
|
||||
uint8_t divider = (1u + (MCG->C5 & MCG_C5_PRDIV0_MASK));
|
||||
MCGOUT_clock = (uint32_t)(CPU_XTAL_CLK_HZ / divider);
|
||||
/* Calculate the MCG output clock */
|
||||
divider = ((MCG->C6 & MCG_C6_VDIV0_MASK) + 24u);
|
||||
MCGOUT_clock *= divider;
|
||||
}
|
||||
}
|
||||
else if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0b01)) { /* 0x40u */
|
||||
/* Internal reference clock is selected */
|
||||
if ((MCG->C2 & MCG_C2_IRCS_MASK) == 0x0u) {
|
||||
/* Slow internal reference clock selected */
|
||||
MCGOUT_clock = CPU_INT_SLOW_CLK_HZ;
|
||||
}
|
||||
else {
|
||||
/* Fast internal reference clock selected */
|
||||
#if K60_CPU_REV == 1
|
||||
/* rev.1 silicon */
|
||||
MCGOUT_clock = CPU_INT_FAST_CLK_HZ;
|
||||
#else /* K60_CPU_REV */
|
||||
/* rev.2 silicon */
|
||||
MCGOUT_clock = CPU_INT_FAST_CLK_HZ /
|
||||
(1 << ((MCG->SC & MCG_SC_FCRDIV_MASK) >> MCG_SC_FCRDIV_SHIFT));
|
||||
#endif /* K60_CPU_REV */
|
||||
}
|
||||
}
|
||||
else if ((MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0b10)) { /* 0x80u */
|
||||
/* External reference clock is selected */
|
||||
#if K60_CPU_REV == 1
|
||||
/* rev.1 silicon */
|
||||
if ((SIM->SOPT2 & SIM_SOPT2_MCGCLKSEL_MASK) == 0x0u) {
|
||||
/* System oscillator drives MCG clock */
|
||||
MCGOUT_clock = CPU_XTAL_CLK_HZ;
|
||||
}
|
||||
else {
|
||||
/* RTC 32 kHz oscillator drives MCG clock */
|
||||
MCGOUT_clock = CPU_XTAL32k_CLK_HZ;
|
||||
}
|
||||
|
||||
#else /* K60_CPU_REV */
|
||||
|
||||
/* rev.2 silicon */
|
||||
if ((MCG->C7 & MCG_C7_OSCSEL_MASK) == 0x0u) {
|
||||
/* System oscillator drives MCG clock */
|
||||
MCGOUT_clock = CPU_XTAL_CLK_HZ;
|
||||
}
|
||||
else {
|
||||
/* RTC 32 kHz oscillator drives MCG clock */
|
||||
MCGOUT_clock = CPU_XTAL32k_CLK_HZ;
|
||||
}
|
||||
|
||||
#endif /* K60_CPU_REV */
|
||||
}
|
||||
else {
|
||||
/* Reserved value */
|
||||
return;
|
||||
}
|
||||
|
||||
/* Core clock and system clock use the same divider setting */
|
||||
SystemCoreClock = SystemSysClock = (MCGOUT_clock / (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV1_MASK)
|
||||
>> SIM_CLKDIV1_OUTDIV1_SHIFT)));
|
||||
SystemBusClock = (MCGOUT_clock / (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV2_MASK) >>
|
||||
SIM_CLKDIV1_OUTDIV2_SHIFT)));
|
||||
SystemFlexBusClock = (MCGOUT_clock / (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV3_MASK) >>
|
||||
SIM_CLKDIV1_OUTDIV3_SHIFT)));
|
||||
SystemFlashClock = (MCGOUT_clock / (1u + ((SIM->CLKDIV1 & SIM_CLKDIV1_OUTDIV4_MASK) >>
|
||||
SIM_CLKDIV1_OUTDIV4_SHIFT)));
|
||||
|
||||
/* Module helper variables */
|
||||
if (SystemBusClock >= 1000000) {
|
||||
/* PIT module clock_delay_usec scale factor */
|
||||
PIT_ticks_per_usec = (SystemBusClock + 500000) / 1000000; /* Rounded to nearest integer */
|
||||
}
|
||||
else {
|
||||
/* less than 1 MHz clock frequency on the PIT module, round up. */
|
||||
PIT_ticks_per_usec = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** @} */
|
@ -0,0 +1,3 @@
|
||||
MODULE = devio
|
||||
|
||||
include $(RIOTBASE)/Makefile.base
|
@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device I/O helpers for a no-op device, implementations.
|
||||
*
|
||||
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <reent.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "devio-null.h"
|
||||
|
||||
int devnull_open_r(struct _reent *r, const char *path, int flags, int mode)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int devnull_close_r(struct _reent *r, int fd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
long devnull_write_r(struct _reent *r, int fd, const char *ptr, int len)
|
||||
{
|
||||
/* Aaand... it's gone!*/
|
||||
return len;
|
||||
}
|
||||
|
||||
long devnull_read_r(struct _reent *r, int fd, char *ptr, int len)
|
||||
{
|
||||
/* Read null bytes */
|
||||
memset(ptr, '\0', len);
|
||||
return len;
|
||||
}
|
||||
|
||||
long devnull_lseek_r(struct _reent *r, int fd, int ptr, int dir)
|
||||
{
|
||||
r->_errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
long devnull_fstat_r(struct _reent *r, int fd, char *ptr, int len)
|
||||
{
|
||||
r->_errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
/*
|
||||
* 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_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device I/O helpers for UARTs on K60, implementation.
|
||||
*
|
||||
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include "devio-uart.h"
|
||||
#include "periph/uart.h"
|
||||
#include "cpu.h"
|
||||
|
||||
static inline long uart_write_r(uart_t uart_num, struct _reent *r, int fd, const char *ptr,
|
||||
int len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
while (i < len) {
|
||||
uart_write_blocking(uart_num, ptr[i]);
|
||||
++i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static long uart_read_r(uart_t uart_num, struct _reent *r, int fd, char *ptr, int len)
|
||||
{
|
||||
/* not yet implemented */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if UART_0_EN
|
||||
long uart0_write_r(struct _reent *r, int fd, const char *ptr, int len)
|
||||
{
|
||||
return uart_write_r(UART_0, r, fd, ptr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UART_1_EN
|
||||
long uart1_write_r(struct _reent *r, int fd, const char *ptr, int len)
|
||||
{
|
||||
return uart_write_r(UART_1, r, fd, ptr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UART_2_EN
|
||||
long uart2_write_r(struct _reent *r, int fd, const char *ptr, int len)
|
||||
{
|
||||
return uart_write_r(UART_2, r, fd, ptr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UART_3_EN
|
||||
long uart3_write_r(struct _reent *r, int fd, const char *ptr, int len)
|
||||
{
|
||||
return uart_write_r(UART_3, r, fd, ptr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UART_4_EN
|
||||
long uart4_write_r(struct _reent *r, int fd, const char *ptr, int len)
|
||||
{
|
||||
return uart_write_r(UART_4, r, fd, ptr, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if UART_0_EN
|
||||
long uart0_read_r(struct _reent *r, int fd, char *ptr, int len)
|
||||
{
|
||||
return uart_read_r(UART_0, r, fd, ptr, len);
|
||||
}
|
||||
#endif
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* 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_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Compatibility definitions between MK60D10.h and MK60DZ10.h
|
||||
*
|
||||
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||
*/
|
||||
|
||||
#ifndef MK60_COMP_H_
|
||||
#define MK60_COMP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#if K60_CPU_REV == 1
|
||||
|
||||
/* Some compatibility defines to minimize the ifdefs needed for the register
|
||||
* name changes */
|
||||
|
||||
#define SIM_SCGC6_SPI0_MASK SIM_SCGC6_DSPI0_MASK
|
||||
#define SIM_SCGC6_SPI0_SHIFT SIM_SCGC6_DSPI0_SHIFT
|
||||
|
||||
#define MCG_C2_RANGE0_MASK MCG_C2_RANGE_MASK
|
||||
#define MCG_C5_PRDIV0_MASK MCG_C5_PRDIV_MASK
|
||||
#define MCG_C6_VDIV0_MASK MCG_C6_VDIV_MASK
|
||||
|
||||
#define UART_BASES { UART0, UART1, UART2, UART3, UART4, UART5 }
|
||||
|
||||
#define LPTMR0_IRQn LPTimer_IRQn
|
||||
|
||||
/* Rev 2.x made the OSC32KSEL field into a bitfield (is a single bit in 1.x) */
|
||||
#define SIM_SOPT1_OSC32KSEL(a) (SIM_SOPT1_OSC32KSEL_MASK)
|
||||
|
||||
#endif /* K60_CPU_REV == 1 */
|
||||
|
||||
|
||||
/* Compatibility defines for compatibility with differing module names between
|
||||
* MK60 and MKW22 headers */
|
||||
#define SIM_SCGC5_LPTMR_MASK SIM_SCGC5_LPTIMER_MASK
|
||||
#define SIM_SCGC5_LPTMR_SHIFT SIM_SCGC5_LPTIMER_SHIFT
|
||||
|
||||
#ifndef OSC0
|
||||
/* Compatibility definition */
|
||||
#define OSC0 OSC
|
||||
#endif
|
||||
#ifndef MCG_C2_RANGE0
|
||||
/* Rev 2 parts renamed the parameter RANGE -> RANGE0 */
|
||||
#define MCG_C2_RANGE0 MCG_C2_RANGE
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* MK60_COMP_H_ */
|
||||
/** @} */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,333 @@
|
||||
/*
|
||||
* 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_k60 Freescale Kinetis K60
|
||||
* @ingroup cpu
|
||||
* @brief CPU specific implementations for the Freescale Kinetis K60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Implementation specific CPU configuration options
|
||||
*
|
||||
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||
*/
|
||||
|
||||
#ifndef CPU_CONF_H_
|
||||
#define CPU_CONF_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined(CPU_MODEL_K60DN512VLL10) || defined(CPU_MODEL_K60DN256VLL10)
|
||||
|
||||
/* Rev. 2.x silicon */
|
||||
#define K60_CPU_REV 2
|
||||
#include "MK60D10.h"
|
||||
|
||||
/** The expected CPUID value, can be used to implement a check that we are
|
||||
* running on the right hardware */
|
||||
#define K60_EXPECTED_CPUID 0x410fc241u
|
||||
|
||||
/* K60 rev 2.x replaced the RNG module in 1.x by the RNGA PRNG module */
|
||||
#define KINETIS_RNGA (RNG)
|
||||
|
||||
#elif defined(CPU_MODEL_K60DN512ZVLL10) || defined(CPU_MODEL_K60DN256ZVLL10)
|
||||
|
||||
/* Rev. 1.x silicon */
|
||||
#define K60_CPU_REV 1
|
||||
#include "MK60DZ10.h"
|
||||
|
||||
/** The expected CPUID value, can be used to implement a check that we are
|
||||
* running on the right hardware */
|
||||
#define K60_EXPECTED_CPUID 0x410fc240u
|
||||
|
||||
/* K60 rev 1.x has the cryptographically strong RNGB module */
|
||||
#define KINETIS_RNGB (RNG)
|
||||
|
||||
#else
|
||||
#error Unknown CPU model. Update Makefile.include in the board directory.
|
||||
#endif
|
||||
|
||||
/* Compatibility definitions between the two different Freescale headers */
|
||||
#include "MK60-comp.h"
|
||||
|
||||
/**
|
||||
* @name GPIO pin mux function numbers
|
||||
*/
|
||||
/** @{ */
|
||||
#define PIN_MUX_FUNCTION_ANALOG 0
|
||||
#define PIN_MUX_FUNCTION_GPIO 1
|
||||
/** @} */
|
||||
/**
|
||||
* @name GPIO interrupt flank settings
|
||||
*/
|
||||
/** @{ */
|
||||
#define PIN_INTERRUPT_RISING 0b1001
|
||||
#define PIN_INTERRUPT_FALLING 0b1010
|
||||
#define PIN_INTERRUPT_EDGE 0b1011
|
||||
/** @} */
|
||||
/**
|
||||
* @name Kernel stack size configuration
|
||||
*
|
||||
* TODO: Tune this
|
||||
* @{
|
||||
*/
|
||||
#define KERNEL_CONF_STACKSIZE_PRINTF (1024)
|
||||
|
||||
#ifndef KERNEL_CONF_STACKSIZE_DEFAULT
|
||||
#define KERNEL_CONF_STACKSIZE_DEFAULT (1024)
|
||||
#endif
|
||||
|
||||
#define KERNEL_CONF_STACKSIZE_IDLE (256)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Length and address for reading CPU_ID (named UID in Freescale documents)
|
||||
* @{
|
||||
*/
|
||||
#define CPUID_ID_LEN (16)
|
||||
#define CPUID_ID_PTR ((void *)(&(SIM->UIDH)))
|
||||
/** @} */
|
||||
|
||||
#ifndef UART0_BUFSIZE
|
||||
/**
|
||||
* @brief UART0 buffer size definition for compatibility reasons
|
||||
*
|
||||
* TODO: remove once the remodeling of the uart0 driver is done
|
||||
*/
|
||||
#define UART0_BUFSIZE (128)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name UART driver settings
|
||||
*/
|
||||
/** @{ */
|
||||
/** UART typedef from CPU header. */
|
||||
#define KINETIS_UART UART_Type
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Clock settings for the LPTMR0 timer
|
||||
* @{
|
||||
*/
|
||||
#define LPTIMER_DEV (LPTMR0) /**< LPTIMER hardware module */
|
||||
#define LPTIMER_CLKEN() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_LPTIMER_SHIFT) = 1) /**< Enable LPTMR0 clock gate */
|
||||
#define LPTIMER_CLKDIS() (BITBAND_REG(SIM->SCGC5, SIM_SCGC5_LPTIMER_SHIFT) = 0) /**< Disable LPTMR0 clock gate */
|
||||
#define LPTIMER_CLKSRC_MCGIRCLK 0 /**< internal reference clock (4MHz) */
|
||||
#define LPTIMER_CLKSRC_LPO 1 /**< PMC 1kHz output */
|
||||
#define LPTIMER_CLKSRC_ERCLK32K 2 /**< RTC clock 32768Hz */
|
||||
#define LPTIMER_CLKSRC_OSCERCLK 3 /**< system oscillator output, clock from RF-Part */
|
||||
|
||||
#ifndef LPTIMER_CLKSRC
|
||||
#define LPTIMER_CLKSRC LPTIMER_CLKSRC_ERCLK32K /**< default clock source */
|
||||
#endif
|
||||
|
||||
#if (LPTIMER_CLKSRC == LPTIMER_CLKSRC_MCGIRCLK)
|
||||
#define LPTIMER_CLK_PRESCALE 1
|
||||
#define LPTIMER_SPEED 1000000
|
||||
#elif (LPTIMER_CLKSRC == LPTIMER_CLKSRC_OSCERCLK)
|
||||
#define LPTIMER_CLK_PRESCALE 1
|
||||
#define LPTIMER_SPEED 1000000
|
||||
#elif (LPTIMER_CLKSRC == LPTIMER_CLKSRC_ERCLK32K)
|
||||
#define LPTIMER_CLK_PRESCALE 0
|
||||
#define LPTIMER_SPEED 32768
|
||||
#else
|
||||
#define LPTIMER_CLK_PRESCALE 0
|
||||
#define LPTIMER_SPEED 1000
|
||||
#endif
|
||||
|
||||
/** IRQ priority for hwtimer interrupts */
|
||||
#define LPTIMER_IRQ_PRIO 1
|
||||
/** IRQ channel for hwtimer interrupts */
|
||||
#define LPTIMER_IRQ_CHAN LPTMR0_IRQn
|
||||
|
||||
#if K60_CPU_REV == 1
|
||||
/*
|
||||
* The CNR register latching in LPTMR0 was added in silicon rev 2.x. With
|
||||
* rev 1.x we do not need to do anything in order to read the current timer counter
|
||||
* value
|
||||
*/
|
||||
#define LPTIMER_CNR_NEEDS_LATCHING 0
|
||||
|
||||
#elif K60_CPU_REV == 2
|
||||
|
||||
#define LPTIMER_CNR_NEEDS_LATCHING 1
|
||||
|
||||
#endif
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @name Power mode hardware details
|
||||
*/
|
||||
/** @{ */
|
||||
#if K60_CPU_REV == 1
|
||||
#define KINETIS_PMCTRL MC->PMCTRL
|
||||
#define KINETIS_PMCTRL_SET_MODE(x) (KINETIS_PMCTRL = MC_PMCTRL_LPLLSM(x) | MC_PMCTRL_LPWUI_MASK)
|
||||
/* Clear LLS protection, clear VLPS, VLPW, VLPR protection */
|
||||
/* Note: This register can only be written once after each reset, so we must
|
||||
* enable all power modes that we wish to use. */
|
||||
#define KINETIS_UNLOCK_PMPROT() (MC->PMPROT |= MC_PMPROT_ALLS_MASK | MC_PMPROT_AVLP_MASK)
|
||||
#elif K60_CPU_REV == 2
|
||||
#define KINETIS_PMCTRL SMC->PMCTRL
|
||||
#define KINETIS_PMCTRL_SET_MODE(x) (KINETIS_PMCTRL = SMC_PMCTRL_STOPM(x) | SMC_PMCTRL_LPWUI_MASK)
|
||||
#define KINETIS_PMPROT_UNLOCK() (SMC->PMPROT |= SMC_PMPROT_ALLS_MASK | SMC_PMPROT_AVLP_MASK)
|
||||
#else
|
||||
#error Unknown K60 CPU revision!
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name STOP mode bitfield values
|
||||
* @{
|
||||
*/
|
||||
/** @brief Normal STOP */
|
||||
#define KINETIS_POWER_MODE_NORMAL (0b000)
|
||||
/** @brief VLPS STOP */
|
||||
#define KINETIS_POWER_MODE_VLPS (0b010)
|
||||
/** @brief LLS STOP */
|
||||
#define KINETIS_POWER_MODE_LLS (0b011)
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
* @brief Wake up source number for the LPTMR0
|
||||
*
|
||||
* In order to let the hwtimer wake the CPU from low power modes, we need to
|
||||
* enable this wake up source.
|
||||
*/
|
||||
#define KINETIS_LLWU_WAKEUP_MODULE_LPTMR 0
|
||||
|
||||
/**
|
||||
* @brief IRQn name to enable LLWU IRQ in NVIC
|
||||
*/
|
||||
#define KINETIS_LLWU_IRQ LLW_IRQn
|
||||
|
||||
/**
|
||||
* @brief Enable clock gate on LLWU module.
|
||||
*/
|
||||
#define LLWU_UNLOCK() (BITBAND_REG(SIM->SCGC4, SIM_SCGC4_LLWU_SHIFT) = 1)
|
||||
|
||||
/**
|
||||
* @brief Internal modules whose interrupts are mapped to LLWU wake up sources.
|
||||
*
|
||||
* Other modules CAN NOT be used to wake the CPU from LLS or VLLSx power modes.
|
||||
*/
|
||||
typedef enum llwu_wakeup_module {
|
||||
KINETIS_LPM_WAKEUP_MODULE_LPTMR = 0,
|
||||
KINETIS_LPM_WAKEUP_MODULE_CMP0 = 1,
|
||||
KINETIS_LPM_WAKEUP_MODULE_CMP1 = 2,
|
||||
KINETIS_LPM_WAKEUP_MODULE_CMP2 = 3,
|
||||
KINETIS_LPM_WAKEUP_MODULE_TSI = 4,
|
||||
KINETIS_LPM_WAKEUP_MODULE_RTC_ALARM = 5,
|
||||
KINETIS_LPM_WAKEUP_MODULE_RESERVED = 6,
|
||||
KINETIS_LPM_WAKEUP_MODULE_RTC_SECONDS = 7,
|
||||
KINETIS_LPM_WAKEUP_MODULE_END,
|
||||
} llwu_wakeup_module_t;
|
||||
|
||||
/**
|
||||
* @brief enum that maps physical pins to wakeup pin numbers in LLWU module
|
||||
*
|
||||
* Other pins CAN NOT be used to wake the CPU from LLS or VLLSx power modes.
|
||||
*/
|
||||
typedef enum llwu_wakeup_pin {
|
||||
KINETIS_LPM_WAKEUP_PIN_PTE1 = 0,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTE2 = 1,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTE4 = 2,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTA4 = 3,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTA13 = 4,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTB0 = 5,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTC1 = 6,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTC3 = 7,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTC4 = 8,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTC5 = 9,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTC6 = 10,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTC11 = 11,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTD0 = 12,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTD2 = 13,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTD4 = 14,
|
||||
KINETIS_LPM_WAKEUP_PIN_PTD6 = 15,
|
||||
KINETIS_LPM_WAKEUP_PIN_END
|
||||
} llwu_wakeup_pin_t;
|
||||
|
||||
/** @} */
|
||||
|
||||
/** @name K60 PORT ISR names
|
||||
* @{ */
|
||||
#define ISR_PORT_A isr_porta_pin_detect
|
||||
#define ISR_PORT_B isr_portb_pin_detect
|
||||
#define ISR_PORT_C isr_portc_pin_detect
|
||||
#define ISR_PORT_D isr_portd_pin_detect
|
||||
#define ISR_PORT_E isr_porte_pin_detect
|
||||
/** @} */
|
||||
|
||||
/** @brief Number of packets in transceiver queue */
|
||||
#define TRANSCEIVER_BUFFER_SIZE (3)
|
||||
|
||||
/**
|
||||
* @name Bit band macros
|
||||
* @{
|
||||
*/
|
||||
/* Generic bitband conversion routine */
|
||||
/** @brief Convert bit-band region address and bit number to bit-band alias address
|
||||
*
|
||||
* @param[in] addr base address in non-bit-banded memory
|
||||
* @param[in] bit bit number within the word
|
||||
*
|
||||
* @return Address of the bit within the bit-band memory region
|
||||
*/
|
||||
#define BITBAND_ADDR(addr, bit) ((((uint32_t) (addr)) & 0xF0000000u) + 0x2000000 + ((((uint32_t) (addr)) & 0xFFFFF) << 5) + ((bit) << 2))
|
||||
|
||||
/**
|
||||
* @brief Bitband 32 bit access to variable stored in SRAM_U
|
||||
*
|
||||
* @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up)
|
||||
* @note var must be declared 'volatile'
|
||||
*/
|
||||
#define BITBAND_VAR32(var, bit) (*((uint32_t volatile*) BITBAND_ADDR(&(var), (bit))))
|
||||
|
||||
/**
|
||||
* @brief Bitband 16 bit access to variable stored in SRAM_U
|
||||
*
|
||||
* @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up)
|
||||
* @note var must be declared 'volatile'
|
||||
*/
|
||||
#define BITBAND_VAR16(var, bit) (*((uint16_t volatile*) BITBAND_ADDR(&(var), (bit))))
|
||||
|
||||
/**
|
||||
* @brief Bitband 8 bit access to variable stored in SRAM_U
|
||||
*
|
||||
* @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up)
|
||||
* @note var must be declared 'volatile'
|
||||
*/
|
||||
#define BITBAND_VAR8(var, bit) (*((uint8_t volatile*) BITBAND_ADDR(&(var), (bit))))
|
||||
|
||||
/**
|
||||
* @brief Bitband 32 bit access to peripheral register
|
||||
*/
|
||||
#define BITBAND_PERIPH32(reg, bit) (*((uint32_t volatile*) BITBAND_ADDR(&(reg), (bit))))
|
||||
|
||||
/**
|
||||
* @brief Bitband 16 bit access to peripheral register
|
||||
*/
|
||||
#define BITBAND_PERIPH16(reg, bit) (*((uint16_t volatile*) BITBAND_ADDR(&(reg), (bit))))
|
||||
|
||||
/**
|
||||
* @brief Bitband 8 bit access to peripheral register
|
||||
*/
|
||||
#define BITBAND_PERIPH8(reg, bit) (*((uint8_t volatile*) BITBAND_ADDR(&(reg), (bit))))
|
||||
|
||||
/** @} */
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* CPU_CONF_H_ */
|
||||
/** @} */
|
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* 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_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device I/O helpers for a no-op device.
|
||||
*
|
||||
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||
*/
|
||||
#ifndef DEVIO_NULL_H_
|
||||
#define DEVIO_NULL_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
int devnull_open_r(struct _reent *r, const char *path, int flags, int mode);
|
||||
int devnull_close_r(struct _reent *r, int fd);
|
||||
long devnull_write_r(struct _reent *r, int fd, const char *ptr, int len);
|
||||
long devnull_read_r(struct _reent *r, int fd, char *ptr, int len);
|
||||
long devnull_lseek_r(struct _reent *r, int fd, int ptr, int dir);
|
||||
long devnull_fstat_r(struct _reent *r, int fd, char *ptr, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(DEVIO_NULL_H_) */
|
||||
/** @} */
|
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <reent.h>
|
||||
|
||||
/**
|
||||
* @ingroup cpu_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device I/O helpers for UARTs on K60.
|
||||
*
|
||||
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||
*/
|
||||
#ifndef DEVIO_UART_H_
|
||||
#define DEVIO_UART_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
long uart0_write_r(struct _reent *r, int fd, const char *ptr, int len);
|
||||
long uart1_write_r(struct _reent *r, int fd, const char *ptr, int len);
|
||||
long uart2_write_r(struct _reent *r, int fd, const char *ptr, int len);
|
||||
long uart3_write_r(struct _reent *r, int fd, const char *ptr, int len);
|
||||
long uart4_write_r(struct _reent *r, int fd, const char *ptr, int len);
|
||||
long uart0_read_r(struct _reent *r, int fd, char *ptr, int len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* !defined(DEVIO_UART_H_) */
|
||||
/** @} */
|
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <reent.h>
|
||||
|
||||
/**
|
||||
* @ingroup cpu_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device operations table.
|
||||
*
|
||||
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||
*/
|
||||
#ifndef DEVOPTTAB_H_
|
||||
#define DEVOPTTAB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Device operations table
|
||||
*
|
||||
* Inspired by http://neptune.billgatliff.com/newlib.html
|
||||
*
|
||||
* A simple "device operations" table, with function pointers for all the kinds
|
||||
* of activities you would expect a stream-like device to support.
|
||||
*/
|
||||
typedef struct {
|
||||
const char *name; /**< Device filename */
|
||||
const int isatty; /**< isatty() return code (usually 0 or 1) */
|
||||
const int st_mode; /**< st_mode code, see man 2 stat */
|
||||
int (*open_r)(struct _reent *r, const char *path, int flags,
|
||||
int mode); /**< pointer to open() function for this device */
|
||||
int (*close_r)(struct _reent *r, int fd); /**< pointer to close() function for this device */
|
||||
long(*write_r)(struct _reent *r, int fd, const char *ptr,
|
||||
int len); /**< pointer to write() function for this device */
|
||||
long(*read_r)(struct _reent *r, int fd, char *ptr,
|
||||
int len); /**< pointer to read() function for this device */
|
||||
long(*lseek_r)(struct _reent *r, int fd, int ptr,
|
||||
int dir); /**< pointer to lseek() function for this device */
|
||||
long(*fstat_r)(struct _reent *r, int fd, char *ptr,
|
||||
int len); /**< pointer to fstat() function for this device */
|
||||
} devoptab_t;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
/** @} */
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* 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_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief CPU specific hwtimer configuration options
|
||||
*
|
||||
* @author Hauke Petersen <hauke.peterse@fu-berlin.de>
|
||||
*/
|
||||
|
||||
#ifndef HWTIMER_CPU_H_
|
||||
#define HWTIMER_CPU_H_
|
||||
|
||||
#include "cpu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @name Hardware timer configuration
|
||||
* @{
|
||||
*/
|
||||
#define HWTIMER_MAXTIMERS 1 /**< the HW timer is using the LPTMR as its hardware timer */
|
||||
#define HWTIMER_SPEED 32768 /**< LPTMR is running at 32.768 kHz */
|
||||
#define HWTIMER_MAXTICKS (0xFFFFFFFF) /**< Virtually extended to 32 bits from 16 bits hardware counter. */
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HWTIMER_CPU_H_ */
|
||||
/** @} */
|
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef SYSTEM_MK60D10_H_
|
||||
#define SYSTEM_MK60D10_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @ingroup cpu_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
* @brief Device specific configuration file for MK60D10 (header file)
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* \brief Current core clock frequency
|
||||
*
|
||||
* MCGOUTCLK divided by OUTDIV1 clocks the ARM Cortex-M4 core.
|
||||
*/
|
||||
extern uint32_t SystemCoreClock;
|
||||
|
||||
/**
|
||||
* \brief Current system clock frequency
|
||||
*
|
||||
* MCGOUTCLK divided by OUTDIV1 clocks the crossbar switch and bus masters
|
||||
* directly connected to the crossbar. In addition, this clock is used for UART0
|
||||
* and UART1.
|
||||
*/
|
||||
extern uint32_t SystemSysClock;
|
||||
|
||||
/**
|
||||
* \brief Current bus clock frequency
|
||||
*
|
||||
* MCGOUTCLK divided by OUTDIV2 clocks the bus slaves and peripheral (excluding
|
||||
* memories).
|
||||
*/
|
||||
extern uint32_t SystemBusClock;
|
||||
|
||||
/**
|
||||
* \brief Current FlexBus clock frequency
|
||||
*
|
||||
* MCGOUTCLK divided by OUTDIV3 clocks the external FlexBus interface.
|
||||
*/
|
||||
extern uint32_t SystemFlexBusClock;
|
||||
|
||||
/**
|
||||
* \brief Current flash clock frequency
|
||||
*
|
||||
* MCGOUTCLK divided by OUTDIV4 clocks the flash memory.
|
||||
*/
|
||||
extern uint32_t SystemFlashClock;
|
||||
|
||||
/**
|
||||
* \brief Updates all of the SystemCoreClock variables.
|
||||
*
|
||||
* It must be called whenever the core clock is changed during program
|
||||
* execution. SystemCoreClockUpdate() evaluates the clock register settings and
|
||||
* calculates the current core clock.
|
||||
*/
|
||||
void SystemCoreClockUpdate(void);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* #if !defined(SYSTEM_MK60D10_H_) */
|
@ -0,0 +1 @@
|
||||
system_MK60D10.h
|
@ -0,0 +1,490 @@
|
||||
/*
|
||||
* 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_k60
|
||||
* @{
|
||||
*
|
||||
* @file
|
||||
*
|
||||
* @brief Interrupt vector for K60 MCU.
|
||||
*
|
||||
* @author Joakim Gebart <joakim.gebart@eistec.se>
|
||||
*
|
||||
* @note It is not necessary to modify this file to define custom interrupt
|
||||
* service routines. All symbols are defined weak, it is only necessary to
|
||||
* define a function with the same name in another file to override the default
|
||||
* interrupt handlers.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @name Interrupt vector definition
|
||||
* @{
|
||||
*/
|
||||
|
||||
#include "cpu.h"
|
||||
#include "fault_handlers.h"
|
||||
#include "wdog.h"
|
||||
|
||||
extern void *_estack[];
|
||||
extern void *_sstack[];
|
||||
|
||||
typedef void (*ISR_func)(void);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Unconditional jump to isr_unhandled()
|
||||
*
|
||||
* This function is only necessary since we can not declare weak aliases to
|
||||
* functions outside the translation unit (.c-file). The default isr_unhandled()
|
||||
* is defined in kinetis_common/fault_handlers.c.
|
||||
*/
|
||||
void isr_default_handler(void) __attribute__((naked));
|
||||
|
||||
void isr_default_handler(void)
|
||||
{
|
||||
__ASM volatile ("b isr_unhandled\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Early reset handler used to instrument the stack before it becomes in use.
|
||||
*
|
||||
* This function will fill the interrupt context-stack with canary values so
|
||||
* that it can be checked to measure stack usage, similar to CREATE_STACKTEST in
|
||||
* @ref thread_create
|
||||
*/
|
||||
void pre_reset_handler(void);
|
||||
|
||||
/** @brief Interrupt stack canary value
|
||||
*
|
||||
* @note 0xe7fe is the ARM Thumb machine code equivalent of asm("bl #-2\n") or
|
||||
* 'while (1);', i.e. an infinite loop.
|
||||
*/
|
||||
#define STACK_CANARY_WORD 0xE7FEE7FEu
|
||||
|
||||
void pre_reset_handler(void)
|
||||
{
|
||||
/*
|
||||
* Important: Keep this function as simple as possible, we must not use any
|
||||
* stack space or we will crash, since we will overwrite all of the stack.
|
||||
*/
|
||||
/* Disable watchdog first, it is necessary to do within 256 cycles.
|
||||
* After this we will completely overwrite the stack so all necessary
|
||||
* variables must be stored in registers or as immediate values in the
|
||||
* machine code. */
|
||||
wdog_disable();
|
||||
/*
|
||||
* The register keyword suggests to the compiler to place the variable in a
|
||||
* register instead of on the stack. Using the register keyword is not a
|
||||
* guarantee that the variable will be placed in a register. However, this
|
||||
* function has been verified manually by disassembling the GCC output to
|
||||
* ensure no stack is being used until after the write loop is finished.
|
||||
*/
|
||||
register uint32_t *p;
|
||||
|
||||
/* Fill stack space with canary values */
|
||||
for (p = (uint32_t *)_sstack; p < (uint32_t *)_estack; ++p) {
|
||||
*p = STACK_CANARY_WORD;
|
||||
}
|
||||
|
||||
/* Now launch the real reset handler. */
|
||||
__ASM volatile("b reset_handler\n");
|
||||
|
||||
/* reset_handler should never return */
|
||||
while (1);
|
||||
}
|
||||
|
||||
#define ISR_VECTOR_SECTION __attribute__ ((used,section(".vector_table")))
|
||||
|
||||
#define UNHANDLED_ALIAS __attribute__((weak, alias("isr_default_handler")));
|
||||
|
||||
/* ARM Cortex defined interrupt vectors */
|
||||
/**
|
||||
* @brief Default reset handler.
|
||||
*/
|
||||
void reset_handler(void) __attribute__((naked));
|
||||
void isr_nmi(void) UNHANDLED_ALIAS;
|
||||
void isr_hard_fault(void) UNHANDLED_ALIAS;
|
||||
void isr_mem_manage(void) UNHANDLED_ALIAS;
|
||||
void isr_bus_fault(void) UNHANDLED_ALIAS;
|
||||
void isr_usage_fault(void) UNHANDLED_ALIAS;
|
||||
void isr_reserved(void) UNHANDLED_ALIAS;
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
void isr_svc(void) UNHANDLED_ALIAS;
|
||||
void isr_debug_mon(void) UNHANDLED_ALIAS;
|
||||
/* void _isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
void isr_pendsv(void) UNHANDLED_ALIAS;
|
||||
void isr_systick(void) UNHANDLED_ALIAS;
|
||||
|
||||
/* device-specific (freescale) defined interrupt vectors */
|
||||
void isr_dma0_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma1_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma2_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma3_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma4_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma5_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma6_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma7_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma8_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma9_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma10_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma11_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma12_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma13_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma14_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma15_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_dma_error(void) UNHANDLED_ALIAS;
|
||||
void isr_mcm(void) UNHANDLED_ALIAS;
|
||||
void isr_flash_command_complete(void) UNHANDLED_ALIAS;
|
||||
void isr_flash_read_collision(void) UNHANDLED_ALIAS;
|
||||
void isr_low_voltage(void) UNHANDLED_ALIAS;
|
||||
void isr_llwu(void) UNHANDLED_ALIAS;
|
||||
void isr_watchdog(void) UNHANDLED_ALIAS;
|
||||
void isr_random_number_generator(void) UNHANDLED_ALIAS;
|
||||
void isr_i2c0(void) UNHANDLED_ALIAS;
|
||||
void isr_i2c1(void) UNHANDLED_ALIAS;
|
||||
void isr_spi0(void) UNHANDLED_ALIAS;
|
||||
void isr_spi1(void) UNHANDLED_ALIAS;
|
||||
void isr_spi2(void) UNHANDLED_ALIAS;
|
||||
void isr_can0_ored_msg_buffer(void) UNHANDLED_ALIAS;
|
||||
void isr_can0_bus_off(void) UNHANDLED_ALIAS;
|
||||
void isr_can0_error(void) UNHANDLED_ALIAS;
|
||||
void isr_can0_tx_warn(void) UNHANDLED_ALIAS;
|
||||
void isr_can0_rx_warn(void) UNHANDLED_ALIAS;
|
||||
void isr_can0_wake_up(void) UNHANDLED_ALIAS;
|
||||
void isr_i2s0_tx(void) UNHANDLED_ALIAS;
|
||||
void isr_i2s0_rx(void) UNHANDLED_ALIAS;
|
||||
void isr_can1_ored_msg_buffer(void) UNHANDLED_ALIAS;
|
||||
void isr_can1_bus_off(void) UNHANDLED_ALIAS;
|
||||
void isr_can1_error(void) UNHANDLED_ALIAS;
|
||||
void isr_can1_tx_warn(void) UNHANDLED_ALIAS;
|
||||
void isr_can1_rx_warn(void) UNHANDLED_ALIAS;
|
||||
void isr_can1_wake_up(void) UNHANDLED_ALIAS;
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
void isr_uart0_lon(void) UNHANDLED_ALIAS;
|
||||
void isr_uart0_status(void) UNHANDLED_ALIAS;
|
||||
void isr_uart0_error(void) UNHANDLED_ALIAS;
|
||||
void isr_uart1_status(void) UNHANDLED_ALIAS;
|
||||
void isr_uart1_error(void) UNHANDLED_ALIAS;
|
||||
void isr_uart2_status(void) UNHANDLED_ALIAS;
|
||||
void isr_uart2_error(void) UNHANDLED_ALIAS;
|
||||
void isr_uart3_status(void) UNHANDLED_ALIAS;
|
||||
void isr_uart3_error(void) UNHANDLED_ALIAS;
|
||||
void isr_uart4_status(void) UNHANDLED_ALIAS;
|
||||
void isr_uart4_error(void) UNHANDLED_ALIAS;
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
void isr_adc0(void) UNHANDLED_ALIAS;
|
||||
void isr_adc1(void) UNHANDLED_ALIAS;
|
||||
void isr_cmp0(void) UNHANDLED_ALIAS;
|
||||
void isr_cmp1(void) UNHANDLED_ALIAS;
|
||||
void isr_cmp2(void) UNHANDLED_ALIAS;
|
||||
void isr_ftm0(void) UNHANDLED_ALIAS;
|
||||
void isr_ftm1(void) UNHANDLED_ALIAS;
|
||||
void isr_ftm2(void) UNHANDLED_ALIAS;
|
||||
void isr_cmt(void) UNHANDLED_ALIAS;
|
||||
void isr_rtc_alarm(void) UNHANDLED_ALIAS;
|
||||
void isr_rtc_seconds(void) UNHANDLED_ALIAS;
|
||||
void isr_pit0(void) UNHANDLED_ALIAS;
|
||||
void isr_pit1(void) UNHANDLED_ALIAS;
|
||||
void isr_pit2(void) UNHANDLED_ALIAS;
|
||||
void isr_pit3(void) UNHANDLED_ALIAS;
|
||||
void isr_pdb(void) UNHANDLED_ALIAS;
|
||||
void isr_usb_otg(void) UNHANDLED_ALIAS;
|
||||
void isr_usb_charger_detect(void) UNHANDLED_ALIAS;
|
||||
void isr_enet_1588_timer(void) UNHANDLED_ALIAS;
|
||||
void isr_enet_tx(void) UNHANDLED_ALIAS;
|
||||
void isr_enet_rx(void) UNHANDLED_ALIAS;
|
||||
void isr_enet_error_misc(void) UNHANDLED_ALIAS;
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
void isr_sdhc(void) UNHANDLED_ALIAS;
|
||||
void isr_dac0(void) UNHANDLED_ALIAS;
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
void isr_tsi(void) UNHANDLED_ALIAS;
|
||||
void isr_mcg(void) UNHANDLED_ALIAS;
|
||||
void isr_lptmr0(void) UNHANDLED_ALIAS;
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
void isr_porta_pin_detect(void) UNHANDLED_ALIAS;
|
||||
void isr_portb_pin_detect(void) UNHANDLED_ALIAS;
|
||||
void isr_portc_pin_detect(void) UNHANDLED_ALIAS;
|
||||
void isr_portd_pin_detect(void) UNHANDLED_ALIAS;
|
||||
void isr_porte_pin_detect(void) UNHANDLED_ALIAS;
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
/* void isr_reserved(void) UNHANDLED_ALIAS; */
|
||||
void isr_software(void) UNHANDLED_ALIAS;
|
||||
|
||||
/**
|
||||
* @brief Interrupt vector definition
|
||||
*/
|
||||
const ISR_func isr_vector[256] ISR_VECTOR_SECTION = {
|
||||
/* ARM Cortex defined interrupt vectors */
|
||||
(ISR_func)_estack,
|
||||
pre_reset_handler,
|
||||
isr_nmi,
|
||||
isr_hard_fault,
|
||||
isr_mem_manage,
|
||||
isr_bus_fault,
|
||||
isr_usage_fault,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_svc,
|
||||
isr_debug_mon,
|
||||
isr_reserved,
|
||||
isr_pendsv,
|
||||
isr_systick,
|
||||
|
||||
/* Device-specific (Freescale defined) interrupt vectors */
|
||||
isr_dma0_complete,
|
||||
isr_dma1_complete,
|
||||
isr_dma2_complete,
|
||||
isr_dma3_complete,
|
||||
isr_dma4_complete,
|
||||
isr_dma5_complete,
|
||||
isr_dma6_complete,
|
||||
isr_dma7_complete,
|
||||
isr_dma8_complete,
|
||||
isr_dma9_complete,
|
||||
isr_dma10_complete,
|
||||
isr_dma11_complete,
|
||||
isr_dma12_complete,
|
||||
isr_dma13_complete,
|
||||
isr_dma14_complete,
|
||||
isr_dma15_complete,
|
||||
isr_dma_error,
|
||||
isr_mcm,
|
||||
isr_flash_command_complete,
|
||||
isr_flash_read_collision,
|
||||
isr_low_voltage,
|
||||
isr_llwu,
|
||||
isr_watchdog,
|
||||
isr_random_number_generator,
|
||||
isr_i2c0,
|
||||
isr_i2c1,
|
||||
isr_spi0,
|
||||
isr_spi1,
|
||||
isr_spi2,
|
||||
isr_can0_ored_msg_buffer,
|
||||
isr_can0_bus_off,
|
||||
isr_can0_error,
|
||||
isr_can0_tx_warn,
|
||||
isr_can0_rx_warn,
|
||||
isr_can0_wake_up,
|
||||
isr_i2s0_tx,
|
||||
isr_i2s0_rx,
|
||||
isr_can1_ored_msg_buffer,
|
||||
isr_can1_bus_off,
|
||||
isr_can1_error,
|
||||
isr_can1_tx_warn,
|
||||
isr_can1_rx_warn,
|
||||
isr_can1_wake_up,
|
||||
isr_reserved,
|
||||
isr_uart0_lon,
|
||||
isr_uart0_status,
|
||||
isr_uart0_error,
|
||||
isr_uart1_status,
|
||||
isr_uart1_error,
|
||||
isr_uart2_status,
|
||||
isr_uart2_error,
|
||||
isr_uart3_status,
|
||||
isr_uart3_error,
|
||||
isr_uart4_status,
|
||||
isr_uart4_error,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_adc0,
|
||||
isr_adc1,
|
||||
isr_cmp0,
|
||||
isr_cmp1,
|
||||
isr_cmp2,
|
||||
isr_ftm0,
|
||||
isr_ftm1,
|
||||
isr_ftm2,
|
||||
isr_cmt,
|
||||
isr_rtc_alarm,
|
||||
isr_rtc_seconds,
|
||||
isr_pit0,
|
||||
isr_pit1,
|
||||
isr_pit2,
|
||||
isr_pit3,
|
||||
isr_pdb,
|
||||
isr_usb_otg,
|
||||
isr_usb_charger_detect,
|
||||
isr_enet_1588_timer,
|
||||
isr_enet_tx,
|
||||
isr_enet_rx,
|
||||
isr_enet_error_misc,
|
||||
isr_reserved,
|
||||
isr_sdhc,
|
||||
isr_dac0,
|
||||
isr_reserved,
|
||||
isr_tsi,
|
||||
isr_mcg,
|
||||
isr_lptmr0,
|
||||
isr_reserved,
|
||||
isr_porta_pin_detect,
|
||||
isr_portb_pin_detect,
|
||||
isr_portc_pin_detect,
|
||||
isr_portd_pin_detect,
|
||||
isr_porte_pin_detect,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_software, /* Vector 110 */
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||
isr_reserved,
|
||||