From d5a880807b47188aa5d721f4aff491bc46c6f186 Mon Sep 17 00:00:00 2001 From: flabbergast Date: Tue, 22 Mar 2016 17:51:46 +0000 Subject: [KINETIS] HAL cleanup/update. New entries in kinetis_registry.h to support new MCUs. Moved registers to ext/CMSIS, like it is done for STM32. Move the same drivers to LLD. Add USB driver. --- os/hal/ports/KINETIS/K20x/gpt_lld.c | 372 ---- os/hal/ports/KINETIS/K20x/gpt_lld.h | 292 ---- os/hal/ports/KINETIS/K20x/hal_lld.c | 82 +- os/hal/ports/KINETIS/K20x/hal_lld.h | 137 +- os/hal/ports/KINETIS/K20x/kinetis_registry.h | 216 ++- os/hal/ports/KINETIS/K20x/mk20d5.h | 2394 -------------------------- os/hal/ports/KINETIS/K20x/pal_lld.c | 241 --- os/hal/ports/KINETIS/K20x/pal_lld.h | 375 ---- os/hal/ports/KINETIS/K20x/platform.mk | 10 +- os/hal/ports/KINETIS/K20x/pwm_lld.c | 390 +++++ os/hal/ports/KINETIS/K20x/pwm_lld.h | 270 +++ os/hal/ports/KINETIS/K20x/serial_lld.c | 327 ---- os/hal/ports/KINETIS/K20x/serial_lld.h | 163 -- os/hal/ports/KINETIS/K20x/spi_lld.c | 133 +- os/hal/ports/KINETIS/K20x/spi_lld.h | 37 +- os/hal/ports/KINETIS/K20x/st_lld.c | 98 -- os/hal/ports/KINETIS/K20x/st_lld.h | 156 -- 17 files changed, 1176 insertions(+), 4517 deletions(-) delete mode 100644 os/hal/ports/KINETIS/K20x/gpt_lld.c delete mode 100644 os/hal/ports/KINETIS/K20x/gpt_lld.h delete mode 100644 os/hal/ports/KINETIS/K20x/mk20d5.h delete mode 100644 os/hal/ports/KINETIS/K20x/pal_lld.c delete mode 100644 os/hal/ports/KINETIS/K20x/pal_lld.h create mode 100644 os/hal/ports/KINETIS/K20x/pwm_lld.c create mode 100644 os/hal/ports/KINETIS/K20x/pwm_lld.h delete mode 100644 os/hal/ports/KINETIS/K20x/serial_lld.c delete mode 100644 os/hal/ports/KINETIS/K20x/serial_lld.h delete mode 100644 os/hal/ports/KINETIS/K20x/st_lld.c delete mode 100644 os/hal/ports/KINETIS/K20x/st_lld.h (limited to 'os/hal/ports/KINETIS/K20x') diff --git a/os/hal/ports/KINETIS/K20x/gpt_lld.c b/os/hal/ports/KINETIS/K20x/gpt_lld.c deleted file mode 100644 index 09d759b..0000000 --- a/os/hal/ports/KINETIS/K20x/gpt_lld.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - ChibiOS - Copyright (C) 2014 Derek Mulcahy - - 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 KINETIS/gpt_lld.c - * @brief KINETIS GPT subsystem low level driver source. - * - * @addtogroup GPT - * @{ - */ - -#include "hal.h" - -#if HAL_USE_GPT || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -#define KINETIS_PIT0_HANDLER VectorB8 -#define KINETIS_PIT1_HANDLER VectorBC -#define KINETIS_PIT2_HANDLER VectorC0 -#define KINETIS_PIT3_HANDLER VectorC4 - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief GPTD1 driver identifier. - * @note The driver GPTD1 allocates the complex timer PIT0 when enabled. - */ -#if KINETIS_GPT_USE_PIT0 || defined(__DOXYGEN__) -GPTDriver GPTD1; -#endif - -/** - * @brief GPTD2 driver identifier. - * @note The driver GPTD2 allocates the timer PIT1 when enabled. - */ -#if KINETIS_GPT_USE_PIT1 || defined(__DOXYGEN__) -GPTDriver GPTD2; -#endif - -/** - * @brief GPTD3 driver identifier. - * @note The driver GPTD3 allocates the timer PIT2 when enabled. - */ -#if KINETIS_GPT_USE_PIT2 || defined(__DOXYGEN__) -GPTDriver GPTD3; -#endif - -/** - * @brief GPTD4 driver identifier. - * @note The driver GPTD4 allocates the timer PIT3 when enabled. - */ -#if KINETIS_GPT_USE_PIT3 || defined(__DOXYGEN__) -GPTDriver GPTD4; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Shared IRQ handler. - * - * @param[in] gptp pointer to a @p GPTDriver object - */ -static void gpt_lld_serve_interrupt(GPTDriver *gptp) { - - /* Clear the interrupt */ - gptp->channel->TFLG |= PIT_TCTRL_TIE; - - if (gptp->state == GPT_ONESHOT) { - gptp->state = GPT_READY; /* Back in GPT_READY state. */ - gpt_lld_stop_timer(gptp); /* Timer automatically stopped. */ - } - gptp->config->callback(gptp); -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if KINETIS_GPT_USE_PIT0 -#if !defined(KINETIS_PIT0_HANDLER) -#error "KINETIS_PIT0_HANDLER not defined" -#endif -/** - * @brief PIT1 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(KINETIS_PIT0_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD1); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* KINETIS_GPT_USE_PIT0 */ - -#if KINETIS_GPT_USE_PIT1 -#if !defined(KINETIS_PIT1_HANDLER) -#error "KINETIS_PIT1_HANDLER not defined" -#endif -/** - * @brief PIT1 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(KINETIS_PIT1_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD2); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* KINETIS_GPT_USE_PIT1 */ - -#if KINETIS_GPT_USE_PIT2 -#if !defined(KINETIS_PIT2_HANDLER) -#error "KINETIS_PIT2_HANDLER not defined" -#endif -/** - * @brief PIT2 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(KINETIS_PIT2_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD3); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* KINETIS_GPT_USE_PIT2 */ - -#if KINETIS_GPT_USE_PIT3 -#if !defined(KINETIS_PIT3_HANDLER) -#error "KINETIS_PIT3_HANDLER not defined" -#endif -/** - * @brief PIT3 interrupt handler. - * - * @isr - */ -OSAL_IRQ_HANDLER(KINETIS_PIT3_HANDLER) { - - OSAL_IRQ_PROLOGUE(); - - gpt_lld_serve_interrupt(&GPTD4); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* KINETIS_GPT_USE_PIT3 */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level GPT driver initialization. - * - * @notapi - */ -void gpt_lld_init(void) { - -#if KINETIS_GPT_USE_PIT0 - /* Driver initialization.*/ - GPTD1.channel = &PIT->CHANNEL[0]; - gptObjectInit(&GPTD1); -#endif - -#if KINETIS_GPT_USE_PIT1 - /* Driver initialization.*/ - GPTD2.channel = &PIT->CHANNEL[1]; - gptObjectInit(&GPTD2); -#endif - -#if KINETIS_GPT_USE_PIT2 - /* Driver initialization.*/ - GPTD3.channel = &PIT->CHANNEL[2]; - gptObjectInit(&GPTD3); -#endif - -#if KINETIS_GPT_USE_PIT3 - /* Driver initialization.*/ - GPTD4.channel = &PIT->CHANNEL[3]; - gptObjectInit(&GPTD4); -#endif -} - -/** - * @brief Configures and activates the GPT peripheral. - * - * @param[in] gptp pointer to the @p GPTDriver object - * - * @notapi - */ -void gpt_lld_start(GPTDriver *gptp) { - uint16_t psc; - - if (gptp->state == GPT_STOP) { - /* Clock activation.*/ - SIM->SCGC6 |= SIM_SCGC6_PIT; - gptp->clock = KINETIS_SYSCLK_FREQUENCY; - -#if KINETIS_GPT_USE_PIT0 - if (&GPTD1 == gptp) { - nvicEnableVector(PITChannel0_IRQn, KINETIS_GPT_PIT0_IRQ_PRIORITY); - } -#endif -#if KINETIS_GPT_USE_PIT1 - if (&GPTD2 == gptp) { - nvicEnableVector(PITChannel1_IRQn, KINETIS_GPT_PIT1_IRQ_PRIORITY); - } -#endif -#if KINETIS_GPT_USE_PIT2 - if (&GPTD3 == gptp) { - nvicEnableVector(PITChannel2_IRQn, KINETIS_GPT_PIT2_IRQ_PRIORITY); - } -#endif -#if KINETIS_GPT_USE_PIT3 - if (&GPTD4 == gptp) { - nvicEnableVector(PITChannel3_IRQn, KINETIS_GPT_PIT3_IRQ_PRIORITY); - } -#endif - - } - - /* Prescaler value calculation.*/ - psc = (uint16_t)((gptp->clock / gptp->config->frequency) - 1); - osalDbgAssert(((uint32_t)(psc + 1) * gptp->config->frequency) == gptp->clock, - "invalid frequency"); - - /* Enable the PIT */ - PIT->MCR = 0; -} - -/** - * @brief Deactivates the GPT peripheral. - * - * @param[in] gptp pointer to the @p GPTDriver object - * - * @notapi - */ -void gpt_lld_stop(GPTDriver *gptp) { - - if (gptp->state == GPT_READY) { - SIM->SCGC6 &= ~SIM_SCGC6_PIT; - - /* Disable the channel */ - gptp->channel->TCTRL = 0; - - /* Clear pending interrupts */ - gptp->channel->TFLG |= PIT_TFLG_TIF; - -#if KINETIS_GPT_USE_PIT0 - if (&GPTD1 == gptp) { - nvicDisableVector(PITChannel0_IRQn); - } -#endif -#if KINETIS_GPT_USE_PIT1 - if (&GPTD2 == gptp) { - nvicDisableVector(PITChannel1_IRQn); - } -#endif -#if KINETIS_GPT_USE_PIT2 - if (&GPTD3 == gptp) { - nvicDisableVector(PITChannel2_IRQn); - } -#endif -#if KINETIS_GPT_USE_PIT3 - if (&GPTD4 == gptp) { - nvicDisableVector(PITChannel3_IRQn); - } -#endif - } -} - -/** - * @brief Starts the timer in continuous mode. - * - * @param[in] gptp pointer to the @p GPTDriver object - * @param[in] interval period in ticks - * - * @notapi - */ -void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t interval) { - - /* Clear pending interrupts */ - gptp->channel->TFLG |= PIT_TFLG_TIF; - - /* Set the interval */ - gptp->channel->LDVAL = (gptp->clock / gptp->config->frequency) * interval; - - /* Start the timer */ - gptp->channel->TCTRL |= PIT_TCTRL_TIE | PIT_TCTRL_TEN; -} - -/** - * @brief Stops the timer. - * - * @param[in] gptp pointer to the @p GPTDriver object - * - * @notapi - */ -void gpt_lld_stop_timer(GPTDriver *gptp) { - - /* Stop the timer */ - gptp->channel->TCTRL = 0; -} - -/** - * @brief Starts the timer in one shot mode and waits for completion. - * @details This function specifically polls the timer waiting for completion - * in order to not have extra delays caused by interrupt servicing, - * this function is only recommended for short delays. - * - * @param[in] gptp pointer to the @p GPTDriver object - * @param[in] interval time interval in ticks - * - * @notapi - */ -void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval) { - struct PIT_CHANNEL *channel = gptp->channel; - - /* Disable timer and disable interrupts */ - channel->TCTRL = 0; - - /* Clear the interrupt flag */ - channel->TFLG |= PIT_TFLG_TIF; - - /* Set the interval */ - channel->LDVAL = (gptp->clock / gptp->config->frequency) * interval; - - /* Enable Timer but keep interrupts disabled */ - channel->TCTRL = PIT_TCTRL_TEN; - - /* Wait for the interrupt flag to be set */ - while (!(channel->TFLG & PIT_TFLG_TIF)) - ; - - /* Disable timer and disable interrupts */ - channel->TCTRL = 0; -} - -#endif /* HAL_USE_GPT */ - -/** @} */ diff --git a/os/hal/ports/KINETIS/K20x/gpt_lld.h b/os/hal/ports/KINETIS/K20x/gpt_lld.h deleted file mode 100644 index 0e72309..0000000 --- a/os/hal/ports/KINETIS/K20x/gpt_lld.h +++ /dev/null @@ -1,292 +0,0 @@ -/* - ChibiOS - Copyright (C) 2014 Derek Mulcahy - - 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 KINETIS/gpt_lld.h - * @brief KINETIS GPT subsystem low level driver header. - * - * @addtogroup GPT - * @{ - */ - -#ifndef _GPT_LLD_H_ -#define _GPT_LLD_H_ - -#if HAL_USE_GPT || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief GPTD1 driver enable switch. - * @details If set to @p TRUE the support for GPTD1 is included. - * @note The default is @p TRUE. - */ -#if !defined(KINETIS_GPT_USE_PIT0) || defined(__DOXYGEN__) -#define KINETIS_GPT_USE_PIT0 FALSE -#endif - -/** - * @brief GPTD2 driver enable switch. - * @details If set to @p TRUE the support for GPTD2 is included. - * @note The default is @p TRUE. - */ -#if !defined(KINETIS_GPT_USE_PIT1) || defined(__DOXYGEN__) -#define KINETIS_GPT_USE_PIT1 FALSE -#endif - -/** - * @brief GPTD3 driver enable switch. - * @details If set to @p TRUE the support for GPTD3 is included. - * @note The default is @p TRUE. - */ -#if !defined(KINETIS_GPT_USE_PIT2) || defined(__DOXYGEN__) -#define KINETIS_GPT_USE_PIT2 FALSE -#endif - -/** - * @brief GPTD4 driver enable switch. - * @details If set to @p TRUE the support for GPTD4 is included. - * @note The default is @p TRUE. - */ -#if !defined(KINETIS_GPT_USE_PIT3) || defined(__DOXYGEN__) -#define KINETIS_GPT_USE_PIT3 FALSE -#endif - -/** - * @brief GPTD1 interrupt priority level setting. - */ -#if !defined(KINETIS_GPT_PIT0_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define KINETIS_GPT_PIT0_IRQ_PRIORITY 7 -#endif - -/** - * @brief GPTD2 interrupt priority level setting. - */ -#if !defined(KINETIS_GPT_PIT1_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define KINETIS_GPT_PIT1_IRQ_PRIORITY 7 -#endif - -/** - * @brief GPTD3 interrupt priority level setting. - */ -#if !defined(KINETIS_GPT_PIT2_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define KINETIS_GPT_PIT2_IRQ_PRIORITY 7 -#endif - -/** - * @brief GPTD4 interrupt priority level setting. - */ -#if !defined(KINETIS_GPT_PIT3_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define KINETIS_GPT_PIT3_IRQ_PRIORITY 7 -#endif - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -#if KINETIS_GPT_USE_PIT0 && !KINETIS_HAS_PIT0 -#error "PIT0 not present in the selected device" -#endif - -#if KINETIS_GPT_USE_PIT1 && !KINETIS_HAS_PIT1 -#error "PIT1 not present in the selected device" -#endif - -#if KINETIS_GPT_USE_PIT2 && !KINETIS_HAS_PIT2 -#error "PIT2 not present in the selected device" -#endif - -#if KINETIS_GPT_USE_PIT3 && !KINETIS_HAS_PIT3 -#error "PIT3 not present in the selected device" -#endif - -#if !KINETIS_GPT_USE_PIT0 && !KINETIS_GPT_USE_PIT1 && \ - !KINETIS_GPT_USE_PIT2 && !KINETIS_GPT_USE_PIT3 -#error "GPT driver activated but no PIT peripheral assigned" -#endif - -#if KINETIS_GPT_USE_PIT0 && \ - !OSAL_IRQ_IS_VALID_PRIORITY(KINETIS_GPT_PIT0_IRQ_PRIORITY) -#error "Invalid IRQ priority assigned to PIT0" -#endif - -#if KINETIS_GPT_USE_PIT1 && \ - !OSAL_IRQ_IS_VALID_PRIORITY(KINETIS_GPT_PIT1_IRQ_PRIORITY) -#error "Invalid IRQ priority assigned to PIT1" -#endif - -#if KINETIS_GPT_USE_PIT2 && \ - !OSAL_IRQ_IS_VALID_PRIORITY(KINETIS_GPT_PIT2_IRQ_PRIORITY) -#error "Invalid IRQ priority assigned to PIT2" -#endif - -#if KINETIS_GPT_USE_PIT3 && \ - !OSAL_IRQ_IS_VALID_PRIORITY(KINETIS_GPT_PIT3_IRQ_PRIORITY) -#error "Invalid IRQ priority assigned to PIT3" -#endif - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief GPT frequency type. - */ -typedef uint32_t gptfreq_t; - -/** - * @brief GPT counter type. - */ -typedef uint32_t gptcnt_t; - -/** - * @brief Driver configuration structure. - * @note It could be empty on some architectures. - */ -typedef struct { - /** - * @brief Timer clock in Hz. - * @note The low level can use assertions in order to catch invalid - * frequency specifications. - */ - gptfreq_t frequency; - /** - * @brief Timer callback pointer. - * @note This callback is invoked on GPT counter events. - * @note This callback can be set to @p NULL but in that case the - * one-shot mode cannot be used. - */ - gptcallback_t callback; - /* End of the mandatory fields.*/ -} GPTConfig; - -/** - * @brief Structure representing a GPT driver. - */ -struct GPTDriver { - /** - * @brief Driver state. - */ - gptstate_t state; - /** - * @brief Current configuration data. - */ - const GPTConfig *config; -#if defined(GPT_DRIVER_EXT_FIELDS) - GPT_DRIVER_EXT_FIELDS -#endif - /* End of the mandatory fields.*/ - /** - * @brief Timer base clock. - */ - uint32_t clock; - /** - * @brief Channel structure in PIT registers block. - */ - struct PIT_CHANNEL *channel; -}; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/** - * @brief Changes the interval of GPT peripheral. - * @details This function changes the interval of a running GPT unit. - * @pre The GPT unit must be running in continuous mode. - * @post The GPT unit interval is changed to the new value. - * @note The function has effect at the next cycle start. - * - * @param[in] gptp pointer to a @p GPTDriver object - * @param[in] interval new cycle time in timer ticks - * - * @notapi - */ -#define gpt_lld_change_interval(gptp, interval) \ - ((gptp)->channel->LDVAL = (uint32_t)((interval))) - -/** - * @brief Returns the interval of GPT peripheral. - * @pre The GPT unit must be running in continuous mode. - * - * @param[in] gptp pointer to a @p GPTDriver object - * @return The current interval. - * - * @notapi - */ -#define gpt_lld_get_interval(gptp) ((gptcnt_t)(gptp)->pit->CHANNEL[gptp->channel].LDVAL) - -/** - * @brief Returns the counter value of GPT peripheral. - * @pre The GPT unit must be running in continuous mode. - * @note The nature of the counter is not defined, it may count upward - * or downward, it could be continuously running or not. - * - * @param[in] gptp pointer to a @p GPTDriver object - * @return The current counter value. - * - * @notapi - */ -#define gpt_lld_get_counter(gptp) ((gptcnt_t)(gptp)->pit->CHANNEL[gptp->channel].CVAL) - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if KINETIS_GPT_USE_PIT0 && !defined(__DOXYGEN__) -extern GPTDriver GPTD1; -#endif - -#if KINETIS_GPT_USE_PIT1 && !defined(__DOXYGEN__) -extern GPTDriver GPTD2; -#endif - -#if KINETIS_GPT_USE_PIT2 && !defined(__DOXYGEN__) -extern GPTDriver GPTD3; -#endif - -#if KINETIS_GPT_USE_PIT3 && !defined(__DOXYGEN__) -extern GPTDriver GPTD4; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void gpt_lld_init(void); - void gpt_lld_start(GPTDriver *gptp); - void gpt_lld_stop(GPTDriver *gptp); - void gpt_lld_start_timer(GPTDriver *gptp, gptcnt_t period); - void gpt_lld_stop_timer(GPTDriver *gptp); - void gpt_lld_polled_delay(GPTDriver *gptp, gptcnt_t interval); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_GPT */ - -#endif /* _GPT_LLD_H_ */ - -/** @} */ diff --git a/os/hal/ports/KINETIS/K20x/hal_lld.c b/os/hal/ports/KINETIS/K20x/hal_lld.c index 1e10241..e6eeed8 100644 --- a/os/hal/ports/KINETIS/K20x/hal_lld.c +++ b/os/hal/ports/KINETIS/K20x/hal_lld.c @@ -39,7 +39,7 @@ #ifdef __CC_ARM __attribute__ ((section(".ARM.__at_0x400"))) #else -__attribute__ ((used, section(".cfmconfig"))) +__attribute__ ((used,section(".cfmconfig"))) #endif const uint8_t _cfm[0x10] = { 0xFF, /* NV_BACKKEY3: KEY=0xFF */ @@ -84,7 +84,7 @@ void hal_lld_init(void) { } /** - * @brief MK20D5 clock initialization. + * @brief K20x 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 @@ -93,16 +93,9 @@ void hal_lld_init(void) { * * @special */ -void mk20d50_clock_init(void) { +void k20x_clock_init(void) { #if !KINETIS_NO_INIT -#if KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE - uint32_t ratio, frdiv; - uint32_t ratios[] = { 32, 64, 128, 256, 512, 1024, 1280, 1536 }; - int ratio_quantity = sizeof(ratios) / sizeof(ratios[0]); - int i; -#endif /* KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE */ - /* Disable the watchdog */ WDOG->UNLOCK = 0xC520; WDOG->UNLOCK = 0xD928; @@ -115,14 +108,24 @@ void mk20d50_clock_init(void) { 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); -#endif /* KINETIS_MCG_MODE == KINETIS_MCG_MODE_FEI */ + /* 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 */ -#if KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE +#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; @@ -132,8 +135,13 @@ void mk20d50_clock_init(void) { * Start in FEI mode */ - /* Disable capacitors for crystal */ - OSC->CR = 0; + /* 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 @@ -141,13 +149,13 @@ void mk20d50_clock_init(void) { */ /* Enable OSC, low power mode */ MCG->C2 = MCG_C2_LOCRE0 | MCG_C2_EREFS0; - if (KINETIS_XTAL_FREQUENCY > 8000000) + if (KINETIS_XTAL_FREQUENCY > 8000000UL) MCG->C2 |= MCG_C2_RANGE0(2); else MCG->C2 |= MCG_C2_RANGE0(1); frdiv = 7; - ratio = KINETIS_XTAL_FREQUENCY / 31250; + ratio = KINETIS_XTAL_FREQUENCY / 31250UL; for (i = 0; i < ratio_quantity; ++i) { if (ratio == ratios[i]) { frdiv = i; @@ -170,22 +178,42 @@ void mk20d50_clock_init(void) { /* * 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 input for 2 MHz */ - MCG->C5 = MCG_C5_PRDIV0((KINETIS_XTAL_FREQUENCY / 2000000) - 1); - - /* Config PLL for 96 MHz output */ - MCG->C6 = MCG_C6_PLLS | MCG_C6_VDIV0(0); + /* + * 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; + } + } - /* Wait for PLL to start using crystal as its input */ - while (!(MCG->S & MCG_S_PLLST)); + 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 lock */ - while (!(MCG->S & MCG_S_LOCK0)); + /* 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; /* Switch to PLL as clock source */ MCG->C1 = MCG_C1_CLKS(0); @@ -196,7 +224,9 @@ void mk20d50_clock_init(void) { /* * Now in PEE mode */ -#endif /* KINETIS_MCG_MODE == KINETIS_MCG_MODE_PEE */ +#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/K20x/hal_lld.h b/os/hal/ports/KINETIS/K20x/hal_lld.h index 3544797..31364cf 100644 --- a/os/hal/ports/KINETIS/K20x/hal_lld.h +++ b/os/hal/ports/KINETIS/K20x/hal_lld.h @@ -15,8 +15,8 @@ */ /** - * @file KL2x/hal_lld.h - * @brief Kinetis KL2x HAL subsystem low level driver header. + * @file K20x/hal_lld.h + * @brief Kinetis K20x HAL subsystem low level driver header. * * @addtogroup HAL * @{ @@ -25,7 +25,6 @@ #ifndef _HAL_LLD_H_ #define _HAL_LLD_H_ -#include "mk20d5.h" #include "kinetis_registry.h" /*===========================================================================*/ @@ -44,16 +43,6 @@ #define PLATFORM_NAME "Kinetis" /** @} */ -/** - * @brief Maximum system and core clock (f_SYS) frequency. - */ -#define KINETIS_SYSCLK_MAX 48000000 - -/** - * @brief Maximum bus clock (f_BUS) frequency. - */ -#define KINETIS_BUSCLK_MAX 24000000 - /** * @name Internal clock sources * @{ @@ -94,24 +83,56 @@ #endif /** - * @brief Clock divider for core/system and bus/flash clocks (OUTDIV1). - * @note The allowed range is 1...16. + * @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_MCG_FLL_OUTDIV1) || defined(__DOXYGEN__) -#define KINETIS_MCG_FLL_OUTDIV1 2 +#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 Additional clock divider bus/flash clocks (OUTDIV4). - * @note The allowed range is 1...8. - * @note This divider is on top of the OUTDIV1 divider. - * @note The default value is calculated for 24 MHz bus/flash clocks - * from a 96 MHz PLL output and 48 MHz core/system clock. + * @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_MCG_FLL_OUTDIV4) || defined(__DOXYGEN__) -#define KINETIS_MCG_FLL_OUTDIV4 2 +#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 /** @@ -140,32 +161,21 @@ * @brief MCU system/core clock frequency. */ #if !defined(KINETIS_SYSCLK_FREQUENCY) || defined(__DOXYGEN__) -#define KINETIS_SYSCLK_FREQUENCY 48000000UL +#define KINETIS_SYSCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV1) #endif /** - * @brief MCU bus/flash clock frequency. + * @brief MCU bus clock frequency. */ #if !defined(KINETIS_BUSCLK_FREQUENCY) || defined(__DOXYGEN__) -#define KINETIS_BUSCLK_FREQUENCY (KINETIS_SYSCLK_FREQUENCY / KINETIS_MCG_FLL_OUTDIV4) +#define KINETIS_BUSCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV2) #endif /** - * @brief UART0 clock frequency. - * @note The default value is based on 96 MHz PLL/2 source. - * If you use a different source, such as the FLL, - * you must set this properly. + * @brief MCU flash clock frequency. */ -#if !defined(KINETIS_UART0_CLOCK_FREQ) || defined(__DOXYGEN__) -#define KINETIS_UART0_CLOCK_FREQ KINETIS_SYSCLK_FREQUENCY -#endif - -/** - * @brief UART0 clock source. - * @note The default value is to use PLL/2 or FLL source. - */ -#if !defined(KINETIS_UART0_CLOCK_SRC) || defined(__DOXYGEN__) -#define KINETIS_UART0_CLOCK_SRC 1 +#if !defined(KINETIS_FLASHCLK_FREQUENCY) || defined(__DOXYGEN__) +#define KINETIS_FLASHCLK_FREQUENCY (KINETIS_PLLCLK_FREQUENCY / KINETIS_CLKDIV1_OUTDIV4) #endif /** @} */ @@ -175,29 +185,52 @@ /*===========================================================================*/ #if !defined(KINETIS_SYSCLK_FREQUENCY) -#error KINETIS_SYSCLK_FREQUENCY must be defined + #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 + #error KINETIS_SYSCLK_FREQUENCY out of range #endif #if !defined(KINETIS_BUSCLK_FREQUENCY) -#error KINETIS_BUSCLK_FREQUENCY must be defined + #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 + #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_MCG_FLL_OUTDIV1) && \ - KINETIS_MCG_FLL_OUTDIV1 >= 1 && KINETIS_MCG_FLL_OUTDIV1 <= 16) -#error KINETIS_MCG_FLL_OUTDIV1 must be 1 through 16 +#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_MCG_FLL_OUTDIV4) && \ - KINETIS_MCG_FLL_OUTDIV4 >= 1 && KINETIS_MCG_FLL_OUTDIV4 <= 8) -#error KINETIS_MCG_FLL_OUTDIV4 must be 1 through 8 +#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) @@ -259,7 +292,7 @@ typedef uint32_t halrtcnt_t; extern "C" { #endif void hal_lld_init(void); - void mk20d50_clock_init(void); + void k20x_clock_init(void); #ifdef __cplusplus } #endif diff --git a/os/hal/ports/KINETIS/K20x/kinetis_registry.h b/os/hal/ports/KINETIS/K20x/kinetis_registry.h index 024a424..4c70e84 100644 --- a/os/hal/ports/KINETIS/K20x/kinetis_registry.h +++ b/os/hal/ports/KINETIS/K20x/kinetis_registry.h @@ -1,5 +1,6 @@ /* ChibiOS - Copyright (C) 2014 Derek Mulcahy + (C) 2016 flabbergast Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,8 +16,8 @@ */ /** - * @file KL2x/kinetis_registry.h - * @brief KL2x capabilities registry. + * @file K20x/kinetis_registry.h + * @brief K20x capabilities registry. * * @addtogroup HAL * @{ @@ -25,31 +26,230 @@ #ifndef _KINETIS_REGISTRY_H_ #define _KINETIS_REGISTRY_H_ +#if !defined(K20x) || defined(__DOXYGEN__) +#define K20x +#endif + /*===========================================================================*/ /* Platform capabilities. */ /*===========================================================================*/ /** - * @name KL2x capabilities + * @name K20x capabilities * @{ */ -/* EXT attributes.*/ +/*===========================================================================*/ +/* K20x5 */ +/*===========================================================================*/ +#if defined(K20x5) || defined(__DOXYGEN__) + +/** + * @brief Maximum system and core clock (f_SYS) frequency. + */ +#define KINETIS_SYSCLK_MAX 50000000L + +/** + * @brief Maximum bus clock (f_BUS) frequency. + */ +#define KINETIS_BUSCLK_MAX 50000000L + +/** + * @brief Maximum flash clock (f_FLASH) frequency. + */ +#define KINETIS_FLASHCLK_MAX 25000000L + +/* ADC attributes.*/ +#define KINETIS_HAS_ADC0 TRUE +#define KINETIS_ADC0_IRQ_VECTOR Vector98 +#define KINETIS_HAS_ADC1 FALSE + +/* DAC attributes.*/ +#define KINETIS_HAS_DAC0 FALSE + +/* 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_HAS_DMA_ERROR_IRQ TRUE +#define KINETIS_DMA_ERROR_IRQ_VECTOR Vector50 +/* EXT attributes.*/ #define KINETIS_PORTA_IRQ_VECTOR VectorE0 #define KINETIS_PORTB_IRQ_VECTOR VectorE4 #define KINETIS_PORTC_IRQ_VECTOR VectorE8 #define KINETIS_PORTD_IRQ_VECTOR VectorEC #define KINETIS_PORTE_IRQ_VECTOR VectorF0 +#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 Vector6C +#define KINETIS_HAS_I2C1 FALSE + +/* Serial attributes.*/ +#define KINETIS_HAS_SERIAL0 TRUE +#define KINETIS_SERIAL0_IRQ_VECTOR Vector80 +#define KINETIS_HAS_SERIAL1 TRUE +#define KINETIS_SERIAL1_IRQ_VECTOR Vector88 +#define KINETIS_HAS_SERIAL2 TRUE +#define KINETIS_SERIAL2_IRQ_VECTOR Vector90 +#define KINETIS_HAS_SERIAL_ERROR_IRQ TRUE +#define KINETIS_SERIAL0_ERROR_IRQ_VECTOR Vector84 +#define KINETIS_SERIAL1_ERROR_IRQ_VECTOR Vector8C +#define KINETIS_SERIAL2_ERROR_IRQ_VECTOR Vector94 +#define KINETIS_SERIAL0_IS_LPUART FALSE +#define KINETIS_SERIAL0_IS_UARTLP FALSE +#define KINETIS_SERIAL1_IS_LPUART FALSE + +/* SPI attributes.*/ +#define KINETIS_HAS_SPI0 TRUE +#define KINETIS_SPI0_IRQ_VECTOR Vector70 +#define KINETIS_HAS_SPI1 FALSE + +/* FlexTimer attributes.*/ +#define KINETIS_FTM0_CHANNELS 8 +#define KINETIS_FTM1_CHANNELS 2 + +#define KINETIS_FTM0_IRQ_VECTOR VectorA4 +#define KINETIS_FTM1_IRQ_VECTOR VectorA8 +#define KINETIS_HAS_FTM2 FALSE + +/* GPT attributes.*/ +#define KINETIS_HAS_PIT0 TRUE +#define KINETIS_PIT0_IRQ_VECTOR VectorB8 +#define KINETIS_HAS_PIT1 TRUE +#define KINETIS_PIT1_IRQ_VECTOR VectorBC +#define KINETIS_HAS_PIT2 TRUE +#define KINETIS_PIT2_IRQ_VECTOR VectorC0 +#define KINETIS_HAS_PIT3 TRUE +#define KINETIS_PIT3_IRQ_VECTOR VectorC4 +#define KINETIS_HAS_PIT_COMMON_IRQ FALSE + +/* USB attributes.*/ +#define KINETIS_HAS_USB TRUE +#define KINETIS_USB_IRQ_VECTOR VectorCC +#define KINETIS_USB0_IS_USBOTG TRUE +#define KINETIS_HAS_USB_CLOCK_RECOVERY FALSE + +/* LPTMR attributes.*/ +#define KINETIS_LPTMR0_IRQ_VECTOR VectorDC + +/*===========================================================================*/ +/* K20x7 */ +/*===========================================================================*/ +#elif defined(K20x7) + +/** + * @brief Maximum system and core clock (f_SYS) frequency. + */ +#define KINETIS_SYSCLK_MAX 72000000L + +/** + * @brief Maximum bus clock (f_BUS) frequency. + */ +#define KINETIS_BUSCLK_MAX 50000000L + +/** + * @brief Maximum flash clock (f_FLASH) frequency. + */ +#define KINETIS_FLASHCLK_MAX 25000000L + +/** + * @name K20x7 attributes + * @{ + */ /* ADC attributes.*/ #define KINETIS_HAS_ADC0 TRUE -#define KINETIS_ADC0_IRQ_VECTOR Vector98 +#define KINETIS_ADC0_IRQ_VECTOR Vector124 +#define KINETIS_HAS_ADC1 TRUE +#define KINETIS_ADC1_IRQ_VECTOR Vector128 + +/* DAC attributes.*/ +#define KINETIS_HAS_DAC0 TRUE +#define KINTEIS_DAC0_IRQ_VECTOR Vector184 + +/* 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_HAS_DMA_ERROR_IRQ TRUE +#define KINETIS_DMA_ERROR_IRQ_VECTOR Vector50 + +/* EXT attributes.*/ +#define KINETIS_PORTA_IRQ_VECTOR Vector19C +#define KINETIS_PORTB_IRQ_VECTOR Vector1A0 +#define KINETIS_PORTC_IRQ_VECTOR Vector1A4 +#define KINETIS_PORTD_IRQ_VECTOR Vector1A8 +#define KINETIS_PORTE_IRQ_VECTOR Vector1AC +#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_I2C0_IRQ_VECTOR Vector6C +#define KINETIS_HAS_I2C0 TRUE +#define KINETIS_I2C0_IRQ_VECTOR VectorA0 +#define KINETIS_HAS_I2C1 TRUE +#define KINETIS_I2C1_IRQ_VECTOR VectorA4 -/* USB attributes */ -#define KINETIS_USB_IRQ_VECTOR VectorCC +/* Serial attributes.*/ +#define KINETIS_HAS_SERIAL0 TRUE +#define KINETIS_SERIAL0_IRQ_VECTOR VectorF4 +#define KINETIS_HAS_SERIAL1 TRUE +#define KINETIS_SERIAL1_IRQ_VECTOR VectorFC +#define KINETIS_HAS_SERIAL2 TRUE +#define KINETIS_SERIAL2_IRQ_VECTOR Vector104 +#define KINETIS_HAS_SERIAL_ERROR_IRQ TRUE +#define KINETIS_SERIAL0_ERROR_IRQ_VECTOR VectorF8 +#define KINETIS_SERIAL1_ERROR_IRQ_VECTOR Vector100 +#define KINETIS_SERIAL2_ERROR_IRQ_VECTOR Vector108 +#define KINETIS_SERIAL0_IS_LPUART FALSE +#define KINETIS_SERIAL0_IS_UARTLP FALSE +#define KINETIS_SERIAL1_IS_LPUART FALSE + +/* SPI attributes.*/ +#define KINETIS_HAS_SPI0 TRUE +#define KINETIS_SPI0_IRQ_VECTOR VectorA8 +#define KINETIS_HAS_SPI1 TRUE +#define KINETIS_SPI1_IRQ_VECTOR VectorAC + +/* FlexTimer attributes.*/ +#define KINETIS_FTM0_CHANNELS 8 +#define KINETIS_FTM1_CHANNELS 2 +#define KINETIS_FTM2_CHANNELS 2 + +#define KINETIS_FTM0_IRQ_VECTOR Vector138 +#define KINETIS_FTM1_IRQ_VECTOR Vector13C +#define KINETIS_HAS_FTM2 TRUE +#define KINETIS_FTM2_IRQ_VECTOR Vector140 + +/* GPT attributes.*/ +#define KINETIS_HAS_PIT0 TRUE +#define KINETIS_PIT0_IRQ_VECTOR Vector150 +#define KINETIS_HAS_PIT1 TRUE +#define KINETIS_PIT1_IRQ_VECTOR Vector154 +#define KINETIS_HAS_PIT2 TRUE +#define KINETIS_PIT2_IRQ_VECTOR Vector158 +#define KINETIS_HAS_PIT3 TRUE +#define KINETIS_PIT3_IRQ_VECTOR Vector15C +#define KINETIS_HAS_PIT FALSE +#define KINETIS_PIT_CHANNELS 4 +#define KINETIS_HAS_PIT_COMMON_IRQ FALSE + +/* USB attributes.*/ +#define KINETIS_HAS_USB TRUE +#define KINETIS_USB_IRQ_VECTOR Vector164 +#define KINETIS_USB0_IS_USBOTG TRUE +#define KINETIS_HAS_USB_CLOCK_RECOVERY FALSE + +/* LPTMR attributes.*/ +#define KINETIS_LPTMR0_IRQ_VECTOR Vector194 + +#endif /* K20xY */ /** @} */ diff --git a/os/hal/ports/KINETIS/K20x/mk20d5.h b/os/hal/ports/KINETIS/K20x/mk20d5.h deleted file mode 100644 index aa70723..0000000 --- a/os/hal/ports/KINETIS/K20x/mk20d5.h +++ /dev/null @@ -1,2394 +0,0 @@ -/* - * Copyright (C) 2014 Fabio Utzig, http://fabioutzig.com - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef _MK20D5_H_ -#define _MK20D5_H_ - -/* - * ============================================================== - * ---------- Interrupt Number Definition ----------------------- - * ============================================================== - */ -typedef enum IRQn -{ -/****** Cortex-M0 Processor Exceptions Numbers ****************/ - InitialSP_IRQn = -15, - InitialPC_IRQn = -15, - NonMaskableInt_IRQn = -14, - HardFault_IRQn = -13, - MemoryManagement_IRQn = -12, - BusFault_IRQn = -11, - UsageFault_IRQn = -10, - SVCall_IRQn = -5, - DebugMonitor_IRQn = -4, - PendSV_IRQn = -2, - SysTick_IRQn = -1, - -/****** K20x Specific Interrupt Numbers ***********************/ - DMA0_IRQn = 0, - DMA1_IRQn = 1, - DMA2_IRQn = 2, - DMA3_IRQn = 3, - DMAError_IRQn = 4, - DMA_IRQn = 5, - FlashMemComplete_IRQn = 6, - FlashMemReadCollision_IRQn = 7, - LowVoltageWarning_IRQn = 8, - LLWU_IRQn = 9, - WDOG_IRQn = 10, - I2C0_IRQn = 11, - SPI0_IRQn = 12, - I2S0_IRQn = 13, - I2S1_IRQn = 14, - UART0LON_IRQn = 15, - UART0Status_IRQn = 16, - UART0Error_IRQn = 17, - UART1Status_IRQn = 18, - UART1Error_IRQn = 19, - UART2Status_IRQn = 20, - UART2Error_IRQn = 21, - ADC0_IRQn = 22, - CMP0_IRQn = 23, - CMP1_IRQn = 24, - FTM0_IRQn = 25, - FTM1_IRQn = 26, - CMT_IRQn = 27, - RTCAlarm_IRQn = 28, - RTCSeconds_IRQn = 29, - PITChannel0_IRQn = 30, - PITChannel1_IRQn = 31, - PITChannel2_IRQn = 32, - PITChannel3_IRQn = 33, - PDB_IRQn = 34, - USB_OTG_IRQn = 35, - USBChargerDetect_IRQn = 36, - TSI_IRQn = 37, - MCG_IRQn = 38, - LowPowerTimer_IRQn = 39, - PINA_IRQn = 40, - PINB_IRQn = 41, - PINC_IRQn = 42, - PIND_IRQn = 43, - PINE_IRQn = 44, - SoftInitInt_IRQn = 45, -} IRQn_Type; - -/* - * ========================================================================== - * ----------- Processor and Core Peripheral Section ------------------------ - * ========================================================================== - */ - -/** - * @brief K20x Interrupt Number Definition, according to the selected device - * in @ref Library_configuration_section - */ -#define __MPU_PRESENT 0 -#define __FPU_PRESENT 0 -#define __NVIC_PRIO_BITS 4 -#define __Vendor_SysTickConfig 0 - -#include "core_cm4.h" /* Cortex-M4 processor and core peripherals */ - -typedef struct -{ - __IO uint32_t SOPT1; - __IO uint32_t SOPT1CFG; - uint32_t RESERVED0[1023]; - __IO uint32_t SOPT2; - uint32_t RESERVED1[1]; - __IO uint32_t SOPT4; - __IO uint32_t SOPT5; - uint32_t RESERVED2[1]; - __IO uint32_t SOPT7; - uint32_t RESERVED3[2]; - __I uint32_t SDID; - uint32_t RESERVED4[3]; - __IO uint32_t SCGC4; - __IO uint32_t SCGC5; - __IO uint32_t SCGC6; - __IO uint32_t SCGC7; - __IO uint32_t CLKDIV1; - __IO uint32_t CLKDIV2; - __I uint32_t FCFG1; - __I uint32_t FCFG2; - __I uint32_t UIDH; - __I uint32_t UIDMH; - __I uint32_t UIDML; - __I uint32_t UIDL; -} SIM_TypeDef; - -typedef struct -{ - __IO uint8_t PE1; - __IO uint8_t PE2; - __IO uint8_t PE3; - __IO uint8_t PE4; - __IO uint8_t ME; - __IO uint8_t F1; - __IO uint8_t F2; - __I uint8_t F3; - __IO uint8_t FILT1; - __IO uint8_t FILT2; -} LLWU_TypeDef; - -typedef struct -{ - __IO uint32_t PCR[32]; - __O uint32_t GPCLR; - __O uint32_t GPCHR; - uint32_t RESERVED0[6]; - __IO uint32_t ISFR; -} PORT_TypeDef; - -typedef struct -{ - __IO uint8_t C1; - __IO uint8_t C2; - __IO uint8_t C3; - __IO uint8_t C4; - __IO uint8_t C5; - __IO uint8_t C6; - __I uint8_t S; - uint8_t RESERVED0[1]; - __IO uint8_t SC; - uint8_t RESERVED1[1]; - __IO uint8_t ATCVH; - __IO uint8_t ATCVL; - __IO uint8_t C7; - __IO uint8_t C8; -} MCG_TypeDef; - -typedef struct -{ - __IO uint8_t CR; -} OSC_TypeDef; - -typedef struct { - uint32_t SADDR; /* TCD Source Address */ - uint16_t SOFF; /* TCD Signed Source Address Offset */ - uint16_t ATTR; /* TCD Transfer Attributes */ - union { - uint32_t NBYTES_MLNO; /* TCD Minor Byte Count (Minor Loop Disabled) */ - uint32_t NBYTES_MLOFFNO; /* TCD Signed Minor Loop Offset (Minor Loop Enabled and Offset Disabled) */ - uint32_t NBYTES_MLOFFYES; /* TCD Signed Minor Loop Offset (Minor Loop and Offset Enabled) */ - }; - uint32_t SLAST; /* TCD Last Source Address Adjustment */ - uint32_t DADDR; /* TCD Destination Address */ - uint16_t DOFF; /* TCD Signed Destination Address Offset */ - union { - uint16_t CITER_ELINKNO; /* TCD Current Minor Loop Link, Major Loop Count (Channel Linking Disabled) */ - uint16_t CITER_ELINKYES; /* TCD Current Minor Loop Link, Major Loop Count (Channel Linking Enabled) */ - }; - uint32_t DLASTSGA; /* TCD Last Destination Address Adjustment/Scatter Gather Address */ - uint16_t CSR; /* TCD Control and Status */ - union { - uint16_t BITER_ELINKNO; /* TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Disabled) */ - uint16_t BITER_ELINKYES; /* TCD Beginning Minor Loop Link, Major Loop Count (Channel Linking Enabled) */ - }; -} DMA_TCD_TypeDef; - -/** DMA - Peripheral register structure */ -typedef struct { - __IO uint32_t CR; /* Control Register */ - __IO uint32_t ES; /* Error Status Register */ - __IO uint8_t RESERVED_0[4]; - __IO uint32_t ERQ; /* Enable Request Register */ - __IO uint8_t RESERVED_1[4]; - __IO uint32_t EEI; /* Enable Error Interrupt Register */ - __IO uint8_t CEEI; /* Clear Enable Error Interrupt Register */ - __IO uint8_t SEEI; /* Set Enable Error Interrupt Register */ - __IO uint8_t CERQ; /* Clear Enable Request Register */ - __IO uint8_t SERQ; /* Set Enable Request Register */ - __IO uint8_t CDNE; /* Clear DONE Status Bit Register */ - __IO uint8_t SSRT; /* Set START Bit Register */ - __IO uint8_t CERR; /* Clear Error Register */ - __IO uint8_t CINT; /* Clear Interrupt Request Register */ - __IO uint8_t RESERVED_2[4]; - __IO uint32_t INT; /* Interrupt Request Register */ - __IO uint8_t RESERVED_3[4]; - __IO uint32_t ERR; /* Error Register */ - __IO uint8_t RESERVED_4[4]; - __IO uint32_t HRS; /* Hardware Request Status Register */ - __IO uint8_t RESERVED_5[200]; - __IO uint8_t DCHPRI3; /* Channel 3 Priority Register */ - __IO uint8_t DCHPRI2; /* Channel 2 Priority Register */ - __IO uint8_t DCHPRI1; /* Channel 1 Priority Register */ - __IO uint8_t DCHPRI0; /* Channel 0 Priority Register */ - __IO uint8_t RESERVED_6[3836]; - DMA_TCD_TypeDef TCD[4]; -} DMA_TypeDef; - -typedef struct -{ - __IO uint8_t CHCFG[4]; -} DMAMUX_TypeDef; - -/** PIT - Peripheral register structure */ -typedef struct { - __IO uint32_t MCR; /* PIT Module Control Register */ - uint8_t RESERVED0[252]; - struct PIT_CHANNEL { - __IO uint32_t LDVAL; /* Timer Load Value Register */ - __IO uint32_t CVAL; /* Current Timer Value Register */ - __IO uint32_t TCTRL; /* Timer Control Register */ - __IO uint32_t TFLG; /* Timer Flag Register */ - } CHANNEL[4]; -} PIT_TypeDef; - -typedef struct -{ - __IO uint32_t SC; /* Status and Control */ - __IO uint32_t CNT; /* Counter */ - __IO uint32_t MOD; /* Modulo */ - struct FTM_Channel { - __IO uint32_t CnSC; /* Channel Status and Control */ - __IO uint32_t CnV; /* Channel Value */ - } CHANNEL[8]; - __IO uint32_t CNTIN; /* Counter Initial Value */ - __IO uint32_t STATUS; /* Capture and Compare Status */ - __IO uint32_t MODE; /* Features Mode Selection */ - __IO uint32_t SYNC; /* Synchronization */ - __IO uint32_t OUTINIT; /* Initial State for Channels Output */ - __IO uint32_t OUTMASK; /* Output Mask */ - __IO uint32_t COMBINE; /* Function for Linked Channels */ - __IO uint32_t DEADTIME; /* Deadtime Insertion Control */ - __IO uint32_t EXTTRIG; /* FTM External Trigger */ - __IO uint32_t POL; /* Channels Polarity */ - __IO uint32_t FMS; /* Fault Mode Status */ - __IO uint32_t FILTER; /* Input Capture Filter Control */ - __IO uint32_t FLTCTRL; /* Fault Control */ - __IO uint32_t QDCTRL; /* Quadrature Decode Control and Status */ - __IO uint32_t CONF; /* Configuration */ - __IO uint32_t FTLPOL; /* FTM Fault Input Polarity */ - __IO uint32_t SYNCONF; /* Synchronization Configuration */ - __IO uint32_t INVCTRL; /* FTM Inverting Control */ - __IO uint32_t SWOCTRL; /* FTM Software Output Control */ - __IO uint32_t PWMLOAD; /* FTM PWM Load */ -} FTM_TypeDef; - -typedef struct -{ - __IO uint32_t SC1A; // offset: 0x00 - __IO uint32_t SC1B; // offset: 0x04 - __IO uint32_t CFG1; // offset: 0x08 - __IO uint32_t CFG2; // offset: 0x0C - __I uint32_t RA; // offset: 0x10 - __I uint32_t RB; // offset: 0x14 - __IO uint32_t CV1; // offset: 0x18 - __IO uint32_t CV2; // offset: 0x1C - __IO uint32_t SC2; // offset: 0x20 - __IO uint32_t SC3; // offset: 0x24 - __IO uint32_t OFS; // offset: 0x28 - __IO uint32_t PG; // offset: 0x2C - __IO uint32_t MG; // offset: 0x30 - __IO uint32_t CLPD; // offset: 0x34 - __IO uint32_t CLPS; // offset: 0x38 - __IO uint32_t CLP4; // offset: 0x3C - __IO uint32_t CLP3; // offset: 0x40 - __IO uint32_t CLP2; // offset: 0x44 - __IO uint32_t CLP1; // offset: 0x48 - __IO uint32_t CLP0; // offset: 0x4C - uint32_t RESERVED0[1]; // offset: 0x50 - __IO uint32_t CLMD; // offset: 0x54 - __IO uint32_t CLMS; // offset: 0x58 - __IO uint32_t CLM4; // offset: 0x5C - __IO uint32_t CLM3; // offset: 0x60 - __IO uint32_t CLM2; // offset: 0x64 - __IO uint32_t CLM1; // offset: 0x68 - __IO uint32_t CLM0; // offset: 0x6C -} ADC_TypeDef; - -typedef struct -{ - __IO uint32_t CSR; - __IO uint32_t PSR; - __IO uint32_t CMR; - __I uint32_t CNR; -} LPTMR_TypeDef; - -typedef struct -{ - __IO uint32_t GENCS; - __IO uint32_t DATA; - __IO uint32_t TSHD; -} TSI_TypeDef; - -typedef struct -{ - __IO uint32_t PDOR; - __IO uint32_t PSOR; - __IO uint32_t PCOR; - __IO uint32_t PTOR; - __IO uint32_t PDIR; - __IO uint32_t PDDR; -} GPIO_TypeDef; - -/** SPI - Peripheral register structure */ -typedef struct { - __IO uint32_t MCR; /**< DSPI Module Configuration Register, offset: 0x0 */ - uint32_t RESERVED0[1]; - __IO uint32_t TCR; /**< DSPI Transfer Count Register, offset: 0x8 */ - union { /* offset: 0xC */ - __IO uint32_t CTAR[2]; /**< DSPI Clock and Transfer Attributes Register (In Master Mode), array offset: 0xC, array step: 0x4 */ - __IO uint32_t CTAR_SLAVE[1]; /**< DSPI Clock and Transfer Attributes Register (In Slave Mode), array offset: 0xC, array step: 0x4 */ - }; - uint32_t RESERVED1[6]; - __IO uint32_t SR; /**< DSPI Status Register, offset: 0x2C */ - __IO uint32_t RSER; /**< DSPI DMA/Interrupt Request Select and Enable Register, offset: 0x30 */ - union { /* offset: 0x34 */ - __IO uint32_t PUSHR; /**< DSPI PUSH TX FIFO Register In Master Mode, offset: 0x34 */ - __IO uint32_t PUSHR_SLAVE; /**< DSPI PUSH TX FIFO Register In Slave Mode, offset: 0x34 */ - }; - __I uint32_t POPR; /**< DSPI POP RX FIFO Register, offset: 0x38 */ - __I uint32_t TXFR[4]; /**< DSPI Transmit FIFO Registers, offset: 0x3C */ - uint32_t RESERVED2[12]; - __I uint32_t RXFR[4]; /**< DSPI Receive FIFO Registers, offset: 0x7C */ -} SPI_TypeDef; - -typedef struct -{ - __IO uint8_t A1; - __IO uint8_t F; - __IO uint8_t C1; - __IO uint8_t S; - __IO uint8_t D; - __IO uint8_t C2; - __IO uint8_t FLT; - __IO uint8_t RA; - __IO uint8_t SMB; - __IO uint8_t A2; - __IO uint8_t SLTH; - __IO uint8_t SLTL; -} I2C_TypeDef; - -typedef struct -{ - __IO uint8_t BDH; - __IO uint8_t BDL; - __IO uint8_t C1; - __IO uint8_t C2; - __I uint8_t S1; - __IO uint8_t S2; - __IO uint8_t C3; - __IO uint8_t D; - __IO uint8_t MA1; - __IO uint8_t MA2; - __IO uint8_t C4; - __IO uint8_t C5; - __I uint8_t ED; - __IO uint8_t MODEM; - __IO uint8_t IR; - uint8_t RESERVED0[1]; - __IO uint8_t PFIFO; - __IO uint8_t CFIFO; - __IO uint8_t SFIFO; - __IO uint8_t TWFIFO; - __I uint8_t TCFIFO; - __IO uint8_t RWFIFO; - __I uint8_t RCFIFO; - uint8_t RESERVED1[1]; - __IO uint8_t C7816; - __IO uint8_t IE7816; - __IO uint8_t IS7816; - union { - __IO uint8_t WP7816T0; - __IO uint8_t WP7816T1; - }; - __IO uint8_t WN7816; - __IO uint8_t WF7816; - __IO uint8_t ET7816; - __IO uint8_t TL7816; - uint8_t RESERVED2[2]; - __IO uint8_t C6; - __IO uint8_t PCTH; - __IO uint8_t PCTL; - __IO uint8_t B1T; - __IO uint8_t SDTH; - __IO uint8_t SDTL; - __IO uint8_t PRE; - __IO uint8_t TPL; - __IO uint8_t IE; - __IO uint8_t WB; - __IO uint8_t S3; - __IO uint8_t S4; - __I uint8_t RPL; - __I uint8_t RPREL; - __IO uint8_t CPW; - __IO uint8_t RIDT; - __IO uint8_t TIDT; -} UART_TypeDef; - -typedef struct -{ - __IO uint8_t LVDSC1; - __IO uint8_t LVDSC2; - __IO uint8_t REGSC; -} PMC_TypeDef; - -typedef struct -{ - __IO uint16_t STCTRLH; - __IO uint16_t STCTRLL; - __IO uint16_t TOVALH; - __IO uint16_t TOVALL; - __IO uint16_t WINH; - __IO uint16_t WINL; - __IO uint16_t REFRESH; - __IO uint16_t UNLOCK; - __IO uint16_t TMROUTH; - __IO uint16_t TMROUTL; - __IO uint16_t RSTCNT; - __IO uint16_t PRESC; -} WDOG_TypeDef; - -typedef struct { - __I uint8_t PERID; // 0x00 - uint8_t RESERVED0[3]; - __I uint8_t IDCOMP; // 0x04 - uint8_t RESERVED1[3]; - __I uint8_t REV; // 0x08 - uint8_t RESERVED2[3]; - __I uint8_t ADDINFO; // 0x0C - uint8_t RESERVED3[3]; - __IO uint8_t OTGISTAT; // 0x10 - uint8_t RESERVED4[3]; - __IO uint8_t OTGICR; // 0x14 - uint8_t RESERVED5[3]; - __IO uint8_t OTGSTAT; // 0x18 - uint8_t RESERVED6[3]; - __IO uint8_t OTGCTL; // 0x1C - uint8_t RESERVED7[99]; - __IO uint8_t ISTAT; // 0x80 - uint8_t RESERVED8[3]; - __IO uint8_t INTEN; // 0x84 - uint8_t RESERVED9[3]; - __IO uint8_t ERRSTAT; // 0x88 - uint8_t RESERVED10[3]; - __IO uint8_t ERREN; // 0x8C - uint8_t RESERVED11[3]; - __I uint8_t STAT; // 0x90 - uint8_t RESERVED12[3]; - __IO uint8_t CTL; // 0x94 - uint8_t RESERVED13[3]; - __IO uint8_t ADDR; // 0x98 - uint8_t RESERVED14[3]; - __IO uint8_t BDTPAGE1; // 0x9C - uint8_t RESERVED15[3]; - __IO uint8_t FRMNUML; // 0xA0 - uint8_t RESERVED16[3]; - __IO uint8_t FRMNUMH; // 0xA4 - uint8_t RESERVED17[3]; - __IO uint8_t TOKEN; // 0xA8 - uint8_t RESERVED18[3]; - __IO uint8_t SOFTHLD; // 0xAC - uint8_t RESERVED19[3]; - __IO uint8_t BDTPAGE2; // 0xB0 - uint8_t RESERVED20[3]; - __IO uint8_t BDTPAGE3; // 0xB4 - uint8_t RESERVED21[11]; - struct { - __IO uint8_t V; // 0xC0 - uint8_t RESERVED[3]; - } ENDPT[16]; - __IO uint8_t USBCTRL; // 0x100 - uint8_t RESERVED22[3]; - __I uint8_t OBSERVE; // 0x104 - uint8_t RESERVED23[3]; - __IO uint8_t CONTROL; // 0x108 - uint8_t RESERVED24[3]; - __IO uint8_t USBTRC0; // 0x10C - uint8_t RESERVED25[7]; - __IO uint8_t USBFRMADJUST; // 0x114 -} USBOTG_TypeDef; - -/****************************************************************/ -/* Peripheral memory map */ -/****************************************************************/ -#define DMA_BASE ((uint32_t)0x40008000) -#define DMAMUX_BASE ((uint32_t)0x40021000) -#define SPI0_BASE ((uint32_t)0x4002C000) -#define PIT_BASE ((uint32_t)0x40037000) -#define FTM0_BASE ((uint32_t)0x40038000) -#define FTM1_BASE ((uint32_t)0x40039000) -#define ADC0_BASE ((uint32_t)0x4003B000) -#define LPTMR0_BASE ((uint32_t)0x40040000) -#define TSI0_BASE ((uint32_t)0x40045000) -#define SIM_BASE ((uint32_t)0x40047000) -#define PORTA_BASE ((uint32_t)0x40049000) -#define PORTB_BASE ((uint32_t)0x4004A000) -#define PORTC_BASE ((uint32_t)0x4004B000) -#define PORTD_BASE ((uint32_t)0x4004C000) -#define PORTE_BASE ((uint32_t)0x4004D000) -#define WDOG_BASE ((uint32_t)0x40052000) -#define MCG_BASE ((uint32_t)0x40064000) -#define OSC0_BASE ((uint32_t)0x40065000) -#define I2C0_BASE ((uint32_t)0x40066000) -#define UART0_BASE ((uint32_t)0x4006A000) -#define UART1_BASE ((uint32_t)0x4006B000) -#define UART2_BASE ((uint32_t)0x4006C000) -#define USBOTG_BASE ((uint32_t)0x40072000) -#define LLWU_BASE ((uint32_t)0x4007C000) -#define PMC_BASE ((uint32_t)0x4007D000) -#define GPIOA_BASE ((uint32_t)0x400FF000) -#define GPIOB_BASE ((uint32_t)0x400FF040) -#define GPIOC_BASE ((uint32_t)0x400FF080) -#define GPIOD_BASE ((uint32_t)0x400FF0C0) -#define GPIOE_BASE ((uint32_t)0x400FF100) - -/****************************************************************/ -/* Peripheral declaration */ -/****************************************************************/ -#define DMA ((DMA_TypeDef *) DMA_BASE) -#define DMAMUX ((DMAMUX_TypeDef *) DMAMUX_BASE) -#define PIT ((PIT_TypeDef *) PIT_BASE) -#define FTM0 ((FTM_TypeDef *) FTM0_BASE) -#define FTM1 ((FTM_TypeDef *) FTM1_BASE) -#define ADC0 ((ADC_TypeDef *) ADC0_BASE) -#define LPTMR0 ((LPTMR_TypeDef *) LPTMR0_BASE) -#define TSI0 ((TSI_TypeDef *) TSI0_BASE) -#define SIM ((SIM_TypeDef *) SIM_BASE) -#define LLWU ((LLWU_TypeDef *) LLWU_BASE) -#define PMC ((PMC_TypeDef *) PMC_BASE) -#define PORTA ((PORT_TypeDef *) PORTA_BASE) -#define PORTB ((PORT_TypeDef *) PORTB_BASE) -#define PORTC ((PORT_TypeDef *) PORTC_BASE) -#define PORTD ((PORT_TypeDef *) PORTD_BASE) -#define PORTE ((PORT_TypeDef *) PORTE_BASE) -#define WDOG ((WDOG_TypeDef *) WDOG_BASE) -#define USBOTG ((USBOTG_TypeDef *) USBOTG_BASE) -#define MCG ((MCG_TypeDef *) MCG_BASE) -#define OSC ((OSC_TypeDef *) OSC0_BASE) -#define SPI0 ((SPI_TypeDef *) SPI0_BASE) -#define I2C0 ((I2C_TypeDef *) I2C0_BASE) -#define UART0 ((UART_TypeDef *) UART0_BASE) -#define UART1 ((UART_TypeDef *) UART1_BASE) -#define UART2 ((UART_TypeDef *) UART2_BASE) -#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE) -#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE) -#define GPIOC ((GPIO_TypeDef *) GPIOC_BASE) -#define GPIOD ((GPIO_TypeDef *) GPIOD_BASE) -#define GPIOE ((GPIO_TypeDef *) GPIOE_BASE) - -/****************************************************************/ -/* Peripheral Registers Bits Definition */ -/****************************************************************/ - -/****************************************************************/ -/* */ -/* System Integration Module (SIM) */ -/* */ -/****************************************************************/ -/********* Bits definition for SIM_SOPT1 register *************/ -#define SIM_SOPT1_USBREGEN ((uint32_t)0x80000000) /*!< USB voltage regulator enable */ -#define SIM_SOPT1_USBSSTBY ((uint32_t)0x40000000) /*!< USB voltage regulator in standby mode during Stop, VLPS, LLS and VLLS modes */ -#define SIM_SOPT1_USBVSTBY ((uint32_t)0x20000000) /*!< USB voltage regulator in standby mode during VLPR and VLPW modes */ -#define SIM_SOPT1_OSC32KSEL_SHIFT 18 /*!< 32K oscillator clock select (shift) */ -#define SIM_SOPT1_OSC32KSEL_MASK ((uint32_t)((uint32_t)0x3 << SIM_SOPT1_OSC32KSEL_SHIFT)) /*!< 32K oscillator clock select (mask) */ -#define SIM_SOPT1_OSC32KSEL(x) ((uint32_t)(((uint32_t)(x) << SIM_SOPT1_OSC32KSEL_SHIFT) & SIM_SOPT1_OSC32KSEL_MASK)) /*!< 32K oscillator clock select */ -#define SIM_SOPT1_RAMSIZE_SHIFT 12 -#define SIM_SOPT1_RAMSIZE_MASK ((uint32_t)((uint32_t)0xf << SIM_SOPT1_RAMSIZE_SHIFT)) -#define SIM_SOPT1_RAMSIZE(x) ((uint32_t)(((uint32_t)(x) << SIM_SOPT1_RAMSIZE_SHIFT) & SIM_SOPT1_RAMSIZE_MASK)) - -/******* Bits definition for SIM_SOPT1CFG register ************/ -#define SIM_SOPT1CFG_USSWE ((uint32_t)0x04000000) /*!< USB voltage regulator stop standby write enable */ -#define SIM_SOPT1CFG_UVSWE ((uint32_t)0x02000000) /*!< USB voltage regulator VLP standby write enable */ -#define SIM_SOPT1CFG_URWE ((uint32_t)0x01000000) /*!< USB voltage regulator voltage regulator write enable */ - -/******* Bits definition for SIM_SOPT2 register ************/ -#define SIM_SOPT2_USBSRC ((uint32_t)0x00040000) /*!< USB clock source select */ -#define SIM_SOPT2_PLLFLLSEL ((uint32_t)0x00010000) /*!< PLL/FLL clock select */ -#define SIM_SOPT2_TRACECLKSEL ((uint32_t)0x00001000) -#define SIM_SOPT2_PTD7PAD ((uint32_t)0x00000800) -#define SIM_SOPT2_CLKOUTSEL_SHIFT 5 -#define SIM_SOPT2_CLKOUTSEL_MASK ((uint32_t)((uint32_t)0x7 << SIM_SOPT2_CLKOUTSEL_SHIFT)) -#define SIM_SOPT2_CLKOUTSEL(x) ((uint32_t)(((uint32_t)(x) << SIM_SOPT2_CLKOUTSEL_SHIFT) & SIM_SOPT2_CLKOUTSEL_MASK)) -#define SIM_SOPT2_RTCCLKOUTSEL ((uint32_t)0x00000010) /*!< RTC clock out select */ - -/******* Bits definition for SIM_SCGC4 register ************/ -#define SIM_SCGC4_VREF ((uint32_t)0x00100000) /*!< VREF Clock Gate Control */ -#define SIM_SCGC4_CMP ((uint32_t)0x00080000) /*!< Comparator Clock Gate Control */ -#define SIM_SCGC4_USBOTG ((uint32_t)0x00040000) /*!< USB Clock Gate Control */ -#define SIM_SCGC4_UART2 ((uint32_t)0x00001000) /*!< UART2 Clock Gate Control */ -#define SIM_SCGC4_UART1 ((uint32_t)0x00000800) /*!< UART1 Clock Gate Control */ -#define SIM_SCGC4_UART0 ((uint32_t)0x00000400) /*!< UART0 Clock Gate Control */ -#define SIM_SCGC4_I2C0 ((uint32_t)0x00000040) /*!< I2C0 Clock Gate Control */ -#define SIM_SCGC4_CMT ((uint32_t)0x00000004) /*!< CMT Clock Gate Control */ -#define SIM_SCGC4_EMW ((uint32_t)0x00000002) /*!< EWM Clock Gate Control */ - -/******* Bits definition for SIM_SCGC5 register ************/ -#define SIM_SCGC5_PORTE ((uint32_t)0x00002000) /*!< Port E Clock Gate Control */ -#define SIM_SCGC5_PORTD ((uint32_t)0x00001000) /*!< Port D Clock Gate Control */ -#define SIM_SCGC5_PORTC ((uint32_t)0x00000800) /*!< Port C Clock Gate Control */ -#define SIM_SCGC5_PORTB ((uint32_t)0x00000400) /*!< Port B Clock Gate Control */ -#define SIM_SCGC5_PORTA ((uint32_t)0x00000200) /*!< Port A Clock Gate Control */ -#define SIM_SCGC5_TSI ((uint32_t)0x00000020) /*!< TSI Access Control */ -#define SIM_SCGC5_LPTIMER ((uint32_t)0x00000001) /*!< Low Power Timer Access Control */ - -/******* Bits definition for SIM_SCGC6 register ************/ -#define SIM_SCGC6_RTC ((uint32_t)0x20000000) /*!< RTC Access Control */ -#define SIM_SCGC6_ADC0 ((uint32_t)0x08000000) /*!< ADC0 Clock Gate Control */ -#define SIM_SCGC6_FTM1 ((uint32_t)0x02000000) /*!< FTM1 Clock Gate Control */ -#define SIM_SCGC6_FTM0 ((uint32_t)0x01000000) /*!< FTM0 Clock Gate Control */ -#define SIM_SCGC6_PIT ((uint32_t)0x00800000) /*!< PIT Clock Gate Control */ -#define SIM_SCGC6_PDB ((uint32_t)0x00400000) /*!< PDB Clock Gate Control */ -#define SIM_SCGC6_USBDCD ((uint32_t)0x00200000) /*!< USB DCD Clock Gate Control */ -#define SIM_SCGC6_CRC ((uint32_t)0x00040000) /*!< Low Power Timer Access Control */ -#define SIM_SCGC6_I2S ((uint32_t)0x00008000) /*!< CRC Clock Gate Control */ -#define SIM_SCGC6_SPI0 ((uint32_t)0x00001000) /*!< SPI0 Clock Gate Control */ -#define SIM_SCGC6_DMAMUX ((uint32_t)0x00000002) /*!< DMA Mux Clock Gate Control */ -#define SIM_SCGC6_FTFL ((uint32_t)0x00000001) /*!< Flash Memory Clock Gate Control */ - -/******* Bits definition for SIM_SCGC6 register ************/ -#define SIM_SCGC7_DMA ((uint32_t)0x00000002) /*!< DMA Clock Gate Control */ - -/****** Bits definition for SIM_CLKDIV1 register ***********/ -#define SIM_CLKDIV1_OUTDIV1_SHIFT 28 -#define SIM_CLKDIV1_OUTDIV1_MASK ((uint32_t)((uint32_t)0xF << SIM_CLKDIV1_OUTDIV1_SHIFT)) -#define SIM_CLKDIV1_OUTDIV1(x) ((uint32_t)(((uint32_t)(x) << SIM_CLKDIV1_OUTDIV1_SHIFT) & SIM_CLKDIV1_OUTDIV1_MASK)) -#define SIM_CLKDIV1_OUTDIV2_SHIFT 24 -#define SIM_CLKDIV1_OUTDIV2_MASK ((uint32_t)((uint32_t)0xF << SIM_CLKDIV1_OUTDIV2_SHIFT)) -#define SIM_CLKDIV1_OUTDIV2(x) ((uint32_t)(((uint32_t)(x) << SIM_CLKDIV1_OUTDIV2_SHIFT) & SIM_CLKDIV1_OUTDIV2_MASK)) -#define SIM_CLKDIV1_OUTDIV4_SHIFT 16 -#define SIM_CLKDIV1_OUTDIV4_MASK ((uint32_t)((uint32_t)0x7 << SIM_CLKDIV1_OUTDIV4_SHIFT)) -#define SIM_CLKDIV1_OUTDIV4(x) ((uint32_t)(((uint32_t)(x) << SIM_CLKDIV1_OUTDIV4_SHIFT) & SIM_CLKDIV1_OUTDIV4_MASK)) - -/****** Bits definition for SIM_CLKDIV2 register ***********/ -#define SIM_CLKDIV2_USBDIV_SHIFT 1 -#define SIM_CLKDIV2_USBDIV_MASK ((uint32_t)((uint32_t)0x7 << SIM_CLKDIV2_USBDIV_SHIFT)) -#define SIM_CLKDIV2_USBDIV(x) ((uint32_t)(((uint32_t)(x) << SIM_CLKDIV2_USBDIV_SHIFT) & SIM_CLKDIV2_USBDIV_MASK)) -#define SIM_CLKDIV2_USBFRAC ((uint32_t)0x00000001) - -/****************************************************************/ -/* */ -/* Low-Leakage Wakeup Unit (LLWU) */ -/* */ -/****************************************************************/ -/********** Bits definition for LLWU_PE1 register *************/ -#define LLWU_PE1_WUPE3_SHIFT 6 /*!< Wakeup Pin Enable for LLWU_P3 (shift) */ -#define LLWU_PE1_WUPE3_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE1_WUPE3_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P3 (mask) */ -#define LLWU_PE1_WUPE3(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE1_WUPE3_SHIFT) & LLWU_PE1_WUPE3_MASK)) /*!< Wakeup Pin Enable for LLWU_P3 */ -#define LLWU_PE1_WUPE2_SHIFT 4 /*!< Wakeup Pin Enable for LLWU_P2 (shift) */ -#define LLWU_PE1_WUPE2_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE1_WUPE2_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P2 (mask) */ -#define LLWU_PE1_WUPE2(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE1_WUPE2_SHIFT) & LLWU_PE1_WUPE2_MASK)) /*!< Wakeup Pin Enable for LLWU_P2 */ -#define LLWU_PE1_WUPE1_SHIFT 2 /*!< Wakeup Pin Enable for LLWU_P1 (shift) */ -#define LLWU_PE1_WUPE1_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE1_WUPE1_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P1 (mask) */ -#define LLWU_PE1_WUPE1(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE1_WUPE1_SHIFT) & LLWU_PE1_WUPE1_MASK)) /*!< Wakeup Pin Enable for LLWU_P1 */ -#define LLWU_PE1_WUPE0_SHIFT 0 /*!< Wakeup Pin Enable for LLWU_P0 (shift) */ -#define LLWU_PE1_WUPE0_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE1_WUPE0_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P0 (mask) */ -#define LLWU_PE1_WUPE0(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE1_WUPE0_SHIFT) & LLWU_PE1_WUPE0_MASK)) /*!< Wakeup Pin Enable for LLWU_P0 */ - -/********** Bits definition for LLWU_PE2 register *************/ -#define LLWU_PE2_WUPE7_SHIFT 6 /*!< Wakeup Pin Enable for LLWU_P7 (shift) */ -#define LLWU_PE2_WUPE7_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE2_WUPE7_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P7 (mask) */ -#define LLWU_PE2_WUPE7(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE2_WUPE7_SHIFT) & LLWU_PE2_WUPE7_MASK)) /*!< Wakeup Pin Enable for LLWU_P7 */ -#define LLWU_PE2_WUPE6_SHIFT 4 /*!< Wakeup Pin Enable for LLWU_P6 (shift) */ -#define LLWU_PE2_WUPE6_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE2_WUPE6_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P6 (mask) */ -#define LLWU_PE2_WUPE6(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE2_WUPE6_SHIFT) & LLWU_PE2_WUPE6_MASK)) /*!< Wakeup Pin Enable for LLWU_P6 */ -#define LLWU_PE2_WUPE5_SHIFT 2 /*!< Wakeup Pin Enable for LLWU_P5 (shift) */ -#define LLWU_PE2_WUPE5_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE2_WUPE5_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P5 (mask) */ -#define LLWU_PE2_WUPE5(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE2_WUPE5_SHIFT) & LLWU_PE2_WUPE5_MASK)) /*!< Wakeup Pin Enable for LLWU_P5 */ -#define LLWU_PE2_WUPE4_SHIFT 0 /*!< Wakeup Pin Enable for LLWU_P4 (shift) */ -#define LLWU_PE2_WUPE4_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE2_WUPE4_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P4 (mask) */ -#define LLWU_PE2_WUPE4(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE2_WUPE4_SHIFT) & LLWU_PE2_WUPE4_MASK)) /*!< Wakeup Pin Enable for LLWU_P4 */ - -/********** Bits definition for LLWU_PE3 register *************/ -#define LLWU_PE3_WUPE11_SHIFT 6 /*!< Wakeup Pin Enable for LLWU_P11 (shift) */ -#define LLWU_PE3_WUPE11_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE3_WUPE11_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P11 (mask) */ -#define LLWU_PE3_WUPE11(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE3_WUPE11_SHIFT) & LLWU_PE3_WUPE11_MASK)) /*!< Wakeup Pin Enable for LLWU_P11 */ -#define LLWU_PE3_WUPE10_SHIFT 4 /*!< Wakeup Pin Enable for LLWU_P10 (shift) */ -#define LLWU_PE3_WUPE10_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE3_WUPE10_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P10 (mask) */ -#define LLWU_PE3_WUPE10(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE3_WUPE10_SHIFT) & LLWU_PE3_WUPE10_MASK)) /*!< Wakeup Pin Enable for LLWU_P10 */ -#define LLWU_PE3_WUPE13_SHIFT 2 /*!< Wakeup Pin Enable for LLWU_P9 (shift) */ -#define LLWU_PE3_WUPE13_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE3_WUPE13_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P9 (mask) */ -#define LLWU_PE3_WUPE13(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE3_WUPE13_SHIFT) & LLWU_PE3_WUPE13_MASK)) /*!< Wakeup Pin Enable for LLWU_P9 */ -#define LLWU_PE3_WUPE8_SHIFT 0 /*!< Wakeup Pin Enable for LLWU_P8 (shift) */ -#define LLWU_PE3_WUPE8_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE3_WUPE8_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P8 (mask) */ -#define LLWU_PE3_WUPE8(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE3_WUPE8_SHIFT) & LLWU_PE3_WUPE8_MASK)) /*!< Wakeup Pin Enable for LLWU_P8 */ - -/********** Bits definition for LLWU_PE4 register *************/ -#define LLWU_PE4_WUPE15_SHIFT 6 /*!< Wakeup Pin Enable for LLWU_P15 (shift) */ -#define LLWU_PE4_WUPE15_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE4_WUPE15_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P15 (mask) */ -#define LLWU_PE4_WUPE15(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE4_WUPE15_SHIFT) & LLWU_PE4_WUPE15_MASK)) /*!< Wakeup Pin Enable for LLWU_P15 */ -#define LLWU_PE4_WUPE14_SHIFT 4 /*!< Wakeup Pin Enable for LLWU_P14 (shift) */ -#define LLWU_PE4_WUPE14_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE4_WUPE14_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P14 (mask) */ -#define LLWU_PE4_WUPE14(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE4_WUPE14_SHIFT) & LLWU_PE4_WUPE14_MASK)) /*!< Wakeup Pin Enable for LLWU_P14 */ -#define LLWU_PE4_WUPE13_SHIFT 2 /*!< Wakeup Pin Enable for LLWU_P13 (shift) */ -#define LLWU_PE4_WUPE13_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE4_WUPE13_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P13 (mask) */ -#define LLWU_PE4_WUPE13(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE4_WUPE13_SHIFT) & LLWU_PE4_WUPE13_MASK)) /*!< Wakeup Pin Enable for LLWU_P13 */ -#define LLWU_PE4_WUPE12_SHIFT 0 /*!< Wakeup Pin Enable for LLWU_P12 (shift) */ -#define LLWU_PE4_WUPE12_MASK ((uint8_t)((uint8_t)0x03 << LLWU_PE4_WUPE12_SHIFT)) /*!< Wakeup Pin Enable for LLWU_P12 (mask) */ -#define LLWU_PE4_WUPE12(x) ((uint8_t)(((uint8_t)(x) << LLWU_PE4_WUPE12_SHIFT) & LLWU_PE4_WUPE12_MASK)) /*!< Wakeup Pin Enable for LLWU_P12 */ - -/********** Bits definition for LLWU_ME register *************/ -#define LLWU_ME_WUME7 ((uint8_t)((uint8_t)1 << 7)) /*!< Wakeup Module Enable for Module 7 */ -#define LLWU_ME_WUME6 ((uint8_t)((uint8_t)1 << 6)) /*!< Wakeup Module Enable for Module 6 */ -#define LLWU_ME_WUME5 ((uint8_t)((uint8_t)1 << 5)) /*!< Wakeup Module Enable for Module 5 */ -#define LLWU_ME_WUME4 ((uint8_t)((uint8_t)1 << 4)) /*!< Wakeup Module Enable for Module 4 */ -#define LLWU_ME_WUME3 ((uint8_t)((uint8_t)1 << 3)) /*!< Wakeup Module Enable for Module 3 */ -#define LLWU_ME_WUME2 ((uint8_t)((uint8_t)1 << 2)) /*!< Wakeup Module Enable for Module 2 */ -#define LLWU_ME_WUME1 ((uint8_t)((uint8_t)1 << 1)) /*!< Wakeup Module Enable for Module 1 */ -#define LLWU_ME_WUME0 ((uint8_t)((uint8_t)1 << 0)) /*!< Wakeup Module Enable for Module 0 */ - -/********** Bits definition for LLWU_F1 register *************/ -#define LLWU_F1_WUF7 ((uint8_t)((uint8_t)1 << 7)) /*!< Wakeup Flag for LLWU_P7 */ -#define LLWU_F1_WUF6 ((uint8_t)((uint8_t)1 << 6)) /*!< Wakeup Flag for LLWU_P6 */ -#define LLWU_F1_WUF5 ((uint8_t)((uint8_t)1 << 5)) /*!< Wakeup Flag for LLWU_P5 */ -#define LLWU_F1_WUF4 ((uint8_t)((uint8_t)1 << 4)) /*!< Wakeup Flag for LLWU_P4 */ -#define LLWU_F1_WUF3 ((uint8_t)((uint8_t)1 << 3)) /*!< Wakeup Flag for LLWU_P3 */ -#define LLWU_F1_WUF2 ((uint8_t)((uint8_t)1 << 2)) /*!< Wakeup Flag for LLWU_P2 */ -#define LLWU_F1_WUF1 ((uint8_t)((uint8_t)1 << 1)) /*!< Wakeup Flag for LLWU_P1 */ -#define LLWU_F1_WUF0 ((uint8_t)((uint8_t)1 << 0)) /*!< Wakeup Flag for LLWU_P0 */ - -/********** Bits definition for LLWU_F2 register *************/ -#define LLWU_F2_WUF15 ((uint8_t)((uint8_t)1 << 7)) /*!< Wakeup Flag for LLWU_P15 */ -#define LLWU_F2_WUF14 ((uint8_t)((uint8_t)1 << 6)) /*!< Wakeup Flag for LLWU_P14 */ -#define LLWU_F2_WUF13 ((uint8_t)((uint8_t)1 << 5)) /*!< Wakeup Flag for LLWU_P13 */ -#define LLWU_F2_WUF12 ((uint8_t)((uint8_t)1 << 4)) /*!< Wakeup Flag for LLWU_P12 */ -#define LLWU_F2_WUF11 ((uint8_t)((uint8_t)1 << 3)) /*!< Wakeup Flag for LLWU_P11 */ -#define LLWU_F2_WUF10 ((uint8_t)((uint8_t)1 << 2)) /*!< Wakeup Flag for LLWU_P10 */ -#define LLWU_F2_WUF9 ((uint8_t)((uint8_t)1 << 1)) /*!< Wakeup Flag for LLWU_P9 */ -#define LLWU_F2_WUF8 ((uint8_t)((uint8_t)1 << 0)) /*!< Wakeup Flag for LLWU_P8 */ - -/********** Bits definition for LLWU_F3 register *************/ -#define LLWU_F3_MWUF7 ((uint8_t)((uint8_t)1 << 7)) /*!< Wakeup Flag for Module 7 */ -#define LLWU_F3_MWUF6 ((uint8_t)((uint8_t)1 << 6)) /*!< Wakeup Flag for Module 6 */ -#define LLWU_F3_MWUF5 ((uint8_t)((uint8_t)1 << 5)) /*!< Wakeup Flag for Module 5 */ -#define LLWU_F3_MWUF4 ((uint8_t)((uint8_t)1 << 4)) /*!< Wakeup Flag for Module 4 */ -#define LLWU_F3_MWUF3 ((uint8_t)((uint8_t)1 << 3)) /*!< Wakeup Flag for Module 3 */ -#define LLWU_F3_MWUF2 ((uint8_t)((uint8_t)1 << 2)) /*!< Wakeup Flag for Module 2 */ -#define LLWU_F3_MWUF1 ((uint8_t)((uint8_t)1 << 1)) /*!< Wakeup Flag for Module 1 */ -#define LLWU_F3_MWUF0 ((uint8_t)((uint8_t)1 << 0)) /*!< Wakeup Flag for Module 0 */ - -/********** Bits definition for LLWU_FILT1 register *************/ -#define LLWU_FILT1_FILTF ((uint8_t)((uint8_t)1 << 7)) /*!< Filter Detect Flag */ -#define LLWU_FILT1_FILTE_SHIFT 5 /*!< Digital Filter on External Pin (shift) */ -#define LLWU_FILT1_FILTE_MASK ((uint8_t)((uint8_t)0x03 << LLWU_FILT1_FILTE_SHIFT)) /*!< Digital Filter on External Pin (mask) */ -#define LLWU_FILT1_FILTE(x) ((uint8_t)(((uint8_t)(x) << LLWU_FILT1_FILTE_SHIFT) & LLWU_FILT1_FILTE_MASK)) /*!< Digital Filter on External Pin */ -#define LLWU_FILT1_FILTE_DISABLED LLWU_FILT1_FILTE(0) /*!< Filter disabled */ -#define LLWU_FILT1_FILTE_POSEDGE LLWU_FILT1_FILTE(1) /*!< Filter posedge detect enabled */ -#define LLWU_FILT1_FILTE_NEGEDGE LLWU_FILT1_FILTE(2) /*!< Filter negedge detect enabled */ -#define LLWU_FILT1_FILTE_ANYEDGE LLWU_FILT1_FILTE(3) /*!< Filter any edge detect enabled */ -#define LLWU_FILT1_FILTSEL_SHIFT 0 /*!< Filter Pin Select (LLWU_P0 ... LLWU_P15) (shift) */ -#define LLWU_FILT1_FILTSEL_MASK ((uint8_t)((uint8_t)0x0F << LLWU_FILT1_FILTSEL_SHIFT)) /*!< Filter Pin Select (LLWU_P0 ... LLWU_P15) (mask) */ -#define LLWU_FILT1_FILTSEL(x) ((uint8_t)(((uint8_t)(x) << LLWU_FILT1_FILTSEL_SHIFT) & LLWU_FILT1_FILTSEL_MASK)) /*!< Filter Pin Select (LLWU_P0 ... LLWU_P15) */ - -/********** Bits definition for LLWU_FILT2 register *************/ -#define LLWU_FILT2_FILTF ((uint8_t)((uint8_t)1 << 7)) /*!< Filter Detect Flag */ -#define LLWU_FILT2_FILTE_SHIFT 5 /*!< Digital Filter on External Pin (shift) */ -#define LLWU_FILT2_FILTE_MASK ((uint8_t)((uint8_t)0x03 << LLWU_FILT2_FILTE_SHIFT)) /*!< Digital Filter on External Pin (mask) */ -#define LLWU_FILT2_FILTE(x) ((uint8_t)(((uint8_t)(x) << LLWU_FILT2_FILTE_SHIFT) & LLWU_FILT2_FILTE_MASK)) /*!< Digital Filter on External Pin */ -#define LLWU_FILT2_FILTE_DISABLED LLWU_FILT2_FILTE(0) /*!< Filter disabled */ -#define LLWU_FILT2_FILTE_POSEDGE LLWU_FILT2_FILTE(1) /*!< Filter posedge detect enabled */ -#define LLWU_FILT2_FILTE_NEGEDGE LLWU_FILT2_FILTE(2) /*!< Filter negedge detect enabled */ -#define LLWU_FILT2_FILTE_ANYEDGE LLWU_FILT2_FILTE(3) /*!< Filter any edge detect enabled */ -#define LLWU_FILT2_FILTSEL_SHIFT 0 /*!< Filter Pin Select (LLWU_P0 ... LLWU_P15) (shift) */ -#define LLWU_FILT2_FILTSEL_MASK ((uint8_t)((uint8_t)0x0F << LLWU_FILT2_FILTSEL_SHIFT)) /*!< Filter Pin Select (LLWU_P0 ... LLWU_P15) (mask) */ -#define LLWU_FILT2_FILTSEL(x) ((uint8_t)(((uint8_t)(x) << LLWU_FILT2_FILTSEL_SHIFT) & LLWU_FILT2_FILTSEL_MASK)) /*!< Filter Pin Select (LLWU_P0 ... LLWU_P15) */ - -/****************************************************************/ -/* */ -/* Port Control and interrupts (PORT) */ -/* */ -/****************************************************************/ -/******** Bits definition for PORTx_PCRn register *************/ -#define PORTx_PCRn_ISF ((uint32_t)0x01000000) /*!< Interrupt Status Flag */ -#define PORTx_PCRn_IRQC_SHIFT 16 -#define PORTx_PCRn_IRQC_MASK ((uint32_t)((uint32_t)0xF << PORTx_PCRn_IRQC_SHIFT)) -#define PORTx_PCRn_IRQC(x) ((uint32_t)(((uint32_t)(x) << PORTx_PCRn_IRQC_SHIFT) & PORTx_PCRn_IRQC_MASK)) -#define PORTx_PCRn_LK ((uint32_t)0x00008000) /*!< Lock Register */ -#define PORTx_PCRn_MUX_SHIFT 8 /*!< Pin Mux Control (shift) */ -#define PORTx_PCRn_MUX_MASK ((uint32_t)((uint32_t)0x7 << PORTx_PCRn_MUX_SHIFT)) /*!< Pin Mux Control (mask) */ -#define PORTx_PCRn_MUX(x) ((uint32_t)(((uint32_t)(x) << PORTx_PCRn_MUX_SHIFT) & PORTx_PCRn_MUX_MASK)) /*!< Pin Mux Control */ -#define PORTx_PCRn_DSE ((uint32_t)0x00000040) /*!< Drive Strength Enable */ -#define PORTx_PCRn_ODE ((uint32_t)0x00000020) /*!< Open Drain Enable */ -#define PORTx_PCRn_PFE ((uint32_t)0x00000010) /*!< Passive Filter Enable */ -#define PORTx_PCRn_SRE ((uint32_t)0x00000004) /*!< Slew Rate Enable */ -#define PORTx_PCRn_PE ((uint32_t)0x00000002) /*!< Pull Enable */ -#define PORTx_PCRn_PS ((uint32_t)0x00000001) /*!< Pull Select */ - -/****************************************************************/ -/* */ -/* Oscillator (OSC) */ -/* */ -/****************************************************************/ -/*********** Bits definition for OSC_CR register **************/ -#define OSC_CR_ERCLKEN ((uint8_t)0x80) /*!< External Reference Enable */ -#define OSC_CR_EREFSTEN ((uint8_t)0x20) /*!< External Reference Stop Enable */ -#define OSC_CR_SC2P ((uint8_t)0x08) /*!< Oscillator 2pF Capacitor Load Configure */ -#define OSC_CR_SC4P ((uint8_t)0x04) /*!< Oscillator 4pF Capacitor Load Configure */ -#define OSC_CR_SC8P ((uint8_t)0x02) /*!< Oscillator 8pF Capacitor Load Configure */ -#define OSC_CR_SC16P ((uint8_t)0x01) /*!< Oscillator 16pF Capacitor Load Configure */ - -/****************************************************************/ -/* */ -/* Direct Memory Access (DMA) */ -/* */ -/****************************************************************/ -/* ---------------------------------------------------------------------------- - -- DMA - Register accessor macros - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup DMA_Register_Accessor_Macros DMA - Register accessor macros - * @{ - */ - - -/* DMA - Register accessors */ -#define DMA_CR_REG(base) ((base)->CR) -#define DMA_ES_REG(base) ((base)->ES) -#define DMA_ERQ_REG(base) ((base)->ERQ) -#define DMA_EEI_REG(base) ((base)->EEI) -#define DMA_CEEI_REG(base) ((base)->CEEI) -#define DMA_SEEI_REG(base) ((base)->SEEI) -#define DMA_CERQ_REG(base) ((base)->CERQ) -#define DMA_SERQ_REG(base) ((base)->SERQ) -#define DMA_CDNE_REG(base) ((base)->CDNE) -#define DMA_SSRT_REG(base) ((base)->SSRT) -#define DMA_CERR_REG(base) ((base)->CERR) -#define DMA_CINT_REG(base) ((base)->CINT) -#define DMA_INT_REG(base) ((base)->INT) -#define DMA_ERR_REG(base) ((base)->ERR) -#define DMA_HRS_REG(base) ((base)->HRS) -#define DMA_DCHPRI3_REG(base) ((base)->DCHPRI3) -#define DMA_DCHPRI2_REG(base) ((base)->DCHPRI2) -#define DMA_DCHPRI1_REG(base) ((base)->DCHPRI1) -#define DMA_DCHPRI0_REG(base) ((base)->DCHPRI0) -#define DMA_SADDR_REG(base,index) ((base)->TCD[index].SADDR) -#define DMA_SOFF_REG(base,index) ((base)->TCD[index].SOFF) -#define DMA_ATTR_REG(base,index) ((base)->TCD[index].ATTR) -#define DMA_NBYTES_MLNO_REG(base,index) ((base)->TCD[index].NBYTES_MLNO) -#define DMA_NBYTES_MLOFFNO_REG(base,index) ((base)->TCD[index].NBYTES_MLOFFNO) -#define DMA_NBYTES_MLOFFYES_REG(base,index) ((base)->TCD[index].NBYTES_MLOFFYES) -#define DMA_SLAST_REG(base,index) ((base)->TCD[index].SLAST) -#define DMA_DADDR_REG(base,index) ((base)->TCD[index].DADDR) -#define DMA_DOFF_REG(base,index) ((base)->TCD[index].DOFF) -#define DMA_CITER_ELINKNO_REG(base,index) ((base)->TCD[index].CITER_ELINKNO) -#define DMA_CITER_ELINKYES_REG(base,index) ((base)->TCD[index].CITER_ELINKYES) -#define DMA_DLAST_SGA_REG(base,index) ((base)->TCD[index].DLAST_SGA) -#define DMA_CSR_REG(base,index) ((base)->TCD[index].CSR) -#define DMA_BITER_ELINKNO_REG(base,index) ((base)->TCD[index].BITER_ELINKNO) -#define DMA_BITER_ELINKYES_REG(base,index) ((base)->TCD[index].BITER_ELINKYES) - -/*! - * @} - */ /* end of group DMA_Register_Accessor_Macros */ - - -/* ---------------------------------------------------------------------------- - -- DMA Register Masks - ---------------------------------------------------------------------------- */ - -/*! - * @addtogroup DMA_Register_Masks DMA Register Masks - * @{ - */ - -/* CR Bit Fields */ -#define DMA_CR_EDBG_MASK 0x2u -#define DMA_CR_EDBG_SHIFT 1 -#define DMA_CR_ERCA_MASK 0x4u -#define DMA_CR_ERCA_SHIFT 2 -#define DMA_CR_HOE_MASK 0x10u -#define DMA_CR_HOE_SHIFT 4 -#define DMA_CR_HALT_MASK 0x20u -#define DMA_CR_HALT_SHIFT 5 -#define DMA_CR_CLM_MASK 0x40u -#define DMA_CR_CLM_SHIFT 6 -#define DMA_CR_EMLM_MASK 0x80u -#define DMA_CR_EMLM_SHIFT 7 -#define DMA_CR_ECX_MASK 0x10000u -#define DMA_CR_ECX_SHIFT 16 -#define DMA_CR_CX_MASK 0x20000u -#define DMA_CR_CX_SHIFT 17 -/* ES Bit Fields */ -#define DMA_ES_DBE_MASK 0x1u -#define DMA_ES_DBE_SHIFT 0 -#define DMA_ES_SBE_MASK 0x2u -#define DMA_ES_SBE_SHIFT 1 -#define DMA_ES_SGE_MASK 0x4u -#define DMA_ES_SGE_SHIFT 2 -#define DMA_ES_NCE_MASK 0x8u -#define DMA_ES_NCE_SHIFT 3 -#define DMA_ES_DOE_MASK 0x10u -#define DMA_ES_DOE_SHIFT 4 -#define DMA_ES_DAE_MASK 0x20u -#define DMA_ES_DAE_SHIFT 5 -#define DMA_ES_SOE_MASK 0x40u -#define DMA_ES_SOE_SHIFT 6 -#define DMA_ES_SAE_MASK 0x80u -#define DMA_ES_SAE_SHIFT 7 -#define DMA_ES_ERRCHN_MASK 0xF00u -#define DMA_ES_ERRCHN_SHIFT 8 -#define DMA_ES_ERRCHN(x) (((uint32_t)(((uint32_t)(x))<PDIR & ((uint32_t) 1 << pad)) ? PAL_HIGH : PAL_LOW; -} - -/** - * @brief Writes a logical state on an output pad. - * @note This function is not meant to be invoked directly by the - * application code. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @param[in] bit logical value, the value must be @p PAL_LOW or - * @p PAL_HIGH - * - * @notapi - */ -void _pal_lld_writepad(ioportid_t port, - uint8_t pad, - uint8_t bit) { - - if (bit == PAL_HIGH) - port->PDOR |= ((uint32_t) 1 << pad); - else - port->PDOR &= ~((uint32_t) 1 << pad); -} - -/** - * @brief Pad mode setup. - * @details This function programs a pad with the specified mode. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * @note Programming an unknown or unsupported mode is silently ignored. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @param[in] mode pad mode - * - * @notapi - */ -void _pal_lld_setpadmode(ioportid_t port, - uint8_t pad, - iomode_t mode) { - - PORT_TypeDef *portcfg = NULL; - - chDbgAssert(pad <= 31, "pal_lld_setpadmode() #1, invalid pad"); - - if (mode == PAL_MODE_OUTPUT_PUSHPULL) - port->PDDR |= ((uint32_t) 1 << pad); - else - port->PDDR &= ~((uint32_t) 1 << pad); - - if (port == IOPORT1) - portcfg = PORTA; - else if (port == IOPORT2) - portcfg = PORTB; - else if (port == IOPORT3) - portcfg = PORTC; - else if (port == IOPORT4) - portcfg = PORTD; - else if (port == IOPORT5) - portcfg = PORTE; - - chDbgAssert(portcfg != NULL, "pal_lld_setpadmode() #2, invalid port"); - - switch (mode) { - case PAL_MODE_RESET: - case PAL_MODE_INPUT: - case PAL_MODE_OUTPUT_PUSHPULL: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(1); - break; - case PAL_MODE_OUTPUT_OPENDRAIN: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(1) | - PORTx_PCRn_ODE; - break; - case PAL_MODE_INPUT_PULLUP: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(1) | - PORTx_PCRn_PE | - PORTx_PCRn_PS; - break; - case PAL_MODE_INPUT_PULLDOWN: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(1) | - PORTx_PCRn_PE; - break; - case PAL_MODE_UNCONNECTED: - case PAL_MODE_INPUT_ANALOG: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(0); - break; - case PAL_MODE_ALTERNATIVE_1: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(1); - break; - case PAL_MODE_ALTERNATIVE_2: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(2); - break; - case PAL_MODE_ALTERNATIVE_3: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(3); - break; - case PAL_MODE_ALTERNATIVE_4: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(4); - break; - case PAL_MODE_ALTERNATIVE_5: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(5); - break; - case PAL_MODE_ALTERNATIVE_6: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(6); - break; - case PAL_MODE_ALTERNATIVE_7: - portcfg->PCR[pad] = PIN_MUX_ALTERNATIVE(7); - break; - } -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Kinetis I/O ports configuration. - * @details Ports A-E clocks enabled. - * - * @param[in] config the Kinetis ports configuration - * - * @notapi - */ -void _pal_lld_init(const PALConfig *config) { - - int i, j; - - /* Enable clocking on all Ports */ - SIM->SCGC5 |= SIM_SCGC5_PORTA | - SIM_SCGC5_PORTB | - SIM_SCGC5_PORTC | - SIM_SCGC5_PORTD | - SIM_SCGC5_PORTE; - - /* Initial PORT and GPIO setup */ - for (i = 0; i < TOTAL_PORTS; i++) { - for (j = 0; j < PADS_PER_PORT; j++) { - pal_lld_setpadmode(config->ports[i].port, - j, - config->ports[i].pads[j]); - } - } -} - -/** - * @brief Pads mode setup. - * @details This function programs a pads group belonging to the same port - * with the specified mode. - * - * @param[in] port the port identifier - * @param[in] mask the group mask - * @param[in] mode the mode - * - * @notapi - */ -void _pal_lld_setgroupmode(ioportid_t port, - ioportmask_t mask, - iomode_t mode) { - - int i; - - (void)mask; - - for (i = 0; i < PADS_PER_PORT; i++) { - pal_lld_setpadmode(port, i, mode); - } -} - -#endif /* HAL_USE_PAL */ - -/** @} */ diff --git a/os/hal/ports/KINETIS/K20x/pal_lld.h b/os/hal/ports/KINETIS/K20x/pal_lld.h deleted file mode 100644 index 242583a..0000000 --- a/os/hal/ports/KINETIS/K20x/pal_lld.h +++ /dev/null @@ -1,375 +0,0 @@ -/* - 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 MK20D5/pal_lld.h - * @brief PAL subsystem low level driver header. - * - * @addtogroup PAL - * @{ - */ - -#ifndef _PAL_LLD_H_ -#define _PAL_LLD_H_ - -#if HAL_USE_PAL || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Unsupported modes and specific modes */ -/*===========================================================================*/ - -#define PAL_MODE_ALTERNATIVE_1 10 -#define PAL_MODE_ALTERNATIVE_2 11 -#define PAL_MODE_ALTERNATIVE_3 12 -#define PAL_MODE_ALTERNATIVE_4 13 -#define PAL_MODE_ALTERNATIVE_5 14 -#define PAL_MODE_ALTERNATIVE_6 15 -#define PAL_MODE_ALTERNATIVE_7 16 - -#define PIN_MUX_ALTERNATIVE(x) PORTx_PCRn_MUX(x) - -/*===========================================================================*/ -/* I/O Ports Types and constants. */ -/*===========================================================================*/ - -#define TOTAL_PORTS 5 -#define PADS_PER_PORT 32 - -/** - * @brief Width, in bits, of an I/O port. - */ -#define PAL_IOPORTS_WIDTH 32 - -/** - * @brief Whole port mask. - * @brief This macro specifies all the valid bits into a port. - */ -#define PAL_WHOLE_PORT ((ioportmask_t)0xFFFFFFFF) - -/** - * @brief Digital I/O port sized unsigned type. - */ -typedef uint32_t ioportmask_t; - -/** - * @brief Digital I/O modes. - */ -typedef uint32_t iomode_t; - -/** - * @brief Port Identifier. - * @details This type can be a scalar or some kind of pointer, do not make - * any assumption about it, use the provided macros when populating - * variables of this type. - */ -typedef GPIO_TypeDef *ioportid_t; - -/** - * @brief Port Configuration. - * @details This structure stores the configuration parameters of all pads - * belonging to a port. - */ -typedef struct { - ioportid_t port; - iomode_t pads[PADS_PER_PORT]; -} PortConfig; - -/** - * @brief Generic I/O ports static initializer. - * @details An instance of this structure must be passed to @p palInit() at - * system startup time in order to initialized the digital I/O - * subsystem. This represents only the initial setup, specific pads - * or whole ports can be reprogrammed at later time. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. - */ -typedef struct { - PortConfig ports[TOTAL_PORTS]; -} PALConfig; - -/*===========================================================================*/ -/* I/O Ports Identifiers. */ -/*===========================================================================*/ - -/** - * @brief GPIO port A identifier. - */ -#define IOPORT1 GPIOA - -/** - * @brief GPIO port B identifier. - */ -#define IOPORT2 GPIOB - -/** - * @brief GPIO port C identifier. - */ -#define IOPORT3 GPIOC - -/** - * @brief GPIO port D identifier. - */ -#define IOPORT4 GPIOD - -/** - * @brief GPIO port E identifier. - */ -#define IOPORT5 GPIOE - -/*===========================================================================*/ -/* Implementation, some of the following macros could be implemented as */ -/* functions, if so please put them in pal_lld.c. */ -/*===========================================================================*/ - -/** - * @brief Low level PAL subsystem initialization. - * - * @param[in] config architecture-dependent ports configuration - * - * @notapi - */ -#define pal_lld_init(config) _pal_lld_init(config) - -/** - * @brief Reads the physical I/O port states. - * - * @param[in] port port identifier - * @return The port bits. - * - * @notapi - */ -#define pal_lld_readport(port) (port)->PDIR - -/** - * @brief Reads the output latch. - * @details The purpose of this function is to read back the latched output - * value. - * - * @param[in] port port identifier - * @return The latched logical states. - * - * @notapi - */ -#define pal_lld_readlatch(port) (port)->PDOR - -/** - * @brief Writes a bits mask on a I/O port. - * - * @param[in] port port identifier - * @param[in] bits bits to be written on the specified port - * - * @notapi - */ -#define pal_lld_writeport(port, bits) (port)->PDOR = (bits) - -/** - * @brief Sets a bits mask on a I/O port. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] bits bits to be ORed on the specified port - * - * @notapi - */ -#define pal_lld_setport(port, bits) (port)->PSOR = (bits) - -/** - * @brief Clears a bits mask on a I/O port. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] bits bits to be cleared on the specified port - * - * @notapi - */ -#define pal_lld_clearport(port, bits) (port)->PCOR = (bits) - -/** - * @brief Toggles a bits mask on a I/O port. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] bits bits to be toggled on the specified port - * - * @notapi - */ -#define pal_lld_toggleport(port, bits) (port)->PTOR = (bits) - -/** - * @brief Reads a group of bits. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] mask group mask - * @param[in] offset group bit offset within the port - * @return The group logical states. - * - * @notapi - */ -#define pal_lld_readgroup(port, mask, offset) 0 - -/** - * @brief Writes a group of bits. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] mask group mask - * @param[in] offset group bit offset within the port - * @param[in] bits bits to be written. Values exceeding the group width - * are masked. - * - * @notapi - */ -#define pal_lld_writegroup(port, mask, offset, bits) (void)bits - -/** - * @brief Pads group mode setup. - * @details This function programs a pads group belonging to the same port - * with the specified mode. - * @note Programming an unknown or unsupported mode is silently ignored. - * - * @param[in] port port identifier - * @param[in] mask group mask - * @param[in] offset group bit offset within the port - * @param[in] mode group mode - * - * @notapi - */ -#define pal_lld_setgroupmode(port, mask, offset, mode) \ - _pal_lld_setgroupmode(port, mask << offset, mode) - -/** - * @brief Reads a logical state from an I/O pad. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @return The logical state. - * @retval PAL_LOW low logical state. - * @retval PAL_HIGH high logical state. - * - * @notapi - */ -#define pal_lld_readpad(port, pad) _pal_lld_readpad(port, pad) - -/** - * @brief Writes a logical state on an output pad. - * @note This function is not meant to be invoked directly by the - * application code. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @param[in] bit logical value, the value must be @p PAL_LOW or - * @p PAL_HIGH - * - * @notapi - */ -#define pal_lld_writepad(port, pad, bit) _pal_lld_writepad(port, pad, bit) - -/** - * @brief Sets a pad logical state to @p PAL_HIGH. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * - * @notapi - */ -#define pal_lld_setpad(port, pad) (port)->PSOR = ((uint32_t) 1 << (pad)) - -/** - * @brief Clears a pad logical state to @p PAL_LOW. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * - * @notapi - */ -#define pal_lld_clearpad(port, pad) (port)->PCOR = ((uint32_t) 1 << (pad)) - -/** - * @brief Toggles a pad logical state. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * - * @notapi - */ -#define pal_lld_togglepad(port, pad) (port)->PTOR = ((uint32_t) 1 << (pad)) - -/** - * @brief Pad mode setup. - * @details This function programs a pad with the specified mode. - * @note The @ref PAL provides a default software implementation of this - * functionality, implement this function if can optimize it by using - * special hardware functionalities or special coding. - * @note Programming an unknown or unsupported mode is silently ignored. - * - * @param[in] port port identifier - * @param[in] pad pad number within the port - * @param[in] mode pad mode - * - * @notapi - */ -#define pal_lld_setpadmode(port, pad, mode) \ - _pal_lld_setpadmode(port, pad, mode) - -#if !defined(__DOXYGEN__) -extern const PALConfig pal_default_config; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void _pal_lld_init(const PALConfig *config); - void _pal_lld_setgroupmode(ioportid_t port, - ioportmask_t mask, - iomode_t mode); - void _pal_lld_setpadmode(ioportid_t port, - uint8_t pad, - iomode_t mode); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_PAL */ - -#endif /* _PAL_LLD_H_ */ - -/** @} */ diff --git a/os/hal/ports/KINETIS/K20x/platform.mk b/os/hal/ports/KINETIS/K20x/platform.mk index 20502c2..baa90a2 100644 --- a/os/hal/ports/KINETIS/K20x/platform.mk +++ b/os/hal/ports/KINETIS/K20x/platform.mk @@ -1,14 +1,16 @@ # List of all platform files. PLATFORMSRC = ${CHIBIOS}/os/hal/ports/common/ARMCMx/nvic.c \ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K20x/hal_lld.c \ - ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K20x/pal_lld.c \ - ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K20x/serial_lld.c \ + ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/pal_lld.c \ + ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/serial_lld.c \ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K20x/spi_lld.c \ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/i2c_lld.c \ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/ext_lld.c \ ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/adc_lld.c \ - ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K20x/gpt_lld.c \ - ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K20x/st_lld.c + ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/gpt_lld.c \ + ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/K20x/pwm_lld.c \ + ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/st_lld.c \ + ${CHIBIOS_CONTRIB}/os/hal/ports/KINETIS/LLD/usb_lld.c # Required include directories PLATFORMINC = ${CHIBIOS}/os/hal/ports/common/ARMCMx \ diff --git a/os/hal/ports/KINETIS/K20x/pwm_lld.c b/os/hal/ports/KINETIS/K20x/pwm_lld.c new file mode 100644 index 0000000..f5a8d96 --- /dev/null +++ b/os/hal/ports/KINETIS/K20x/pwm_lld.c @@ -0,0 +1,390 @@ +/* + ChibiOS/HAL - Copyright (C) 2014 Adam J. Porter + + 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 K20x/pwm_lld.c + * @brief KINETIS PWM subsystem low level driver source. + * + * @addtogroup PWM + * @{ + */ + +#include "hal.h" + +#if HAL_USE_PWM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/** + * @brief PWMD1 driver identifier. + * @note The driver PWMD1 allocates the timer FTM0 when enabled. + */ +#if KINETIS_PWM_USE_FTM0 || defined(__DOXYGEN__) +PWMDriver PWMD1; +#endif + +/** + * @brief PWMD2 driver identifier. + * @note The driver PWMD2 allocates the timer FTM1 when enabled. + */ +#if KINETIS_PWM_USE_FTM1 || defined(__DOXYGEN__) +PWMDriver PWMD2; +#endif + +/** + * @brief PWMD3 driver identifier. + * @note The driver PWMD3 allocates the timer FTM2 when enabled. + */ +#if KINETIS_PWM_USE_FTM2 || defined(__DOXYGEN__) +PWMDriver PWMD3; +#endif + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +static void pwm_lld_serve_interrupt(PWMDriver *pwmp) { + uint32_t sr; + + sr = pwmp->ftm->SC; + pwmp->ftm->SC = sr&(~FTM_SC_TOF); + + if (((sr & FTM_SC_TOF) != 0) && /* Timer Overflow */ + ((sr & FTM_SC_TOIE) != 0) && + (pwmp->config->callback != NULL)) { + pwmp->config->callback(pwmp); + } + + uint8_t n=0; + for(n=0;nchannels;n++) { + sr = pwmp->ftm->CHANNEL[n].CnSC; + pwmp->ftm->CHANNEL[n].CnSC = sr&(~FTM_CnSC_CHF); + if (((sr & FTM_CnSC_CHF) != 0) && + ((sr & FTM_CnSC_CHIE) != 0) && + (pwmp->config->channels[n].callback != NULL)) { + pwmp->config->channels[n].callback(pwmp); + } + } +} + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +#if KINETIS_PWM_USE_FTM0 +/** + * @brief FTM0 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(KINETIS_FTM0_IRQ_VECTOR) { + OSAL_IRQ_PROLOGUE(); + pwm_lld_serve_interrupt(&PWMD1); + OSAL_IRQ_EPILOGUE(); +} +#endif /* KINETIS_PWM_USE_FTM0 */ + +#if KINETIS_PWM_USE_FTM1 +/** + * @brief FTM1 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(KINETIS_FTM1_IRQ_VECTOR) { + + OSAL_IRQ_PROLOGUE(); + pwm_lld_serve_interrupt(&PWMD2); + OSAL_IRQ_EPILOGUE(); +} +#endif /* KINETIS_PWM_USE_FTM1 */ + +#if KINETIS_PWM_USE_FTM2 +/** + * @brief FTM2 interrupt handler. + * + * @isr + */ +OSAL_IRQ_HANDLER(KINETIS_FTM2_IRQ_VECTOR) { + + OSAL_IRQ_PROLOGUE(); + pwm_lld_serve_interrupt(&PWMD3); + OSAL_IRQ_EPILOGUE(); +} +#endif /* KINETIS_PWM_USE_FTM2 */ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief Low level PWM driver initialization. + * + * @notapi + */ +void pwm_lld_init(void) { + +#if KINETIS_PWM_USE_FTM0 + pwmObjectInit(&PWMD1); + PWMD1.channels = KINETIS_FTM0_CHANNELS; + PWMD1.ftm = FTM0; +#endif + +#if KINETIS_PWM_USE_FTM1 + pwmObjectInit(&PWMD2); + PWMD2.channels = KINETIS_FTM1_CHANNELS; + PWMD2.ftm = FTM1; +#endif + +#if KINETIS_PWM_USE_FTM2 + pwmObjectInit(&PWMD3); + PWMD3.channels = KINETIS_FTM2_CHANNELS; + PWMD3.ftm = FTM2; +#endif +} + +/** + * @brief Configures and activates the PWM peripheral. + * @note Starting a driver that is already in the @p PWM_READY state + * disables all the active channels. + * + * @param[in] pwmp pointer to a @p PWMDriver object + * + * @notapi + */ +void pwm_lld_start(PWMDriver *pwmp) { + uint16_t psc; + uint8_t i=0; + + if (pwmp->state == PWM_STOP) { + /* Clock activation and timer reset.*/ +#if KINETIS_PWM_USE_FTM0 + if (&PWMD1 == pwmp) { + SIM->SCGC6 |= SIM_SCGC6_FTM0; + nvicEnableVector(FTM0_IRQn, KINETIS_PWM_FTM0_PRIORITY); + } +#endif + +#if KINETIS_PWM_USE_FTM1 + if (&PWMD2 == pwmp) { + SIM->SCGC6 |= SIM_SCGC6_FTM1; + nvicEnableVector(FTM1_IRQn, KINETIS_PWM_FTM1_PRIORITY); + } +#endif + +#if KINETIS_PWM_USE_FTM2 + if (&PWMD3 == pwmp) { + SIM->SCGC3 |= SIM_SCGC3_FTM2; + nvicEnableVector(FTM2_IRQn, KINETIS_PWM_FTM2_PRIORITY); + } +#endif + } + pwmp->ftm->MODE = FTM_MODE_FTMEN_MASK|FTM_MODE_PWMSYNC_MASK; + pwmp->ftm->SYNC = FTM_SYNC_CNTMIN_MASK|FTM_SYNC_CNTMAX_MASK + |FTM_SYNC_SWSYNC_MASK; + pwmp->ftm->COMBINE = FTM_COMBINE_SYNCEN3_MASK | FTM_COMBINE_SYNCEN2_MASK + | FTM_COMBINE_SYNCEN1_MASK | FTM_COMBINE_SYNCEN0_MASK; + pwmp->ftm->SYNCONF = FTM_SYNCONF_SYNCMODE_MASK; + + pwmp->ftm->CNTIN = 0x0000; + //~ pwmp->ftm->SC = 0; /* Disable FTM counter.*/ + pwmp->ftm->CNT = 0x0000; /* Clear count register.*/ + + /* Prescaler value calculation.*/ + psc = (KINETIS_SYSCLK_FREQUENCY / pwmp->config->frequency); + //~ /* Prescaler must be power of two between 1 and 128.*/ + osalDbgAssert(psc <= 128 && !(psc & (psc - 1)), "invalid frequency"); + //~ /* Prescaler register value determination. + //~ Prescaler register value conveniently corresponds to bit position, + //~ i.e., register value for prescaler CLK/64 is 6 ((1 << 6) == 64).*/ + for (i = 0; i < 8; i++) { + if (psc == (unsigned)(1 << i)) { + break; + } + } + + /* Set prescaler and clock mode. + This also sets the following: + CPWMS up-counting mode + Timer overflow interrupt disabled + DMA disabled.*/ + pwmp->ftm->SC = FTM_SC_CLKS(1) | FTM_SC_PS(i); + /* Configure period */ + pwmp->ftm->MOD = pwmp->period-1; + pwmp->ftm->PWMLOAD = FTM_PWMLOAD_LDOK_MASK; +} + +/** + * @brief Deactivates the PWM peripheral. + * + * @param[in] pwmp pointer to a @p PWMDriver object + * + * @notapi + */ +void pwm_lld_stop(PWMDriver *pwmp) { + + /* If in ready state then disables the PWM clock.*/ + if (pwmp->state == PWM_READY) { +#if KINETIS_PWM_USE_FTM0 + if (&PWMD1 == pwmp) { + SIM->SCGC6 &= ~SIM_SCGC6_FTM0; + nvicDisableVector(FTM0_IRQn); + } +#endif + +#if KINETIS_PWM_USE_FTM1 + if (&PWMD2 == pwmp) { + SIM->SCGC6 &= ~SIM_SCGC6_FTM1; + nvicDisableVector(FTM1_IRQn); + } +#endif + +#if KINETIS_PWM_USE_FTM2 + if (&PWMD3 == pwmp) { + SIM->SCGC3 &= ~SIM_SCGC3_FTM2; + nvicDisableVector(FTM2_IRQn); + } +#endif + /* Disable FTM counter.*/ + pwmp->ftm->SC = 0; + pwmp->ftm->MOD = 0; + } +} + +/** + * @brief Enables a PWM channel. + * @pre The PWM unit must have been activated using @p pwmStart(). + * @post The channel is active using the specified configuration. + * @note The function has effect at the next cycle start. + * @note Channel notification is not enabled. + * + * @param[in] pwmp pointer to a @p PWMDriver object + * @param[in] channel PWM channel identifier (0...channels-1) + * @param[in] width PWM pulse width as clock pulses number + * + * @notapi + */ +void pwm_lld_enable_channel(PWMDriver *pwmp, + pwmchannel_t channel, + pwmcnt_t width) { + uint32_t mode = FTM_CnSC_MSB; /* Edge-aligned PWM mode.*/ + + switch (pwmp->config->channels[channel].mode & PWM_OUTPUT_MASK) { + case PWM_OUTPUT_ACTIVE_HIGH: + mode |= FTM_CnSC_ELSB; + break; + case PWM_OUTPUT_ACTIVE_LOW: + mode |= FTM_CnSC_ELSA; + break; + } + + if (pwmp->ftm->CHANNEL[channel].CnSC & FTM_CnSC_CHIE) + mode |= FTM_CnSC_CHIE; + + pwmp->ftm->CHANNEL[channel].CnSC = mode; + pwmp->ftm->CHANNEL[channel].CnV = width; + pwmp->ftm->PWMLOAD = FTM_PWMLOAD_LDOK_MASK; +} + +/** + * @brief Disables a PWM channel and its notification. + * @pre The PWM unit must have been activated using @p pwmStart(). + * @post The channel is disabled and its output line returned to the + * idle state. + * @note The function has effect at the next cycle start. + * + * @param[in] pwmp pointer to a @p PWMDriver object + * @param[in] channel PWM channel identifier (0...channels-1) + * + * @notapi + */ +void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel) { + + pwmp->ftm->CHANNEL[channel].CnSC = 0; + pwmp->ftm->CHANNEL[channel].CnV = 0; +} + +/** + * @brief Enables the periodic activation edge notification. + * @pre The PWM unit must have been activated using @p pwmStart(). + * @note If the notification is already enabled then the call has no effect. + * + * @param[in] pwmp pointer to a @p PWMDriver object + * + * @notapi + */ +void pwm_lld_enable_periodic_notification(PWMDriver *pwmp) { + pwmp->ftm->SC |= FTM_SC_TOIE; +} + +/** + * @brief Disables the periodic activation edge notification. + * @pre The PWM unit must have been activated using @p pwmStart(). + * @note If the notification is already disabled then the call has no effect. + * + * @param[in] pwmp pointer to a @p PWMDriver object + * + * @notapi + */ +void pwm_lld_disable_periodic_notification(PWMDriver *pwmp) { + pwmp->ftm->SC &= ~FTM_SC_TOIE; +} + +/** + * @brief Enables a channel de-activation edge notification. + * @pre The PWM unit must have been activated using @p pwmStart(). + * @pre The channel must have been activated using @p pwmEnableChannel(). + * @note If the notification is already enabled then the call has no effect. + * + * @param[in] pwmp pointer to a @p PWMDriver object + * @param[in] channel PWM channel identifier (0...channels-1) + * + * @notapi + */ +void pwm_lld_enable_channel_notification(PWMDriver *pwmp, + pwmchannel_t channel) { + pwmp->ftm->CHANNEL[channel].CnSC |= FTM_CnSC_CHIE; +} + +/** + * @brief Disables a channel de-activation edge notification. + * @pre The PWM unit must have been activated using @p pwmStart(). + * @pre The channel must have been activated using @p pwmEnableChannel(). + * @note If the notification is already disabled then the call has no effect. + * + * @param[in] pwmp pointer to a @p PWMDriver object + * @param[in] channel PWM channel identifier (0...channels-1) + * + * @notapi + */ +void pwm_lld_disable_channel_notification(PWMDriver *pwmp, + pwmchannel_t channel) { + pwmp->ftm->CHANNEL[channel].CnSC &= ~FTM_CnSC_CHIE; +} + +#endif /* HAL_USE_PWM */ + +/** @} */ diff --git a/os/hal/ports/KINETIS/K20x/pwm_lld.h b/os/hal/ports/KINETIS/K20x/pwm_lld.h new file mode 100644 index 0000000..176e8a8 --- /dev/null +++ b/os/hal/ports/KINETIS/K20x/pwm_lld.h @@ -0,0 +1,270 @@ +/* + ChibiOS/HAL - Copyright (C) 2014 Adam J. Porter + + 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 K20x7/pwm_lld.h + * @brief KINETIS PWM subsystem low level driver header. + * + * @addtogroup PWM + * @{ + */ + +#ifndef _PWM_LLD_H_ +#define _PWM_LLD_H_ + +#if HAL_USE_PWM || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/** + * @brief Number of PWM channels per PWM driver. + */ +#define PWM_CHANNELS 8 + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +#if !defined(KINETIS_PWM_USE_FTM0) + #define KINETIS_PWM_USE_FTM0 FALSE +#endif + +#if !defined(KINETIS_PWM_USE_FTM1) + #define KINETIS_PWM_USE_FTM1 FALSE +#endif + +#if !defined(KINETIS_PWM_USE_FTM2) + #define KINETIS_PWM_USE_FTM2 FALSE +#endif + +/** + * @brief FTM0 interrupt priority level setting. + */ +#if !defined(KINETIS_PWM_FTM0_PRIORITY) || defined(__DOXYGEN__) +#define KINETIS_PWM_FTM0_PRIORITY 12 +#endif + +/** + * @brief FTM1 interrupt priority level setting. + */ +#if !defined(KINETIS_PWM_FTM1_PRIORITY) || defined(__DOXYGEN__) +#define KINETIS_PWM_FTM1_PRIORITY 12 +#endif + +/** + * @brief FTM2 interrupt priority level setting. + */ +#if !defined(KINETIS_PWM_FTM2_PRIORITY) || defined(__DOXYGEN__) +#define KINETIS_PWM_FTM2_PRIORITY 12 +#endif + +/** @} */ + +/** + * @name Configuration options + * @{ + */ +/** + * @brief If advanced timer features switch. + * @details If set to @p TRUE the advanced features for TIM1 and TIM8 are + * enabled. + * @note The default is @p TRUE. + */ +#if !defined(KINETIS_PWM_USE_ADVANCED) || defined(__DOXYGEN__) +#define KINETIS_PWM_USE_ADVANCED FALSE +#endif +/** @} */ + +/*===========================================================================*/ +/* Configuration checks. */ +/*===========================================================================*/ + +#if !KINETIS_PWM_USE_FTM0 && !KINETIS_PWM_USE_FTM1 && !KINETIS_PWM_USE_FTM2 +#error "PWM driver activated but no FTM peripheral assigned" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Type of a PWM mode. + */ +typedef uint32_t pwmmode_t; + +/** + * @brief Type of a PWM channel. + */ +typedef uint8_t pwmchannel_t; + +/** + * @brief Type of a channels mask. + */ +typedef uint32_t pwmchnmsk_t; + +/** + * @brief Type of a PWM counter. + */ +typedef uint16_t pwmcnt_t; + +/** + * @brief Type of a PWM driver channel configuration structure. + */ +typedef struct { + /** + * @brief Channel active logic level. + */ + pwmmode_t mode; + + /** + * @brief Channel callback pointer. + * @note This callback is invoked on the channel compare event. If set to + * @p NULL then the callback is disabled. + */ + pwmcallback_t callback; + /* End of the mandatory fields.*/ +} PWMChannelConfig; + +/** + * @brief Type of a PWM driver configuration structure. + */ +typedef struct { + /** + * @brief Timer clock in Hz. + * @note The low level can use assertions in order to catch invalid + * frequency specifications. + */ + uint32_t frequency; + /** + * @brief PWM period in ticks. + * @note The low level can use assertions in order to catch invalid + * period specifications. + */ + pwmcnt_t period; + /** + * @brief Periodic callback pointer. + * @note This callback is invoked on PWM counter reset. If set to + * @p NULL then the callback is disabled. + */ + pwmcallback_t callback; + /** + * @brief Channels configurations. + */ + PWMChannelConfig channels[PWM_CHANNELS]; + /* End of the mandatory fields.*/ +} PWMConfig; + +/** + * @brief Structure representing a PWM driver. + */ +struct PWMDriver { + /** + * @brief Driver state. + */ + pwmstate_t state; + /** + * @brief Current driver configuration data. + */ + const PWMConfig *config; + /** + * @brief Current PWM period in ticks. + */ + pwmcnt_t period; + /** + * @brief Mask of the enabled channels. + */ + pwmchnmsk_t enabled; + /** + * @brief Number of channels in this instance. + */ + pwmchannel_t channels; +#if defined(PWM_DRIVER_EXT_FIELDS) + PWM_DRIVER_EXT_FIELDS +#endif + /* End of the mandatory fields.*/ + /** + * @brief Pointer to the FTM registers block. + */ + FTM_TypeDef *ftm; +}; + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @brief Changes the period the PWM peripheral. + * @details This function changes the period of a PWM unit that has already + * been activated using @p pwmStart(). + * @pre The PWM unit must have been activated using @p pwmStart(). + * @post The PWM unit period is changed to the new value. + * @note The function has effect at the next cycle start. + * @note If a period is specified that is shorter than the pulse width + * programmed in one of the channels then the behavior is not + * guaranteed. + * + * @param[in] pwmp pointer to a @p PWMDriver object + * @param[in] period new cycle time in ticks + * + * @notapi + */ +#define pwm_lld_change_period(pwmp, period) \ + do { \ + (pwmp)->ftm->MOD = ((period) - 1); \ + pwmp->ftm->PWMLOAD = FTM_PWMLOAD_LDOK_MASK;\ + } while(0) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#if KINETIS_PWM_USE_FTM0 || defined(__DOXYGEN__) +extern PWMDriver PWMD1; +#endif +#if KINETIS_PWM_USE_FTM1 || defined(__DOXYGEN__) +extern PWMDriver PWMD2; +#endif +#if KINETIS_PWM_USE_FTM2 || defined(__DOXYGEN__) +extern PWMDriver PWMD3; +#endif + +#ifdef __cplusplus +extern "C" { +#endif + void pwm_lld_init(void); + void pwm_lld_start(PWMDriver *pwmp); + void pwm_lld_stop(PWMDriver *pwmp); + void pwm_lld_enable_channel(PWMDriver *pwmp, + pwmchannel_t channel, + pwmcnt_t width); + void pwm_lld_disable_channel(PWMDriver *pwmp, pwmchannel_t channel); + void pwm_lld_enable_periodic_notification(PWMDriver *pwmp); + void pwm_lld_disable_periodic_notification(PWMDriver *pwmp); + void pwm_lld_enable_channel_notification(PWMDriver *pwmp, + pwmchannel_t channel); + void pwm_lld_disable_channel_notification(PWMDriver *pwmp, + pwmchannel_t channel); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_PWM */ + +#endif /* _PWM_LLD_H_ */ + +/** @} */ diff --git a/os/hal/ports/KINETIS/K20x/serial_lld.c b/os/hal/ports/KINETIS/K20x/serial_lld.c deleted file mode 100644 index 0092747..0000000 --- a/os/hal/ports/KINETIS/K20x/serial_lld.c +++ /dev/null @@ -1,327 +0,0 @@ -/* - 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 K20x/serial_lld.c - * @brief Kinetis K20x Serial Driver subsystem low level driver source. - * - * @addtogroup SERIAL - * @{ - */ - -#include "osal.h" -#include "hal.h" - -#if HAL_USE_SERIAL || defined(__DOXYGEN__) - -#include "mk20d5.h" - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/** - * @brief SD1 driver identifier. - */ -#if KINETIS_SERIAL_USE_UART0 || defined(__DOXYGEN__) -SerialDriver SD1; -#endif - -#if KINETIS_SERIAL_USE_UART1 || defined(__DOXYGEN__) -SerialDriver SD2; -#endif - -#if KINETIS_SERIAL_USE_UART2 || defined(__DOXYGEN__) -SerialDriver SD3; -#endif - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/** - * @brief Driver default configuration. - */ -static const SerialConfig default_config = { - 38400 -}; - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/** - * @brief Common IRQ handler. - * @note Tries hard to clear all the pending interrupt sources, we don't - * want to go through the whole ISR and have another interrupt soon - * after. - * - * @param[in] u pointer to an UART I/O block - * @param[in] sdp communication channel associated to the UART - */ -static void serve_interrupt(SerialDriver *sdp) { - UART_TypeDef *u = sdp->uart; - uint8_t s1 = u->S1; - - if (s1 & UARTx_S1_RDRF) { - osalSysLockFromISR(); - if (iqIsEmptyI(&sdp->iqueue)) - chnAddFlagsI(sdp, CHN_INPUT_AVAILABLE); - if (iqPutI(&sdp->iqueue, u->D) < Q_OK) - chnAddFlagsI(sdp, SD_OVERRUN_ERROR); - osalSysUnlockFromISR(); - } - - if (s1 & UARTx_S1_TDRE) { - msg_t b; - - osalSysLockFromISR(); - b = oqGetI(&sdp->oqueue); - osalSysUnlockFromISR(); - - if (b < Q_OK) { - osalSysLockFromISR(); - chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); - osalSysUnlockFromISR(); - u->C2 &= ~UARTx_C2_TIE; - } else { - u->D = b; - } - } -} - -/** - * @brief Attempts a TX preload - */ -static void preload(SerialDriver *sdp) { - UART_TypeDef *u = sdp->uart; - - if (u->S1 & UARTx_S1_TDRE) { - msg_t b = oqGetI(&sdp->oqueue); - if (b < Q_OK) { - chnAddFlagsI(sdp, CHN_OUTPUT_EMPTY); - return; - } - u->D = b; - u->C2 |= UARTx_C2_TIE; - } -} - -/** - * @brief Driver output notification. - */ -#if KINETIS_SERIAL_USE_UART0 || defined(__DOXYGEN__) -static void notify1(io_queue_t *qp) -{ - (void)qp; - preload(&SD1); -} -#endif - -#if KINETIS_SERIAL_USE_UART1 || defined(__DOXYGEN__) -static void notify2(io_queue_t *qp) -{ - (void)qp; - preload(&SD2); -} -#endif - -#if KINETIS_SERIAL_USE_UART2 || defined(__DOXYGEN__) -static void notify3(io_queue_t *qp) -{ - (void)qp; - preload(&SD3); -} -#endif - -/** - * @brief Common UART configuration. - * - */ -static void configure_uart(UART_TypeDef *uart, const SerialConfig *config) -{ - uint32_t divisor = (KINETIS_SYSCLK_FREQUENCY * 2 + 1) / config->sc_speed; - - /* Disable UART while configuring */ - uart->C2 &= ~(UARTx_C2_RE | UARTx_C2_TE); - uart->C1 = 0; - - uart->BDH = UARTx_BDH_SBR(divisor >> 13) | (uart->BDH & ~UARTx_BDH_SBR_MASK); - uart->BDL = divisor >> 5; - uart->C4 = UARTx_C4_BRFA(divisor) | (uart->C4 & ~UARTx_C4_BRFA_MASK); - - uart->C2 |= UARTx_C2_RE | UARTx_C2_RIE | UARTx_C2_TE; - uart->C3 = UARTx_C3_ORIE | UARTx_C3_NEIE | UARTx_C3_FEIE | UARTx_C3_PEIE; -} - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -/* TODO: - * UART0_Error is Vector84 - * UART1_Error is Vector8C - * UART2_Error is Vector94 - */ - -#if KINETIS_SERIAL_USE_UART0 || defined(__DOXYGEN__) -OSAL_IRQ_HANDLER(Vector80) { - - OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD1); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if KINETIS_SERIAL_USE_UART1 || defined(__DOXYGEN__) -OSAL_IRQ_HANDLER(Vector88) { - - OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD2); - OSAL_IRQ_EPILOGUE(); -} -#endif - -#if KINETIS_SERIAL_USE_UART2 || defined(__DOXYGEN__) -OSAL_IRQ_HANDLER(Vector90) { - - OSAL_IRQ_PROLOGUE(); - serve_interrupt(&SD3); - OSAL_IRQ_EPILOGUE(); -} -#endif - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level serial driver initialization. - * - * @notapi - */ -void sd_lld_init(void) { - -#if KINETIS_SERIAL_USE_UART0 - /* Driver initialization.*/ - sdObjectInit(&SD1, NULL, notify1); - SD1.uart = UART0; -#endif - -#if KINETIS_SERIAL_USE_UART1 - /* Driver initialization.*/ - sdObjectInit(&SD2, NULL, notify2); - SD2.uart = UART1; -#endif - -#if KINETIS_SERIAL_USE_UART2 - /* Driver initialization.*/ - sdObjectInit(&SD3, NULL, notify3); - SD3.uart = UART2; -#endif -} - -/** - * @brief Low level serial driver configuration and (re)start. - * - * @param[in] sdp pointer to a @p SerialDriver object - * @param[in] config the architecture-dependent serial driver configuration. - * If this parameter is set to @p NULL then a default - * configuration is used. - * - * @notapi - */ -void sd_lld_start(SerialDriver *sdp, const SerialConfig *config) { - - if (config == NULL) - config = &default_config; - - if (sdp->state == SD_STOP) { - /* Enables the peripheral.*/ - -#if KINETIS_SERIAL_USE_UART0 - if (sdp == &SD1) { - SIM->SCGC4 |= SIM_SCGC4_UART0; - configure_uart(sdp->uart, config); - nvicEnableVector(UART0Status_IRQn, KINETIS_SERIAL_UART0_PRIORITY); - } -#endif /* KINETIS_SERIAL_USE_UART0 */ - -#if KINETIS_SERIAL_USE_UART1 - if (sdp == &SD2) { - SIM->SCGC4 |= SIM_SCGC4_UART1; - configure_uart(sdp->uart, config); - nvicEnableVector(UART1Status_IRQn, KINETIS_SERIAL_UART1_PRIORITY); - } -#endif /* KINETIS_SERIAL_USE_UART1 */ - -#if KINETIS_SERIAL_USE_UART2 - if (sdp == &SD3) { - SIM->SCGC4 |= SIM_SCGC4_UART2; - configure_uart(sdp->uart, config); - nvicEnableVector(UART2Status_IRQn, KINETIS_SERIAL_UART2_PRIORITY); - } -#endif /* KINETIS_SERIAL_USE_UART2 */ - - } - /* Configures the peripheral.*/ - -} - -/** - * @brief Low level serial driver stop. - * @details De-initializes the USART, stops the associated clock, resets the - * interrupt vector. - * - * @param[in] sdp pointer to a @p SerialDriver object - * - * @notapi - */ -void sd_lld_stop(SerialDriver *sdp) { - - if (sdp->state == SD_READY) { - /* TODO: Resets the peripheral.*/ - -#if KINETIS_SERIAL_USE_UART0 - if (sdp == &SD1) { - nvicDisableVector(UART0Status_IRQn); - SIM->SCGC4 &= ~SIM_SCGC4_UART0; - } -#endif - -#if KINETIS_SERIAL_USE_UART1 - if (sdp == &SD2) { - nvicDisableVector(UART1Status_IRQn); - SIM->SCGC4 &= ~SIM_SCGC4_UART1; - } -#endif - -#if KINETIS_SERIAL_USE_UART2 - if (sdp == &SD3) { - nvicDisableVector(UART2Status_IRQn); - SIM->SCGC4 &= ~SIM_SCGC4_UART2; - } -#endif - } -} - -#endif /* HAL_USE_SERIAL */ - -/** @} */ diff --git a/os/hal/ports/KINETIS/K20x/serial_lld.h b/os/hal/ports/KINETIS/K20x/serial_lld.h deleted file mode 100644 index 736cfe3..0000000 --- a/os/hal/ports/KINETIS/K20x/serial_lld.h +++ /dev/null @@ -1,163 +0,0 @@ -/* - 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 K20x/serial_lld.h - * @brief Kinetis K20x Serial Driver subsystem low level driver header. - * - * @addtogroup SERIAL - * @{ - */ - -#ifndef _SERIAL_LLD_H_ -#define _SERIAL_LLD_H_ - -#if HAL_USE_SERIAL || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief SD1 driver enable switch. - * @details If set to @p TRUE the support for SD1 is included. - */ -#if !defined(KINETIS_SERIAL_USE_UART0) || defined(__DOXYGEN__) -#define KINETIS_SERIAL_USE_UART0 FALSE -#endif -/** - * @brief SD2 driver enable switch. - * @details If set to @p TRUE the support for SD2 is included. - */ -#if !defined(KINETIS_SERIAL_USE_UART1) || defined(__DOXYGEN__) -#define KINETIS_SERIAL_USE_UART1 FALSE -#endif -/** - * @brief SD3 driver enable switch. - * @details If set to @p TRUE the support for SD3 is included. - */ -#if !defined(KINETIS_SERIAL_USE_UART2) || defined(__DOXYGEN__) -#define KINETIS_SERIAL_USE_UART2 FALSE -#endif - -/** - * @brief UART0 interrupt priority level setting. - */ -#if !defined(KINETIS_SERIAL_UART0_PRIORITY) || defined(__DOXYGEN__) -#define KINETIS_SERIAL_UART0_PRIORITY 12 -#endif - -/** - * @brief UART1 interrupt priority level setting. - */ -#if !defined(KINETIS_SERIAL_UART1_PRIORITY) || defined(__DOXYGEN__) -#define KINETIS_SERIAL_UART1_PRIORITY 12 -#endif - -/** - * @brief UART2 interrupt priority level setting. - */ -#if !defined(KINETIS_SERIAL_UART2_PRIORITY) || defined(__DOXYGEN__) -#define KINETIS_SERIAL_UART2_PRIORITY 12 -#endif - -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/** - * @brief Generic Serial Driver configuration structure. - * @details An instance of this structure must be passed to @p sdStart() - * in order to configure and start a serial driver operations. - * @note Implementations may extend this structure to contain more, - * architecture dependent, fields. - */ -typedef struct { - /** - * @brief Bit rate. - */ - uint32_t sc_speed; - /* End of the mandatory fields.*/ -} SerialConfig; - -/** - * @brief @p SerialDriver specific data. - */ -#define _serial_driver_data \ - _base_asynchronous_channel_data \ - /* Driver state.*/ \ - sdstate_t state; \ - /* Input queue.*/ \ - input_queue_t iqueue; \ - /* Output queue.*/ \ - output_queue_t oqueue; \ - /* Input circular buffer.*/ \ - uint8_t ib[SERIAL_BUFFERS_SIZE]; \ - /* Output circular buffer.*/ \ - uint8_t ob[SERIAL_BUFFERS_SIZE]; \ - /* End of the mandatory fields.*/ \ - /* Pointer to the UART registers block.*/ \ - UART_TypeDef *uart; - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#if KINETIS_SERIAL_USE_UART0 && !defined(__DOXYGEN__) -extern SerialDriver SD1; -#endif - -#if KINETIS_SERIAL_USE_UART1 && !defined(__DOXYGEN__) -extern SerialDriver SD2; -#endif - -#if KINETIS_SERIAL_USE_UART2 && !defined(__DOXYGEN__) -extern SerialDriver SD3; -#endif - -#ifdef __cplusplus -extern "C" { -#endif - void sd_lld_init(void); - void sd_lld_start(SerialDriver *sdp, const SerialConfig *config); - void sd_lld_stop(SerialDriver *sdp); -#ifdef __cplusplus -} -#endif - -#endif /* HAL_USE_SERIAL */ - -#endif /* _SERIAL_LLD_H_ */ - -/** @} */ diff --git a/os/hal/ports/KINETIS/K20x/spi_lld.c b/os/hal/ports/KINETIS/K20x/spi_lld.c index 132580f..29ab4e8 100644 --- a/os/hal/ports/KINETIS/K20x/spi_lld.c +++ b/os/hal/ports/KINETIS/K20x/spi_lld.c @@ -30,10 +30,6 @@ /* Driver local definitions. */ /*===========================================================================*/ -#if !defined(KINETIS_SPI_USE_SPI0) -#define KINETIS_SPI_USE_SPI0 TRUE -#endif - #if !defined(KINETIS_SPI0_RX_DMA_IRQ_PRIORITY) #define KINETIS_SPI0_RX_DMA_IRQ_PRIORITY 8 #endif @@ -54,8 +50,35 @@ #define KINETIS_SPI0_TX_DMA_CHANNEL 1 #endif +#if !defined(KINETIS_SPI1_RX_DMA_IRQ_PRIORITY) +#define KINETIS_SPI1_RX_DMA_IRQ_PRIORITY 8 +#endif + +#if !defined(KINETIS_SPI1_RX_DMAMUX_CHANNEL) +#define KINETIS_SPI1_RX_DMAMUX_CHANNEL 0 +#endif + +#if !defined(KINETIS_SPI1_RX_DMA_CHANNEL) +#define KINETIS_SPI1_RX_DMA_CHANNEL 0 +#endif + +#if !defined(KINETIS_SPI1_TX_DMAMUX_CHANNEL) +#define KINETIS_SPI1_TX_DMAMUX_CHANNEL 1 +#endif + +#if !defined(KINETIS_SPI1_TX_DMA_CHANNEL) +#define KINETIS_SPI1_TX_DMA_CHANNEL 1 +#endif + +#if KINETIS_SPI_USE_SPI0 #define DMAMUX_SPI_RX_SOURCE 16 #define DMAMUX_SPI_TX_SOURCE 17 +#endif + +#if KINETIS_SPI_USE_SPI1 +#define DMAMUX_SPI_RX_SOURCE 18 +#define DMAMUX_SPI_TX_SOURCE 19 +#endif /*===========================================================================*/ /* Driver exported variables. */ @@ -66,6 +89,11 @@ SPIDriver SPID1; #endif +/** @brief SPI1 driver identifier.*/ +#if KINETIS_SPI_USE_SPI1 || defined(__DOXYGEN__) +SPIDriver SPID2; +#endif + /*===========================================================================*/ /* Driver local variables and types. */ /*===========================================================================*/ @@ -137,7 +165,9 @@ static void spi_stop_xfer(SPIDriver *spip) /* Driver interrupt handlers. */ /*===========================================================================*/ -OSAL_IRQ_HANDLER(Vector40) { +#if KINETIS_SPI_USE_SPI0 || defined(__DOXYGEN__) + +OSAL_IRQ_HANDLER(KINETIS_DMA0_IRQ_VECTOR) { OSAL_IRQ_PROLOGUE(); /* Clear bit 0 in Interrupt Request Register (INT) by writing 0 to CINT */ @@ -150,6 +180,25 @@ OSAL_IRQ_HANDLER(Vector40) { OSAL_IRQ_EPILOGUE(); } +#endif + +#if KINETIS_SPI_USE_SPI1 || defined(__DOXYGEN__) + +OSAL_IRQ_HANDLER(KINETIS_DMA0_IRQ_VECTOR) { + OSAL_IRQ_PROLOGUE(); + + /* Clear bit 0 in Interrupt Request Register (INT) by writing 0 to CINT */ + DMA->CINT = KINETIS_SPI1_RX_DMA_CHANNEL; + + spi_stop_xfer(&SPID2); + + _spi_isr_code(&SPID2); + + OSAL_IRQ_EPILOGUE(); +} + +#endif + /*===========================================================================*/ /* Driver exported functions. */ /*===========================================================================*/ @@ -163,6 +212,9 @@ void spi_lld_init(void) { #if KINETIS_SPI_USE_SPI0 spiObjectInit(&SPID1); #endif +#if KINETIS_SPI_USE_SPI1 + spiObjectInit(&SPID2); +#endif } /** @@ -193,6 +245,22 @@ void spi_lld_start(SPIDriver *spip) { } #endif +#if KINETIS_SPI_USE_SPI1 + if (&SPID2 == spip) { + + /* Enable the clock for SPI0 */ + SIM->SCGC6 |= SIM_SCGC6_SPI1; + + SPID2.spi = SPI1; + + if (spip->config->tar0) { + spip->spi->CTAR[0] = spip->config->tar0; + } else { + spip->spi->CTAR[0] = KINETIS_SPI_TAR0_DEFAULT; + } + } +#endif + nvicEnableVector(DMA0_IRQn, KINETIS_SPI0_RX_DMA_IRQ_PRIORITY); SIM->SCGC6 |= SIM_SCGC6_DMAMUX; @@ -201,6 +269,7 @@ void spi_lld_start(SPIDriver *spip) { /* Clear DMA error flags */ DMA->ERR = 0x0F; +#if KINETIS_SPI_USE_SPI0 /* Rx, select SPI Rx FIFO */ DMAMUX->CHCFG[KINETIS_SPI0_RX_DMAMUX_CHANNEL] = DMAMUX_CHCFGn_ENBL | DMAMUX_CHCFGn_SOURCE(DMAMUX_SPI_RX_SOURCE); @@ -239,6 +308,48 @@ void spi_lld_start(SPIDriver *spip) { DMA_ATTR_DSIZE(dma_size); DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].NBYTES_MLNO = spip->word_size; DMA->TCD[KINETIS_SPI0_TX_DMA_CHANNEL].CSR = DMA_CSR_DREQ_MASK; +#endif + +#if KINETIS_SPI_USE_SPI1 + /* Rx, select SPI Rx FIFO */ + DMAMUX->CHCFG[KINETIS_SPI1_RX_DMAMUX_CHANNEL] = DMAMUX_CHCFGn_ENBL | + DMAMUX_CHCFGn_SOURCE(DMAMUX_SPI_RX_SOURCE); + + /* Tx, select SPI Tx FIFO */ + DMAMUX->CHCFG[KINETIS_SPI1_TX_DMAMUX_CHANNEL] = DMAMUX_CHCFGn_ENBL | + DMAMUX_CHCFGn_SOURCE(DMAMUX_SPI_TX_SOURCE); + + /* Extract the frame size from the TAR */ + uint16_t frame_size = ((spip->spi->CTAR[0] >> SPIx_CTARn_FMSZ_SHIFT) & + SPIx_CTARn_FMSZ_MASK) + 1; + + /* DMA transfer size is 16 bits for a frame size > 8 bits */ + uint16_t dma_size = frame_size > 8 ? 1 : 0; + + /* DMA word size is 2 for a 16 bit frame size */ + spip->word_size = frame_size > 8 ? 2 : 1; + + /* configure DMA RX fixed values */ + DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].SADDR = (uint32_t)&SPI1->POPR; + DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].SOFF = 0; + DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].SLAST = 0; + DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].DLASTSGA = 0; + DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].ATTR = DMA_ATTR_SSIZE(dma_size) | + DMA_ATTR_DSIZE(dma_size); + DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].NBYTES_MLNO = spip->word_size; + DMA->TCD[KINETIS_SPI1_RX_DMA_CHANNEL].CSR = DMA_CSR_DREQ_MASK | + DMA_CSR_INTMAJOR_MASK; + + /* configure DMA TX fixed values */ + DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].SLAST = 0; + DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].DADDR = (uint32_t)&SPI1->PUSHR; + DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].DOFF = 0; + DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].DLASTSGA = 0; + DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].ATTR = DMA_ATTR_SSIZE(dma_size) | + DMA_ATTR_DSIZE(dma_size); + DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].NBYTES_MLNO = spip->word_size; + DMA->TCD[KINETIS_SPI1_TX_DMA_CHANNEL].CSR = DMA_CSR_DREQ_MASK; +#endif } } @@ -264,10 +375,20 @@ void spi_lld_stop(SPIDriver *spip) { /* SPI halt.*/ spip->spi->MCR |= SPIx_MCR_HALT; } -#endif /* Disable the clock for SPI0 */ SIM->SCGC6 &= ~SIM_SCGC6_SPI0; +#endif + +#if KINETIS_SPI_USE_SPI1 + if (&SPID2 == spip) { + /* SPI halt.*/ + spip->spi->MCR |= SPIx_MCR_HALT; + } + + /* Disable the clock for SPI1 */ + SIM->SCGC6 &= ~SIM_SCGC6_SPI1; +#endif } } diff --git a/os/hal/ports/KINETIS/K20x/spi_lld.h b/os/hal/ports/KINETIS/K20x/spi_lld.h index 23c6812..a1f2a99 100644 --- a/os/hal/ports/KINETIS/K20x/spi_lld.h +++ b/os/hal/ports/KINETIS/K20x/spi_lld.h @@ -55,17 +55,39 @@ #define KINETIS_SPI_SPI0_IRQ_PRIORITY 10 #endif +/** + * @brief SPI1 driver enable switch. + * @details If set to @p TRUE the support for SPI0 is included. + * @note The default is @p FALSE. + */ +#if !defined(KINETIS_SPI_USE_SPI1) || defined(__DOXYGEN__) +#define KINETIS_SPI_USE_SPI1 FALSE +#endif + +/** + * @brief SPI1 interrupt priority level setting. + */ +#if !defined(KINETIS_SPI_SPI1_IRQ_PRIORITY) || defined(__DOXYGEN__) +#define KINETIS_SPI_SPI1_IRQ_PRIORITY 10 +#endif + /*===========================================================================*/ /* Derived constants and error checks. */ /*===========================================================================*/ -#define KINETIS_HAS_SPI0 TRUE - #if KINETIS_SPI_USE_SPI0 && !KINETIS_HAS_SPI0 #error "SPI0 not present in the selected device" #endif -#if !KINETIS_SPI_USE_SPI0 +#if KINETIS_SPI_USE_SPI1 && !KINETIS_HAS_SPI1 +#error "SPI1 not present in the selected device" +#endif + +#if KINETIS_SPI_USE_SPI0 && KINETIS_SPI_USE_SPI1 +#error "Only one SPI peripheral can be enabled" +#endif + +#if !(KINETIS_SPI_USE_SPI0 || KINETIS_SPI_USE_SPI1) #error "SPI driver activated but no SPI peripheral assigned" #endif @@ -74,6 +96,11 @@ #error "Invalid IRQ priority assigned to SPI0" #endif +#if KINETIS_SPI_USE_SPI1 && \ + !OSAL_IRQ_IS_VALID_PRIORITY(KINETIS_SPI_SPI1_IRQ_PRIORITY) +#error "Invalid IRQ priority assigned to SPI1" +#endif + /*===========================================================================*/ /* Driver data structures and types. */ /*===========================================================================*/ @@ -205,6 +232,10 @@ struct SPIDriver { extern SPIDriver SPID1; #endif +#if KINETIS_SPI_USE_SPI1 && !defined(__DOXYGEN__) +extern SPIDriver SPID2; +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/os/hal/ports/KINETIS/K20x/st_lld.c b/os/hal/ports/KINETIS/K20x/st_lld.c deleted file mode 100644 index 1f8cb63..0000000 --- a/os/hal/ports/KINETIS/K20x/st_lld.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - 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 KINETIS/KL2x/st_lld.c - * @brief ST Driver subsystem low level driver code. - * - * @addtogroup ST - * @{ - */ - -#include "hal.h" - -#if (OSAL_ST_MODE != OSAL_ST_MODE_NONE) || defined(__DOXYGEN__) - -/*===========================================================================*/ -/* Driver local definitions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver exported variables. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local variables and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver local functions. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver interrupt handlers. */ -/*===========================================================================*/ - -#if (OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC) || defined(__DOXYGEN__) -/** - * @brief System Timer vector. - * @details This interrupt is used for system tick in periodic mode. - * - * @isr - */ -OSAL_IRQ_HANDLER(SysTick_Handler) { - - OSAL_IRQ_PROLOGUE(); - - osalSysLockFromISR(); - osalOsTimerHandlerI(); - osalSysUnlockFromISR(); - - OSAL_IRQ_EPILOGUE(); -} -#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */ - -/*===========================================================================*/ -/* Driver exported functions. */ -/*===========================================================================*/ - -/** - * @brief Low level ST driver initialization. - * - * @notapi - */ -void st_lld_init(void) { -#if OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC - /* Periodic systick mode, the Cortex-Mx internal systick timer is used - in this mode.*/ - SysTick->LOAD = (KINETIS_SYSCLK_FREQUENCY / OSAL_ST_FREQUENCY) - 1; - SysTick->VAL = 0; - SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_ENABLE_Msk | - SysTick_CTRL_TICKINT_Msk; - - /* IRQ enabled.*/ - nvicSetSystemHandlerPriority(HANDLER_SYSTICK, KINETIS_ST_IRQ_PRIORITY); -#endif /* OSAL_ST_MODE == OSAL_ST_MODE_PERIODIC */ -} - -#endif /* OSAL_ST_MODE != OSAL_ST_MODE_NONE */ - -/** @} */ diff --git a/os/hal/ports/KINETIS/K20x/st_lld.h b/os/hal/ports/KINETIS/K20x/st_lld.h deleted file mode 100644 index 24044e5..0000000 --- a/os/hal/ports/KINETIS/K20x/st_lld.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - 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 KINETIS/st_lld.h - * @brief ST Driver subsystem low level driver header. - * @details This header is designed to be include-able without having to - * include other files from the HAL. - * - * @addtogroup ST - * @{ - */ - -#ifndef _ST_LLD_H_ -#define _ST_LLD_H_ - -#include "mcuconf.h" - -/*===========================================================================*/ -/* Driver constants. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver pre-compile time settings. */ -/*===========================================================================*/ - -/** - * @name Configuration options - * @{ - */ -/** - * @brief SysTick timer IRQ priority. - */ -#if !defined(KINETIS_ST_IRQ_PRIORITY) || defined(__DOXYGEN__) -#define KINETIS_ST_IRQ_PRIORITY 8 -#endif - -/** @} */ - -/*===========================================================================*/ -/* Derived constants and error checks. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver data structures and types. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Driver macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* External declarations. */ -/*===========================================================================*/ - -#ifdef __cplusplus -extern "C" { -#endif - void st_lld_init(void); -#ifdef __cplusplus -} -#endif - -/*===========================================================================*/ -/* Driver inline functions. */ -/*===========================================================================*/ - -/** - * @brief Returns the time counter value. - * - * @return The counter value. - * - * @notapi - */ -static inline systime_t st_lld_get_counter(void) { - - return (systime_t)0; -} - -/** - * @brief Starts the alarm. - * @note Makes sure that no spurious alarms are triggered after - * this call. - * - * @param[in] time the time to be set for the first alarm - * - * @notapi - */ -static inline void st_lld_start_alarm(systime_t time) { - - (void)time; -} - -/** - * @brief Stops the alarm interrupt. - * - * @notapi - */ -static inline void st_lld_stop_alarm(void) { - -} - -/** - * @brief Sets the alarm time. - * - * @param[in] time the time to be set for the next alarm - * - * @notapi - */ -static inline void st_lld_set_alarm(systime_t time) { - - (void)time; -} - -/** - * @brief Returns the current alarm time. - * - * @return The currently set alarm time. - * - * @notapi - */ -static inline systime_t st_lld_get_alarm(void) { - - return (systime_t)0; -} - -/** - * @brief Determines if the alarm is active. - * - * @return The alarm status. - * @retval false if the alarm is not active. - * @retval true is the alarm is active - * - * @notapi - */ -static inline bool st_lld_is_alarm_active(void) { - - return false; -} - -#endif /* _ST_LLD_H_ */ - -/** @} */ -- cgit v1.2.3