/* * Copyright (C) 2015 Eistec AB * * This file is subject to the terms and conditions of the GNU Lesser General * Public License v2.1. See the file LICENSE in the top level directory for more * details. */ /** * @defgroup cpu_k60 Freescale Kinetis K60 * @ingroup cpu * @brief CPU specific implementations for the Freescale Kinetis K60 * @{ * * @file * @brief Implementation specific CPU configuration options * * @author Joakim NohlgÄrd */ #ifndef CPU_CONF_H_ #define CPU_CONF_H_ #include "cpu_conf_common.h" #ifdef __cplusplus extern "C" { #endif #include #if defined(CPU_MODEL_K60DN512VLL10) || defined(CPU_MODEL_K60DN256VLL10) /* Rev. 2.x silicon */ #define K60_CPU_REV 2 #include "MK60D10.h" /** The expected CPUID value, can be used to implement a check that we are * running on the right hardware */ #define K60_EXPECTED_CPUID 0x410fc241u /* K60 rev 2.x replaced the RNG module in 1.x by the RNGA PRNG module */ #define KINETIS_RNGA (RNG) #elif defined(CPU_MODEL_K60DN512ZVLL10) || defined(CPU_MODEL_K60DN256ZVLL10) /* Rev. 1.x silicon */ #define K60_CPU_REV 1 #include "MK60DZ10.h" /** The expected CPUID value, can be used to implement a check that we are * running on the right hardware */ #define K60_EXPECTED_CPUID 0x410fc240u /* K60 rev 1.x has the cryptographically strong RNGB module */ #define KINETIS_RNGB (RNG) #else #error Unknown CPU model. Update Makefile.include in the board directory. #endif /* Compatibility definitions between the two different Freescale headers */ #include "MK60-comp.h" /** * @brief ARM Cortex-M specific CPU configuration * @{ */ #define CPU_DEFAULT_IRQ_PRIO (1U) #define CPU_IRQ_NUMOF (104U) #define CPU_FLASH_BASE (0x00000000) /** @} */ /** * @name GPIO pin mux function numbers */ /** @{ */ #define PIN_MUX_FUNCTION_ANALOG 0 #define PIN_MUX_FUNCTION_GPIO 1 /** @} */ /** * @name GPIO interrupt flank settings */ /** @{ */ #define PIN_INTERRUPT_RISING 0b1001 #define PIN_INTERRUPT_FALLING 0b1010 #define PIN_INTERRUPT_EDGE 0b1011 /** @} */ /** @name PORT module clock gates */ /** @{ */ #define PORTA_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTA_SHIFT)) #define PORTB_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTB_SHIFT)) #define PORTC_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTC_SHIFT)) #define PORTD_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTD_SHIFT)) #define PORTE_CLOCK_GATE (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_PORTE_SHIFT)) /** @} */ /** * @name UART driver settings */ /** @{ */ /** UART typedef from CPU header. */ #define KINETIS_UART UART_Type /** @} */ /** * @name Clock settings for the LPTMR0 timer * @{ */ #define LPTIMER_DEV (LPTMR0) /**< LPTIMER hardware module */ #define LPTIMER_CLKEN() (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_LPTIMER_SHIFT) = 1) /**< Enable LPTMR0 clock gate */ #define LPTIMER_CLKDIS() (BITBAND_REG32(SIM->SCGC5, SIM_SCGC5_LPTIMER_SHIFT) = 0) /**< Disable LPTMR0 clock gate */ #define LPTIMER_CLKSRC_MCGIRCLK 0 /**< internal reference clock (4MHz) */ #define LPTIMER_CLKSRC_LPO 1 /**< PMC 1kHz output */ #define LPTIMER_CLKSRC_ERCLK32K 2 /**< RTC clock 32768Hz */ #define LPTIMER_CLKSRC_OSCERCLK 3 /**< system oscillator output, clock from RF-Part */ #ifndef LPTIMER_CLKSRC #define LPTIMER_CLKSRC LPTIMER_CLKSRC_ERCLK32K /**< default clock source */ #endif #if (LPTIMER_CLKSRC == LPTIMER_CLKSRC_MCGIRCLK) #define LPTIMER_CLK_PRESCALE 1 #define LPTIMER_SPEED 1000000 #elif (LPTIMER_CLKSRC == LPTIMER_CLKSRC_OSCERCLK) #define LPTIMER_CLK_PRESCALE 1 #define LPTIMER_SPEED 1000000 #elif (LPTIMER_CLKSRC == LPTIMER_CLKSRC_ERCLK32K) #define LPTIMER_CLK_PRESCALE 0 #define LPTIMER_SPEED 32768 #else #define LPTIMER_CLK_PRESCALE 0 #define LPTIMER_SPEED 1000 #endif /** IRQ priority for hwtimer interrupts */ #define LPTIMER_IRQ_PRIO 1 /** IRQ channel for hwtimer interrupts */ #define LPTIMER_IRQ_CHAN LPTMR0_IRQn #if K60_CPU_REV == 1 /* * The CNR register latching in LPTMR0 was added in silicon rev 2.x. With * rev 1.x we do not need to do anything in order to read the current timer counter * value */ #define LPTIMER_CNR_NEEDS_LATCHING 0 #elif K60_CPU_REV == 2 #define LPTIMER_CNR_NEEDS_LATCHING 1 #endif /** @} */ /** * @name Power mode hardware details */ /** @{ */ #if K60_CPU_REV == 1 #define KINETIS_PMCTRL MC->PMCTRL #define KINETIS_PMCTRL_SET_MODE(x) (KINETIS_PMCTRL = MC_PMCTRL_LPLLSM(x) | MC_PMCTRL_LPWUI_MASK) /* Clear LLS protection, clear VLPS, VLPW, VLPR protection */ /* Note: This register can only be written once after each reset, so we must * enable all power modes that we wish to use. */ #define KINETIS_UNLOCK_PMPROT() (MC->PMPROT |= MC_PMPROT_ALLS_MASK | MC_PMPROT_AVLP_MASK) #elif K60_CPU_REV == 2 #define KINETIS_PMCTRL SMC->PMCTRL #define KINETIS_PMCTRL_SET_MODE(x) (KINETIS_PMCTRL = SMC_PMCTRL_STOPM(x) | SMC_PMCTRL_LPWUI_MASK) #define KINETIS_PMPROT_UNLOCK() (SMC->PMPROT |= SMC_PMPROT_ALLS_MASK | SMC_PMPROT_AVLP_MASK) #else #error Unknown K60 CPU revision! #endif /** * @name STOP mode bitfield values * @{ */ /** @brief Normal STOP */ #define KINETIS_POWER_MODE_NORMAL (0b000) /** @brief VLPS STOP */ #define KINETIS_POWER_MODE_VLPS (0b010) /** @brief LLS STOP */ #define KINETIS_POWER_MODE_LLS (0b011) /** @} */ /** * @brief Wake up source number for the LPTMR0 * * In order to let the hwtimer wake the CPU from low power modes, we need to * enable this wake up source. */ #define KINETIS_LLWU_WAKEUP_MODULE_LPTMR 0 /** * @brief IRQn name to enable LLWU IRQ in NVIC */ #define KINETIS_LLWU_IRQ LLW_IRQn /** * @brief Enable clock gate on LLWU module. */ #define LLWU_UNLOCK() (BITBAND_REG32(SIM->SCGC4, SIM_SCGC4_LLWU_SHIFT) = 1) /** * @brief Internal modules whose interrupts are mapped to LLWU wake up sources. * * Other modules CAN NOT be used to wake the CPU from LLS or VLLSx power modes. */ typedef enum llwu_wakeup_module { KINETIS_LPM_WAKEUP_MODULE_LPTMR = 0, KINETIS_LPM_WAKEUP_MODULE_CMP0 = 1, KINETIS_LPM_WAKEUP_MODULE_CMP1 = 2, KINETIS_LPM_WAKEUP_MODULE_CMP2 = 3, KINETIS_LPM_WAKEUP_MODULE_TSI = 4, KINETIS_LPM_WAKEUP_MODULE_RTC_ALARM = 5, KINETIS_LPM_WAKEUP_MODULE_RESERVED = 6, KINETIS_LPM_WAKEUP_MODULE_RTC_SECONDS = 7, KINETIS_LPM_WAKEUP_MODULE_END, } llwu_wakeup_module_t; /** * @brief enum that maps physical pins to wakeup pin numbers in LLWU module * * Other pins CAN NOT be used to wake the CPU from LLS or VLLSx power modes. */ typedef enum llwu_wakeup_pin { KINETIS_LPM_WAKEUP_PIN_PTE1 = 0, KINETIS_LPM_WAKEUP_PIN_PTE2 = 1, KINETIS_LPM_WAKEUP_PIN_PTE4 = 2, KINETIS_LPM_WAKEUP_PIN_PTA4 = 3, KINETIS_LPM_WAKEUP_PIN_PTA13 = 4, KINETIS_LPM_WAKEUP_PIN_PTB0 = 5, KINETIS_LPM_WAKEUP_PIN_PTC1 = 6, KINETIS_LPM_WAKEUP_PIN_PTC3 = 7, KINETIS_LPM_WAKEUP_PIN_PTC4 = 8, KINETIS_LPM_WAKEUP_PIN_PTC5 = 9, KINETIS_LPM_WAKEUP_PIN_PTC6 = 10, KINETIS_LPM_WAKEUP_PIN_PTC11 = 11, KINETIS_LPM_WAKEUP_PIN_PTD0 = 12, KINETIS_LPM_WAKEUP_PIN_PTD2 = 13, KINETIS_LPM_WAKEUP_PIN_PTD4 = 14, KINETIS_LPM_WAKEUP_PIN_PTD6 = 15, KINETIS_LPM_WAKEUP_PIN_END } llwu_wakeup_pin_t; /** @} */ /** * @name Bit band macros * @{ */ /* Generic bitband conversion routine */ /** @brief Convert bit-band region address and bit number to bit-band alias address * * @param[in] addr base address in non-bit-banded memory * @param[in] bit bit number within the word * * @return Address of the bit within the bit-band memory region */ #define BITBAND_ADDR(addr, bit) ((((uint32_t) (addr)) & 0xF0000000u) + 0x2000000 + ((((uint32_t) (addr)) & 0xFFFFF) << 5) + ((bit) << 2)) /** * @brief Bitband 32 bit access to variable stored in SRAM_U * * @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up) * @note var must be declared 'volatile' */ #define BITBAND_VAR32(var, bit) (*((uint32_t volatile*) BITBAND_ADDR(&(var), (bit)))) /** * @brief Bitband 16 bit access to variable stored in SRAM_U * * @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up) * @note var must be declared 'volatile' */ #define BITBAND_VAR16(var, bit) (*((uint16_t volatile*) BITBAND_ADDR(&(var), (bit)))) /** * @brief Bitband 8 bit access to variable stored in SRAM_U * * @note SRAM_L is not bit band aliased on the K60, only SRAM_U (0x20000000 and up) * @note var must be declared 'volatile' */ #define BITBAND_VAR8(var, bit) (*((uint8_t volatile*) BITBAND_ADDR(&(var), (bit)))) /** @} */ #ifdef __cplusplus } #endif #endif /* CPU_CONF_H_ */ /** @} */