aboutsummaryrefslogtreecommitdiffstats
path: root/os/hal/ports
diff options
context:
space:
mode:
authorFabien Poussin <fabien.poussin@gmail.com>2018-05-05 19:23:19 +0200
committerGitHub <noreply@github.com>2018-05-05 19:23:19 +0200
commitdfd4708dbcb52315df18d388a3ba295a9a02f319 (patch)
tree896eece34f04ad92c2666d718c58ddf10bc3d075 /os/hal/ports
parentee2031101c96705baa56fdc8a00eccebebd1aeec (diff)
parent527ddd6e45c8682693deff351c544fb72e151979 (diff)
downloadChibiOS-Contrib-dfd4708dbcb52315df18d388a3ba295a9a02f319.tar.gz
ChibiOS-Contrib-dfd4708dbcb52315df18d388a3ba295a9a02f319.tar.bz2
ChibiOS-Contrib-dfd4708dbcb52315df18d388a3ba295a9a02f319.zip
Merge pull request #156 from wiml/k64_support
Kinetis K64 and PJRC Teensy3.5 support
Diffstat (limited to 'os/hal/ports')
-rw-r--r--os/hal/ports/KINETIS/K60x/hal_lld.c237
-rw-r--r--os/hal/ports/KINETIS/K60x/hal_lld.h302
-rw-r--r--os/hal/ports/KINETIS/K60x/kinetis_registry.h198
-rw-r--r--os/hal/ports/KINETIS/K60x/platform.mk19
4 files changed, 756 insertions, 0 deletions
diff --git a/os/hal/ports/KINETIS/K60x/hal_lld.c b/os/hal/ports/KINETIS/K60x/hal_lld.c
new file mode 100644
index 0000000..cfe633b
--- /dev/null
+++ b/os/hal/ports/KINETIS/K60x/hal_lld.c
@@ -0,0 +1,237 @@
+/*
+ ChibiOS - Copyright (C) 2014-2015 Fabio Utzig
+ Copyright (C) 2017 Fabio Utzig
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file templates/hal_lld.c
+ * @brief HAL Driver subsystem low level driver source template.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#include "hal.h"
+
+/*===========================================================================*/
+/* Driver local definitions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported variables. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver local variables and types. */
+/*===========================================================================*/
+
+#ifdef __CC_ARM
+__attribute__ ((section(".ARM.__at_0x400")))
+#else
+__attribute__ ((used,section(".cfmconfig")))
+#endif
+const uint8_t _cfm[0x10] = {
+ 0xFF, /* NV_BACKKEY3: KEY=0xFF */
+ 0xFF, /* NV_BACKKEY2: KEY=0xFF */
+ 0xFF, /* NV_BACKKEY1: KEY=0xFF */
+ 0xFF, /* NV_BACKKEY0: KEY=0xFF */
+ 0xFF, /* NV_BACKKEY7: KEY=0xFF */
+ 0xFF, /* NV_BACKKEY6: KEY=0xFF */
+ 0xFF, /* NV_BACKKEY5: KEY=0xFF */
+ 0xFF, /* NV_BACKKEY4: KEY=0xFF */
+ 0xFF, /* NV_FPROT3: PROT=0xFF */
+ 0xFF, /* NV_FPROT2: PROT=0xFF */
+ 0xFF, /* NV_FPROT1: PROT=0xFF */
+ 0xFF, /* NV_FPROT0: PROT=0xFF */
+ 0x7E, /* NV_FSEC: KEYEN=1,MEEN=3,FSLACC=3,SEC=2 */
+ 0xFF, /* NV_FOPT: ??=1,??=1,FAST_INIT=1,LPBOOT1=1,RESET_PIN_CFG=1,
+ NMI_DIS=1,EZPORT_DIS=1,LPBOOT0=1 */
+ 0xFF,
+ 0xFF
+};
+
+/*===========================================================================*/
+/* Driver local functions. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver interrupt handlers. */
+/*===========================================================================*/
+
+/*===========================================================================*/
+/* Driver exported functions. */
+/*===========================================================================*/
+
+/**
+ * @brief Low level HAL driver initialization.
+ * @todo Use a macro to define the system clock frequency.
+ *
+ * @notapi
+ */
+void hal_lld_init(void) {
+
+}
+
+/**
+ * @brief K60x clock initialization.
+ * @note All the involved constants come from the file @p board.h.
+ * @note This function is meant to be invoked early during the system
+ * initialization, it is usually invoked from the file
+ * @p board.c.
+ * @todo This function needs to be more generic.
+ * @todo This function should be combined with the nearly-identical
+ * functions in other Kinetis ports.
+ *
+ * @special
+ */
+void k60x_clock_init(void) {
+#if !KINETIS_NO_INIT
+
+ /* Disable the watchdog */
+ WDOG->UNLOCK = 0xC520;
+ WDOG->UNLOCK = 0xD928;
+ __asm__("nop");
+ WDOG->STCTRLH &= ~WDOG_STCTRLH_WDOGEN;
+
+ SIM->SCGC5 |= SIM_SCGC5_PORTA |
+ SIM_SCGC5_PORTB |
+ SIM_SCGC5_PORTC |
+ SIM_SCGC5_PORTD |
+ SIM_SCGC5_PORTE;
+
+#if KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEI
+ /* This is the default mode at reset. */
+
+ /* Configure FEI mode */
+ MCG->C4 = MCG_C4_DRST_DRS(KINETIS_MCG_FLL_DRS) |
+ (KINETIS_MCG_FLL_DMX32 ? MCG_C4_DMX32 : 0);
+
+ /* Set clock dividers */
+ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1-1) |
+ SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2-1) |
+ SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4-1);
+ SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0); /* not strictly necessary since usb_lld will set this */
+
+#elif KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE
+
+ uint32_t ratio, frdiv;
+ uint32_t ratios[] = { 32, 64, 128, 256, 512, 1024, 1280, 1536 };
+ uint8_t ratio_quantity = sizeof(ratios) / sizeof(ratios[0]);
+ uint8_t i;
+
+ /* EXTAL0 and XTAL0 */
+ PORTA->PCR[18] = 0;
+ PORTA->PCR[19] = 0;
+
+ /*
+ * Start in FEI mode
+ */
+
+ /* Internal capacitors for crystal */
+#if defined(KINETIS_BOARD_OSCILLATOR_SETTING)
+ OSC0->CR = KINETIS_BOARD_OSCILLATOR_SETTING;
+#else /* KINETIS_BOARD_OSCILLATOR_SETTING */
+ /* Disable the internal capacitors */
+ OSC0->CR = 0;
+#endif /* KINETIS_BOARD_OSCILLATOR_SETTING */
+
+ /* TODO: need to add more flexible calculation, specially regarding
+ * divisors which may not be available depending on the XTAL
+ * frequency, which would required other registers to be modified.
+ */
+ /* Enable OSC, low power mode */
+ if (KINETIS_XTAL_FREQUENCY > 8000000UL)
+ MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0 | MCG_C2_RANGE0(2);
+ else
+ MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0 | MCG_C2_RANGE0(1);
+
+ frdiv = 7;
+ ratio = KINETIS_XTAL_FREQUENCY / 31250UL;
+ for (i = 0; i < ratio_quantity; ++i) {
+ if (ratio == ratios[i]) {
+ frdiv = i;
+ break;
+ }
+ }
+
+ /* Switch to crystal as clock source, FLL input of 31.25 KHz */
+ MCG->C1 = MCG_C1_CLKS(2) | MCG_C1_FRDIV(frdiv);
+
+ /* Wait for crystal oscillator to begin */
+ while (!(MCG->S & MCG_S_OSCINIT0));
+
+ /* Wait for the FLL to use the oscillator */
+ while (MCG->S & MCG_S_IREFST);
+
+ /* Wait for the MCGOUTCLK to use the oscillator */
+ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST(2));
+
+ /*
+ * Now in FBE mode
+ */
+ #define KINETIS_PLLIN_FREQUENCY 2000000UL
+ /*
+ * Config PLL input for 2 MHz
+ * TODO: Make sure KINETIS_XTAL_FREQUENCY >= 2Mhz && <= 50Mhz
+ */
+ MCG->C5 = MCG_C5_PRDIV0((KINETIS_XTAL_FREQUENCY/KINETIS_PLLIN_FREQUENCY) - 1);
+
+ /*
+ * Config PLL output to match KINETIS_SYSCLK_FREQUENCY
+ * TODO: make sure KINETIS_SYSCLK_FREQUENCY is a match
+ */
+ for(i = 24; i < 56; i++)
+ {
+ if(i == (KINETIS_PLLCLK_FREQUENCY/KINETIS_PLLIN_FREQUENCY))
+ {
+ /* Config PLL to match KINETIS_PLLCLK_FREQUENCY */
+ MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(i-24);
+ break;
+ }
+ }
+
+ if(i>=56) /* Config PLL for 96 MHz output as default setting */
+ MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0);
+
+ /* Wait for PLL to start using crystal as its input, and to lock */
+ while ((MCG->S & (MCG_S_PLLST|MCG_S_LOCK0))!=(MCG_S_PLLST|MCG_S_LOCK0));
+
+ /*
+ * Now in PBE mode
+ */
+ /* Set the PLL dividers for the different clocks */
+ SIM->CLKDIV1 = SIM_CLKDIV1_OUTDIV1(KINETIS_CLKDIV1_OUTDIV1-1) |
+ SIM_CLKDIV1_OUTDIV2(KINETIS_CLKDIV1_OUTDIV2-1) |
+ SIM_CLKDIV1_OUTDIV4(KINETIS_CLKDIV1_OUTDIV4-1);
+ SIM->CLKDIV2 = SIM_CLKDIV2_USBDIV(0);
+ SIM->SOPT2 = SIM_SOPT2_PLLFLLSEL_IRC48M; /* FIXME ? Why this? */
+
+ /* Switch to PLL as clock source */
+ MCG->C1 = MCG_C1_CLKS(0);
+
+ /* Wait for PLL clock to be used */
+ while ((MCG->S & MCG_S_CLKST_MASK) != MCG_S_CLKST_PLL);
+
+ /*
+ * Now in PEE mode
+ */
+#else /* KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE */
+#error Unimplemented KINETIS_MCG_MODE
+#endif /* KINETIS_MCG_MODE == ... */
+
+#endif /* !KINETIS_NO_INIT */
+}
+
+/** @} */
diff --git a/os/hal/ports/KINETIS/K60x/hal_lld.h b/os/hal/ports/KINETIS/K60x/hal_lld.h
new file mode 100644
index 0000000..8da89b3
--- /dev/null
+++ b/os/hal/ports/KINETIS/K60x/hal_lld.h
@@ -0,0 +1,302 @@
+/*
+ ChibiOS - Copyright (C) 2014-2015 Fabio Utzig
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file K60x/hal_lld.h
+ * @brief Kinetis K60x HAL subsystem low level driver header.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef HAL_LLD_H_
+#define HAL_LLD_H_
+
+#include "kinetis_registry.h"
+
+/*===========================================================================*/
+/* Driver constants. */
+/*===========================================================================*/
+
+/**
+ * @brief Defines the support for realtime counters in the HAL.
+ */
+#define HAL_IMPLEMENTS_COUNTERS FALSE /* FIXME check */
+
+/**
+ * @name Platform identification
+ * @{
+ */
+#define PLATFORM_NAME "Kinetis"
+/** @} */
+
+/**
+ * @name Internal clock sources
+ * @{
+ */
+#define KINETIS_IRCLK_F 4000000 /**< Fast internal reference clock, factory trimmed. */
+#define KINETIS_IRCLK_S 32768 /**< Slow internal reference clock, factory trimmed. */
+/** @} */
+
+#define KINETIS_MCG_MODE_FEI 1 /**< FLL Engaged Internal. */
+#define KINETIS_MCG_MODE_FEE 2 /**< FLL Engaged External. */
+#define KINETIS_MCG_MODE_FBI 3 /**< FLL Bypassed Internal. */
+#define KINETIS_MCG_MODE_FBE 4 /**< FLL Bypassed External. */
+#define KINETIS_MCG_MODE_PEE 5 /**< PLL Engaged External. */
+#define KINETIS_MCG_MODE_PBE 6 /**< PLL Bypassed External. */
+#define KINETIS_MCG_MODE_BLPI 7 /**< Bypassed Low Power Internal. */
+#define KINETIS_MCG_MODE_BLPE 8 /**< Bypassed Low Power External. */
+
+/*===========================================================================*/
+/* Driver pre-compile time settings. */
+/*===========================================================================*/
+
+/**
+ * @name Configuration options
+ * @{
+ */
+/**
+ * @brief Disables the MCG/system clock initialization in the HAL.
+ */
+#if !defined(KINETIS_NO_INIT) || defined(__DOXYGEN__)
+#define KINETIS_NO_INIT FALSE
+#endif
+
+/**
+ * @brief MCG mode selection.
+ */
+#if !defined(KINETIS_MCG_MODE) || defined(__DOXYGEN__)
+#define KINETIS_MCG_MODE KINETIS_MCG_MODE_PEE
+#endif
+
+/**
+ * @brief MCU PLL clock frequency.
+ */
+#if !defined(KINETIS_PLLCLK_FREQUENCY) || defined(__DOXYGEN__)
+#define KINETIS_PLLCLK_FREQUENCY 96000000UL
+#endif
+
+/**
+ * @brief Clock divider for core/system clocks (OUTDIV1).
+ * @note The allowed range is 1..16
+ * @note The default value is calculated for a 48 MHz system clock
+ * from a 96 MHz PLL output.
+ */
+#if !defined(KINETIS_CLKDIV1_OUTDIV1) || defined(__DOXYGEN__)
+ #if defined(KINETIS_SYSCLK_FREQUENCY) && KINETIS_SYSCLK_FREQUENCY > 0
+ #define KINETIS_CLKDIV1_OUTDIV1 (KINETIS_PLLCLK_FREQUENCY/KINETIS_SYSCLK_FREQUENCY)
+ #else
+ #define KINETIS_CLKDIV1_OUTDIV1 2
+ #endif
+#endif
+
+/**
+ * @brief Clock divider for bus clock (OUTDIV2).
+ * @note The allowed range is 1..16
+ * @note The default value is calculated for a 48 MHz bus clock
+ * from a 96 MHz PLL output.
+ */
+#if !defined(KINETIS_CLKDIV1_OUTDIV2) || defined(__DOXYGEN__)
+ #if defined(KINETIS_BUSCLK_FREQUENCY) && KINETIS_BUSCLK_FREQUENCY > 0
+ #define KINETIS_CLKDIV1_OUTDIV2 (KINETIS_PLLCLK_FREQUENCY/KINETIS_BUSCLK_FREQUENCY)
+ #elif defined(KINETIS_SYSCLK_FREQUENCY) && KINETIS_SYSCLK_FREQUENCY > 0
+ #define KINETIS_CLKDIV1_OUTDIV2 KINETIS_CLKDIV1_OUTDIV1
+ #else
+ #define KINETIS_CLKDIV1_OUTDIV2 2
+ #endif
+#endif
+
+/**
+ * @brief Clock divider for flash clock (OUTDIV4).
+ * @note The allowed range is 1..16
+ * @note The default value is calculated for a 24 MHz flash clock
+ * from a 96 MHz PLL output
+ */
+#if !defined(KINETIS_CLKDIV1_OUTDIV4) || defined(__DOXYGEN__)
+ #if defined(KINETIS_FLASHCLK_FREQUENCY) && KINETIS_FLASHCLK_FREQUENCY > 0
+ #define KINETIS_CLKDIV1_OUTDIV4 (KINETIS_PLLCLK_FREQUENCY/KINETIS_FLASHCLK_FREQUENCY)
+ #elif defined(KINETIS_SYSCLK_FREQUENCY) && KINETIS_SYSCLK_FREQUENCY > 0
+ #define KINETIS_CLKDIV1_OUTDIV4 (KINETIS_CLKDIV1_OUTDIV1*2)
+ #else
+ #define KINETIS_CLKDIV1_OUTDIV4 4
+ #endif
+#endif
+
+/**
+ * @brief FLL DCO tuning enable for 32.768 kHz reference.
+ * @note Set to 1 for fine-tuning DCO for maximum frequency with
+ * a 32.768 kHz reference.
+ * @note The default value is for a 32.768 kHz external crystal.
+ */
+#if !defined(KINETIS_MCG_FLL_DMX32) || defined(__DOXYGEN__)
+#define KINETIS_MCG_FLL_DMX32 1
+#endif
+
+/**
+ * @brief FLL DCO range selection.
+ * @note The allowed range is 0...3.
+ * @note The default value is calculated for 48 MHz FLL output
+ * from a 32.768 kHz external crystal.
+ * (DMX32 && DRST_DRS=1 => F=1464; 32.768 kHz * F ~= 48 MHz.)
+ *
+ */
+#if !defined(KINETIS_MCG_FLL_DRS) || defined(__DOXYGEN__)
+#define KINETIS_MCG_FLL_DRS 2
+#endif
+
+/**
+ * @brief MCU system/core clock frequency.
+ */
+#if !defined(KINETIS_SYSCLK_FREQUENCY) || defined(__DOXYGEN__)
+#define KINETIS_SYSCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV1)
+#endif
+
+/**
+ * @brief MCU bus clock frequency.
+ */
+#if !defined(KINETIS_BUSCLK_FREQUENCY) || defined(__DOXYGEN__)
+#define KINETIS_BUSCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV2)
+#endif
+
+/**
+ * @brief MCU flash clock frequency.
+ */
+#if !defined(KINETIS_FLASHCLK_FREQUENCY) || defined(__DOXYGEN__)
+#define KINETIS_FLASHCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV4)
+#endif
+
+/** @} */
+
+/*===========================================================================*/
+/* Derived constants and error checks. */
+/*===========================================================================*/
+
+#if !defined(KINETIS_SYSCLK_FREQUENCY)
+ #error KINETIS_SYSCLK_FREQUENCY must be defined
+#endif
+
+#if KINETIS_SYSCLK_FREQUENCY <= 0 || KINETIS_SYSCLK_FREQUENCY > KINETIS_SYSCLK_MAX
+ #error KINETIS_SYSCLK_FREQUENCY out of range
+#endif
+
+#if !defined(KINETIS_BUSCLK_FREQUENCY)
+ #error KINETIS_BUSCLK_FREQUENCY must be defined
+#endif
+
+#if KINETIS_BUSCLK_FREQUENCY <= 0 || KINETIS_BUSCLK_FREQUENCY > KINETIS_BUSCLK_MAX
+ #error KINETIS_BUSCLK_FREQUENCY out of range
+#endif
+
+#if KINETIS_BUSCLK_FREQUENCY > KINETIS_SYSCLK_FREQUENCY
+ #error KINETIS_BUSCLK_FREQUENCY must be an integer divide of\
+ KINETIS_SYSCLK_FREQUENCY
+#endif
+
+#if !defined(KINETIS_FLASHCLK_FREQUENCY)
+ #error KINETIS_FLASHCLK_FREQUENCY must be defined
+#endif
+
+#if KINETIS_FLASHCLK_FREQUENCY <= 0 || KINETIS_FLASHCLK_FREQUENCY > KINETIS_FLASHCLK_MAX
+ #error KINETIS_FLASHCLK_FREQUENCY out of range
+#endif
+
+#if KINETIS_FLASHCLK_FREQUENCY > KINETIS_SYSCLK_FREQUENCY
+ #error KINETIS_FLASHCLK_FREQUENCY must be an integer divide of\
+ KINETIS_SYSCLK_FREQUENCY
+#endif
+
+#if !(defined(KINETIS_CLKDIV1_OUTDIV1) && \
+ KINETIS_CLKDIV1_OUTDIV1 >= 1 && KINETIS_CLKDIV1_OUTDIV1 <= 16)
+ #error KINETIS_CLKDIV1_OUTDIV1 must be 1 through 16
+#endif
+
+#if !(defined(KINETIS_CLKDIV1_OUTDIV2) && \
+ KINETIS_CLKDIV1_OUTDIV2 >= 1 && KINETIS_CLKDIV1_OUTDIV2 <= 16)
+#error KINETIS_CLKDIV1_OUTDIV2 must be 1 through 16
+#endif
+
+#if !(defined(KINETIS_CLKDIV1_OUTDIV4) && \
+ KINETIS_CLKDIV1_OUTDIV4 >= 1 && KINETIS_CLKDIV1_OUTDIV4 <= 16)
+#error KINETIS_CLKDIV1_OUTDIV4 must be 1 through 16
+#endif
+
+#if !(KINETIS_MCG_FLL_DMX32 == 0 || KINETIS_MCG_FLL_DMX32 == 1)
+#error Invalid KINETIS_MCG_FLL_DMX32 value, must be 0 or 1
+#endif
+
+#if !(0 <= KINETIS_MCG_FLL_DRS && KINETIS_MCG_FLL_DRS <= 3)
+#error Invalid KINETIS_MCG_FLL_DRS value, must be 0...3
+#endif
+
+/*===========================================================================*/
+/* Driver data structures and types. */
+/*===========================================================================*/
+
+/**
+ * @brief Type representing a system clock frequency.
+ */
+typedef uint32_t halclock_t;
+
+/**
+ * @brief Type of the realtime free counter value.
+ */
+typedef uint32_t halrtcnt_t;
+
+/*===========================================================================*/
+/* Driver macros. */
+/*===========================================================================*/
+
+/**
+ * @brief Returns the current value of the system free running counter.
+ * @note This service is implemented by returning the content of the
+ * DWT_CYCCNT register.
+ *
+ * @return The value of the system free running counter of
+ * type halrtcnt_t.
+ *
+ * @notapi
+ */
+#define hal_lld_get_counter_value() 0
+
+/**
+ * @brief Realtime counter frequency.
+ * @note The DWT_CYCCNT register is incremented directly by the system
+ * clock so this function returns STM32_HCLK.
+ *
+ * @return The realtime counter frequency of type halclock_t.
+ *
+ * @notapi
+ */
+#define hal_lld_get_counter_frequency() 0
+
+/*===========================================================================*/
+/* External declarations. */
+/*===========================================================================*/
+
+#include "nvic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+ void hal_lld_init(void);
+ void k60x_clock_init(void);
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HAL_LLD_H_ */
+
+/** @} */
diff --git a/os/hal/ports/KINETIS/K60x/kinetis_registry.h b/os/hal/ports/KINETIS/K60x/kinetis_registry.h
new file mode 100644
index 0000000..e595c35
--- /dev/null
+++ b/os/hal/ports/KINETIS/K60x/kinetis_registry.h
@@ -0,0 +1,198 @@
+/*
+ ChibiOS - Copyright (C) 2014 Derek Mulcahy
+ (C) 2016 flabbergast <s3+flabbergast@sdfeu.org>
+ (C) 2017 Wim Lewis
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+/**
+ * @file K60x/kinetis_registry.h
+ * @brief K60x capabilities registry.
+ *
+ * @addtogroup HAL
+ * @{
+ */
+
+#ifndef KINETIS_REGISTRY_H_
+#define KINETIS_REGISTRY_H_
+
+#if !defined(K60x) || defined(__DOXYGEN__)
+#define K60x /* Processor family */
+#endif
+
+#if defined(K64FX512) || defined(K64FN1M0) || defined(__DOXYGEN__)
+#define K64F /* Sub-family */
+#else
+#error "Unknown processor sub-family"
+#endif
+
+/*===========================================================================*/
+/* Platform capabilities. */
+/*===========================================================================*/
+
+/**
+ * @name K60x capabilities
+ * @{
+ */
+/*===========================================================================*/
+/* K64F */
+/*===========================================================================*/
+#if defined(K64F) || defined(__DOXYGEN__)
+
+/**
+ * @brief Maximum system and core clock (f_SYS) frequency.
+ */
+#define KINETIS_SYSCLK_MAX 120000000L
+
+/**
+ * @brief Maximum bus clock (f_BUS) frequency.
+ */
+#define KINETIS_BUSCLK_MAX 60000000L
+
+/**
+ * @brief Maximum flash clock (f_FLASH) frequency.
+ */
+#define KINETIS_FLASHCLK_MAX 25000000L
+
+/* ADC attributes.*/
+#define KINETIS_HAS_ADC0 TRUE
+#define KINETIS_ADC0_IRQ_VECTOR VectorDC
+#define KINETIS_HAS_ADC1 TRUE
+#define KINETIS_ADC1_IRQ_VECTOR Vector164
+
+/* DAC attributes.*/
+#define KINETIS_HAS_DAC0 TRUE
+#define KINETIS_DAC0_IRQ_VECTOR Vector120
+#define KINETIS_HAS_DAC1 TRUE
+#define KINETIS_DAC1_IRQ_VECTOR Vector160
+
+/* DMA attributes.*/
+#define KINETIS_DMA0_IRQ_VECTOR Vector40
+#define KINETIS_DMA1_IRQ_VECTOR Vector44
+#define KINETIS_DMA2_IRQ_VECTOR Vector48
+#define KINETIS_DMA3_IRQ_VECTOR Vector4C
+#define KINETIS_DMA4_IRQ_VECTOR Vector50
+#define KINETIS_DMA5_IRQ_VECTOR Vector54
+#define KINETIS_DMA6_IRQ_VECTOR Vector58
+#define KINETIS_DMA7_IRQ_VECTOR Vector5C
+#define KINETIS_DMA8_IRQ_VECTOR Vector60
+#define KINETIS_DMA9_IRQ_VECTOR Vector64
+#define KINETIS_DMA10_IRQ_VECTOR Vector68
+#define KINETIS_DMA11_IRQ_VECTOR Vector6C
+#define KINETIS_DMA12_IRQ_VECTOR Vector70
+#define KINETIS_DMA13_IRQ_VECTOR Vector74
+#define KINETIS_DMA14_IRQ_VECTOR Vector78
+#define KINETIS_DMA15_IRQ_VECTOR Vector7C
+#define KINETIS_HAS_DMA_ERROR_IRQ TRUE
+#define KINETIS_DMA_ERROR_IRQ_VECTOR Vector80
+
+/* EXT attributes.*/
+#define KINETIS_PORTA_IRQ_VECTOR Vector12C
+#define KINETIS_PORTB_IRQ_VECTOR Vector130
+#define KINETIS_PORTC_IRQ_VECTOR Vector134
+#define KINETIS_PORTD_IRQ_VECTOR Vector138
+#define KINETIS_PORTE_IRQ_VECTOR Vector13C
+#define KINETIS_EXT_HAS_COMMON_CD_IRQ FALSE
+#define KINETIS_EXT_HAS_COMMON_BCDE_IRQ FALSE
+#define KINETIS_GPIO_HAS_OPENDRAIN TRUE
+
+/* I2C attributes.*/
+#define KINETIS_HAS_I2C0 TRUE
+#define KINETIS_I2C0_IRQ_VECTOR VectorA0
+#define KINETIS_HAS_I2C1 TRUE
+#define KINETIS_I2C1_IRQ_VECTOR VectorA4
+#define KINETIS_HAS_I2C2 TRUE
+#define KINETIS_I2C2_IRQ_VECTOR Vector168
+
+/* Serial attributes.*/
+#define KINETIS_HAS_SERIAL0 TRUE
+#define KINETIS_SERIAL0_IRQ_VECTOR VectorBC
+#define KINETIS_SERIAL0_ERROR_IRQ_VECTOR VectorC0
+#define KINETIS_SERIAL0_IS_LPUART FALSE
+#define KINETIS_SERIAL0_IS_UARTLP FALSE
+
+#define KINETIS_HAS_SERIAL1 TRUE
+#define KINETIS_SERIAL1_IRQ_VECTOR VectorC4
+#define KINETIS_SERIAL1_ERROR_IRQ_VECTOR VectorC8
+#define KINETIS_SERIAL1_IS_LPUART FALSE
+
+#define KINETIS_HAS_SERIAL2 TRUE
+#define KINETIS_SERIAL2_IRQ_VECTOR VectorCC
+#define KINETIS_SERIAL2_ERROR_IRQ_VECTOR VectorD0
+
+#define KINETIS_HAS_SERIAL3 TRUE
+#define KINETIS_SERIAL3_IRQ_VECTOR VectorD4
+#define KINETIS_SERIAL3_ERROR_IRQ_VECTOR VectorD8
+
+#define KINETIS_HAS_SERIAL4 TRUE
+#define KINETIS_SERIAL4_IRQ_VECTOR Vector148
+#define KINETIS_SERIAL4_ERROR_IRQ_VECTOR Vector14C
+
+#define KINETIS_HAS_SERIAL5 TRUE
+#define KINETIS_SERIAL5_IRQ_VECTOR Vector150
+#define KINETIS_SERIAL5_ERROR_IRQ_VECTOR Vector154
+
+#define KINETIS_HAS_SERIAL_ERROR_IRQ TRUE
+
+/* SPI attributes.*/
+#define KINETIS_HAS_SPI0 TRUE
+#define KINETIS_SPI0_IRQ_VECTOR VectorA8
+#define KINETIS_HAS_SPI1 TRUE
+#define KINETIS_SPI1_IRQ_VECTOR VectorAC
+#define KINETIS_HAS_SPI2 TRUE
+#define KINETIS_SPI2_IRQ_VECTOR Vector144
+
+/* FlexTimer attributes.*/
+#define KINETIS_FTM0_CHANNELS 8
+#define KINETIS_FTM1_CHANNELS 2
+#define KINETIS_FTM2_CHANNELS 2
+#define KINETIS_FTM3_CHANNELS 8
+
+#define KINETIS_FTM0_IRQ_VECTOR VectorE8
+#define KINETIS_FTM1_IRQ_VECTOR VectorEC
+#define KINETIS_FTM2_IRQ_VECTOR VectorF0
+#define KINETIS_HAS_FTM2 TRUE
+#define KINETIS_FTM3_IRQ_VECTOR Vector15C
+#define KINETIS_HAS_FTM3 TRUE
+
+/* GPT attributes.*/
+#define KINETIS_HAS_PIT0 TRUE
+#define KINETIS_PIT0_IRQ_VECTOR Vector100
+#define KINETIS_HAS_PIT1 TRUE
+#define KINETIS_PIT1_IRQ_VECTOR Vector104
+#define KINETIS_HAS_PIT2 TRUE
+#define KINETIS_PIT2_IRQ_VECTOR Vector108
+#define KINETIS_HAS_PIT3 TRUE
+#define KINETIS_PIT3_IRQ_VECTOR Vector10C
+#define KINETIS_HAS_PIT_COMMON_IRQ FALSE
+
+/* USB attributes.*/
+#define KINETIS_HAS_USB TRUE
+#define KINETIS_USB_IRQ_VECTOR Vector114
+#define KINETIS_USB0_IS_USBOTG TRUE
+#define KINETIS_HAS_USB_CLOCK_RECOVERY TRUE
+
+/* SDHC (SDC, MMC, SDIO) attributes */
+#define KINETIS_HAS_SDHC TRUE
+#define KINETIS_SDHC_IRQ_VECTOR Vector184
+
+/* LPTMR attributes.*/
+#define KINETIS_LPTMR0_IRQ_VECTOR Vector128
+
+#endif
+/** @} */
+
+#endif /* KINETIS_REGISTRY_H_ */
+
+/** @} */
diff --git a/os/hal/ports/KINETIS/K60x/platform.mk b/os/hal/ports/KINETIS/K60x/platform.mk
new file mode 100644
index 0000000..33ac2cc
--- /dev/null
+++ b/os/hal/ports/KINETIS/K60x/platform.mk
@@ -0,0 +1,19 @@
+# List of all platform files.
+PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K60x/hal_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_pal_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_serial_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_ext_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_gpt_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_st_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_sdc_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_i2c_lld.c \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_adc_lld.c \
+# ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K60x/hal_spi_lld.c \
+# ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K60x/hal_pwm_lld.c \
+# ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/hal_usb_lld.c
+
+# Required include directories
+PLATFORMINC = ${CHIBIOS}/os/hal/ports/common/ARMCMx \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K60x \
+ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD