/***************************************************************************//** * @file em_cmu.h * @brief Clock management unit (CMU) API * @version 4.0.0 ******************************************************************************* * @section License * (C) Copyright 2014 Silicon Labs, http://www.silabs.com ******************************************************************************* * * Permission is granted to anyone to use this software for any purpose, * including commercial applications, and to alter it and redistribute it * freely, subject to the following restrictions: * * 1. The origin of this software must not be misrepresented; you must not * claim that you wrote the original software. * 2. Altered source versions must be plainly marked as such, and must not be * misrepresented as being the original software. * 3. This notice may not be removed or altered from any source distribution. * * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no * obligation to support this Software. Silicon Labs is providing the * Software "AS IS", with no express or implied warranties of any kind, * including, but not limited to, any implied warranties of merchantability * or fitness for any particular purpose or warranties against infringement * of any proprietary rights of a third party. * * Silicon Labs will not be liable for any consequential, incidental, or * special damages, or any other relief, or for any claim by any third party, * arising from your use of this Software. * ******************************************************************************/ #ifndef __SILICON_LABS_EM_CMU_H_ #define __SILICON_LABS_EM_CMU_H_ #include "em_device.h" #if defined( CMU_PRESENT ) #include #include "em_bitband.h" #ifdef __cplusplus extern "C" { #endif /***************************************************************************//** * @addtogroup EM_Library * @{ ******************************************************************************/ /***************************************************************************//** * @addtogroup CMU * @{ ******************************************************************************/ /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ /* Select register ids, for internal use */ #define CMU_NOSEL_REG 0 #define CMU_HFCLKSEL_REG 1 #define CMU_LFACLKSEL_REG 2 #define CMU_LFBCLKSEL_REG 3 #define CMU_DBGCLKSEL_REG 4 #if defined( _CMU_CMD_USBCCLKSEL_MASK ) #define CMU_USBCCLKSEL_REG 5 #endif #if defined( _CMU_LFCLKSEL_LFC_MASK ) #define CMU_LFCCLKSEL_REG 6 #endif #define CMU_SEL_REG_POS 0 #define CMU_SEL_REG_MASK 0xf /* Divisor register ids, for internal use */ #define CMU_NODIV_REG 0 #define CMU_HFPERCLKDIV_REG 1 #define CMU_HFCORECLKDIV_REG 2 #define CMU_LFAPRESC0_REG 3 #define CMU_LFBPRESC0_REG 4 #if defined( _CMU_CTRL_HFCLKDIV_MASK ) #define CMU_HFCLKDIV_REG 5 #endif #define CMU_DIV_REG_POS 4 #define CMU_DIV_REG_MASK 0xf /* Enable register ids, for internal use */ #define CMU_NO_EN_REG 0 #define CMU_HFPERCLKDIV_EN_REG 1 #define CMU_HFPERCLKEN0_EN_REG 2 #define CMU_HFCORECLKEN0_EN_REG 3 #define CMU_LFACLKEN0_EN_REG 4 #define CMU_LFBCLKEN0_EN_REG 5 #define CMU_PCNT_EN_REG 6 #if defined( _CMU_LFCCLKEN0_MASK ) #define CMU_LFCCLKEN0_EN_REG 7 #endif #define CMU_EN_REG_POS 8 #define CMU_EN_REG_MASK 0xf /* Enable register bit position, for internal use */ #define CMU_EN_BIT_POS 12 #define CMU_EN_BIT_MASK 0x1f /* Clock branch bitfield position, for internal use */ #define CMU_HF_CLK_BRANCH 0 #define CMU_HFPER_CLK_BRANCH 1 #define CMU_HFCORE_CLK_BRANCH 2 #define CMU_LFA_CLK_BRANCH 3 #define CMU_RTC_CLK_BRANCH 4 #define CMU_LETIMER_CLK_BRANCH 5 #define CMU_LCDPRE_CLK_BRANCH 6 #define CMU_LCD_CLK_BRANCH 7 #define CMU_LESENSE_CLK_BRANCH 8 #define CMU_LFB_CLK_BRANCH 9 #define CMU_LEUART0_CLK_BRANCH 10 #define CMU_LEUART1_CLK_BRANCH 11 #define CMU_DBG_CLK_BRANCH 12 #define CMU_AUX_CLK_BRANCH 13 #define CMU_USBC_CLK_BRANCH 14 #define CMU_LFC_CLK_BRANCH 15 #define CMU_USBLE_CLK_BRANCH 16 #define CMU_CLK_BRANCH_POS 17 #define CMU_CLK_BRANCH_MASK 0x1f /** @endcond */ /******************************************************************************* ******************************** ENUMS ************************************ ******************************************************************************/ /** Clock divisors. These values are valid for prescalers. */ #define cmuClkDiv_1 1 /**< Divide clock by 1. */ #define cmuClkDiv_2 2 /**< Divide clock by 2. */ #define cmuClkDiv_4 4 /**< Divide clock by 4. */ #define cmuClkDiv_8 8 /**< Divide clock by 8. */ #define cmuClkDiv_16 16 /**< Divide clock by 16. */ #define cmuClkDiv_32 32 /**< Divide clock by 32. */ #define cmuClkDiv_64 64 /**< Divide clock by 64. */ #define cmuClkDiv_128 128 /**< Divide clock by 128. */ #define cmuClkDiv_256 256 /**< Divide clock by 256. */ #define cmuClkDiv_512 512 /**< Divide clock by 512. */ #define cmuClkDiv_1024 1024 /**< Divide clock by 1024. */ #define cmuClkDiv_2048 2048 /**< Divide clock by 2048. */ #define cmuClkDiv_4096 4096 /**< Divide clock by 4096. */ #define cmuClkDiv_8192 8192 /**< Divide clock by 8192. */ #define cmuClkDiv_16384 16384 /**< Divide clock by 16384. */ #define cmuClkDiv_32768 32768 /**< Divide clock by 32768. */ /** Clock divider configuration */ typedef uint32_t CMU_ClkDiv_TypeDef; /** High frequency RC bands. */ typedef enum { /** 1MHz RC band. */ cmuHFRCOBand_1MHz = _CMU_HFRCOCTRL_BAND_1MHZ, /** 7MHz RC band. */ cmuHFRCOBand_7MHz = _CMU_HFRCOCTRL_BAND_7MHZ, /** 11MHz RC band. */ cmuHFRCOBand_11MHz = _CMU_HFRCOCTRL_BAND_11MHZ, /** 14MHz RC band. */ cmuHFRCOBand_14MHz = _CMU_HFRCOCTRL_BAND_14MHZ, /** 21MHz RC band. */ cmuHFRCOBand_21MHz = _CMU_HFRCOCTRL_BAND_21MHZ, #if defined( _CMU_HFRCOCTRL_BAND_28MHZ ) /** 28MHz RC band. */ cmuHFRCOBand_28MHz = _CMU_HFRCOCTRL_BAND_28MHZ #endif } CMU_HFRCOBand_TypeDef; #if defined( _CMU_AUXHFRCOCTRL_BAND_MASK ) /** AUX High frequency RC bands. */ typedef enum { /** 1MHz RC band. */ cmuAUXHFRCOBand_1MHz = _CMU_AUXHFRCOCTRL_BAND_1MHZ, /** 7MHz RC band. */ cmuAUXHFRCOBand_7MHz = _CMU_AUXHFRCOCTRL_BAND_7MHZ, /** 11MHz RC band. */ cmuAUXHFRCOBand_11MHz = _CMU_AUXHFRCOCTRL_BAND_11MHZ, /** 14MHz RC band. */ cmuAUXHFRCOBand_14MHz = _CMU_AUXHFRCOCTRL_BAND_14MHZ, /** 21MHz RC band. */ cmuAUXHFRCOBand_21MHz = _CMU_AUXHFRCOCTRL_BAND_21MHZ, #if defined( _CMU_AUXHFRCOCTRL_BAND_28MHZ ) /** 28MHz RC band. */ cmuAUXHFRCOBand_28MHz = _CMU_AUXHFRCOCTRL_BAND_28MHZ #endif } CMU_AUXHFRCOBand_TypeDef; #endif #if defined( _CMU_USHFRCOCONF_BAND_MASK ) /** USB High frequency RC bands. */ typedef enum { /** 24MHz RC band. */ cmuUSHFRCOBand_24MHz = _CMU_USHFRCOCONF_BAND_24MHZ, /** 48MHz RC band. */ cmuUSHFRCOBand_48MHz = _CMU_USHFRCOCONF_BAND_48MHZ, } CMU_USHFRCOBand_TypeDef; #endif /** Clock points in CMU. Please refer to CMU overview in reference manual. */ typedef enum { /*******************/ /* HF clock branch */ /*******************/ /** High frequency clock */ #if defined( _CMU_CTRL_HFCLKDIV_MASK ) cmuClock_HF = (CMU_HFCLKDIV_REG << CMU_DIV_REG_POS) | (CMU_HFCLKSEL_REG << CMU_SEL_REG_POS) | (CMU_NO_EN_REG << CMU_EN_REG_POS) | (0 << CMU_EN_BIT_POS) | (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS), #else cmuClock_HF = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_HFCLKSEL_REG << CMU_SEL_REG_POS) | (CMU_NO_EN_REG << CMU_EN_REG_POS) | (0 << CMU_EN_BIT_POS) | (CMU_HF_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif /** Debug clock */ cmuClock_DBG = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_DBGCLKSEL_REG << CMU_SEL_REG_POS) | (CMU_NO_EN_REG << CMU_EN_REG_POS) | (0 << CMU_EN_BIT_POS) | (CMU_DBG_CLK_BRANCH << CMU_CLK_BRANCH_POS), /** AUX clock */ cmuClock_AUX = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_NO_EN_REG << CMU_EN_REG_POS) | (0 << CMU_EN_BIT_POS) | (CMU_AUX_CLK_BRANCH << CMU_CLK_BRANCH_POS), /**********************************/ /* HF peripheral clock sub-branch */ /**********************************/ /** High frequency peripheral clock */ cmuClock_HFPER = (CMU_HFPERCLKDIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKDIV_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKDIV_HFPERCLKEN_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #if defined(_CMU_HFPERCLKEN0_USART0_MASK) /** Universal sync/async receiver/transmitter 0 clock. */ cmuClock_USART0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_USART0_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_USARTRF0_MASK) /** Universal sync/async receiver/transmitter 0 clock. */ cmuClock_USARTRF0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_USARTRF0_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_USART1_MASK) /** Universal sync/async receiver/transmitter 1 clock. */ cmuClock_USART1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_USART1_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_USART2_MASK) /** Universal sync/async receiver/transmitter 2 clock. */ cmuClock_USART2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_USART2_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_UART0_MASK) /** Universal async receiver/transmitter 0 clock. */ cmuClock_UART0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_UART0_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_UART1_MASK) /** Universal async receiver/transmitter 1 clock. */ cmuClock_UART1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_UART1_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_TIMER0_MASK) /** Timer 0 clock. */ cmuClock_TIMER0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_TIMER0_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_TIMER1_MASK) /** Timer 1 clock. */ cmuClock_TIMER1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_TIMER1_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_TIMER2_MASK) /** Timer 2 clock. */ cmuClock_TIMER2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_TIMER2_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_TIMER3_MASK) /** Timer 3 clock. */ cmuClock_TIMER3 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_TIMER3_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_ACMP0_MASK) /** Analog comparator 0 clock. */ cmuClock_ACMP0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_ACMP0_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_ACMP1_MASK) /** Analog comparator 1 clock. */ cmuClock_ACMP1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_ACMP1_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_PRS_MASK) /** Peripheral reflex system clock. */ cmuClock_PRS = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_PRS_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_DAC0_MASK) /** Digital to analog converter 0 clock. */ cmuClock_DAC0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_DAC0_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_IDAC0_MASK) /** Digital to analog converter 0 clock. */ cmuClock_IDAC0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_IDAC0_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(GPIO_PRESENT) /** General purpose input/output clock. */ cmuClock_GPIO = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_GPIO_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(VCMP_PRESENT) /** Voltage comparator clock. */ cmuClock_VCMP = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_VCMP_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_ADC0_MASK) /** Analog to digital converter 0 clock. */ cmuClock_ADC0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_ADC0_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_I2C0_MASK) /** I2C 0 clock. */ cmuClock_I2C0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_I2C0_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_HFPERCLKEN0_I2C1_MASK) /** I2C 1 clock. */ cmuClock_I2C1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFPERCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFPERCLKEN0_I2C1_SHIFT << CMU_EN_BIT_POS) | (CMU_HFPER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif /**********************/ /* HF core sub-branch */ /**********************/ /** Core clock */ cmuClock_CORE = (CMU_HFCORECLKDIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_NO_EN_REG << CMU_EN_REG_POS) | (0 << CMU_EN_BIT_POS) | (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS), #if defined(AES_PRESENT) /** Advanced encryption standard accelerator clock. */ cmuClock_AES = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFCORECLKEN0_AES_SHIFT << CMU_EN_BIT_POS) | (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(DMA_PRESENT) /** Direct memory access controller clock. */ cmuClock_DMA = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFCORECLKEN0_DMA_SHIFT << CMU_EN_BIT_POS) | (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif /** Low energy clocking module clock. */ cmuClock_CORELE = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFCORECLKEN0_LE_SHIFT << CMU_EN_BIT_POS) | (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS), #if defined(EBI_PRESENT) /** External bus interface clock. */ cmuClock_EBI = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFCORECLKEN0_EBI_SHIFT << CMU_EN_BIT_POS) | (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(USB_PRESENT) /** USB Core clock. */ cmuClock_USBC = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_USBCCLKSEL_REG << CMU_SEL_REG_POS) | (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFCORECLKEN0_USBC_SHIFT << CMU_EN_BIT_POS) | (CMU_USBC_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(USB_PRESENT) /** USB clock. */ cmuClock_USB = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_HFCORECLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_HFCORECLKEN0_USB_SHIFT << CMU_EN_BIT_POS) | (CMU_HFCORE_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif /***************/ /* LF A branch */ /***************/ /** Low frequency A clock */ cmuClock_LFA = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_LFACLKSEL_REG << CMU_SEL_REG_POS) | (CMU_NO_EN_REG << CMU_EN_REG_POS) | (0 << CMU_EN_BIT_POS) | (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS), #if defined(RTC_PRESENT) /** Real time counter clock. */ cmuClock_RTC = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_LFACLKEN0_RTC_SHIFT << CMU_EN_BIT_POS) | (CMU_RTC_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_LFACLKEN0_LETIMER0_MASK) /** Low energy timer 0 clock. */ cmuClock_LETIMER0 = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_LFACLKEN0_LETIMER0_SHIFT << CMU_EN_BIT_POS) | (CMU_LETIMER_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_LFACLKEN0_LCD_MASK) /** Liquid crystal display, pre FDIV clock. */ cmuClock_LCDpre = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_NO_EN_REG << CMU_EN_REG_POS) | (0 << CMU_EN_BIT_POS) | (CMU_LCDPRE_CLK_BRANCH << CMU_CLK_BRANCH_POS), /** Liquid crystal display clock. Please notice that FDIV prescaler * must be set by special API. */ cmuClock_LCD = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_LFACLKEN0_LCD_SHIFT << CMU_EN_BIT_POS) | (CMU_LCD_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_PCNTCTRL_PCNT0CLKEN_MASK) /** Pulse counter 0 clock. */ cmuClock_PCNT0 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_PCNT_EN_REG << CMU_EN_REG_POS) | (_CMU_PCNTCTRL_PCNT0CLKEN_SHIFT << CMU_EN_BIT_POS) | (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_PCNTCTRL_PCNT1CLKEN_MASK) /** Pulse counter 1 clock. */ cmuClock_PCNT1 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_PCNT_EN_REG << CMU_EN_REG_POS) | (_CMU_PCNTCTRL_PCNT1CLKEN_SHIFT << CMU_EN_BIT_POS) | (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_PCNTCTRL_PCNT2CLKEN_MASK) /** Pulse counter 2 clock. */ cmuClock_PCNT2 = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_PCNT_EN_REG << CMU_EN_REG_POS) | (_CMU_PCNTCTRL_PCNT2CLKEN_SHIFT << CMU_EN_BIT_POS) | (CMU_LFA_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_LFACLKEN0_LESENSE_MASK) /** LESENSE clock. */ cmuClock_LESENSE = (CMU_LFAPRESC0_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_LFACLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_LFACLKEN0_LESENSE_SHIFT << CMU_EN_BIT_POS) | (CMU_LESENSE_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif /***************/ /* LF B branch */ /***************/ /** Low frequency B clock */ cmuClock_LFB = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_LFBCLKSEL_REG << CMU_SEL_REG_POS) | (CMU_NO_EN_REG << CMU_EN_REG_POS) | (0 << CMU_EN_BIT_POS) | (CMU_LFB_CLK_BRANCH << CMU_CLK_BRANCH_POS), #if defined(_CMU_LFBCLKEN0_LEUART0_MASK) /** Low energy universal asynchronous receiver/transmitter 0 clock. */ cmuClock_LEUART0 = (CMU_LFBPRESC0_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_LFBCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_LFBCLKEN0_LEUART0_SHIFT << CMU_EN_BIT_POS) | (CMU_LEUART0_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_LFBCLKEN0_LEUART1_MASK) /** Low energy universal asynchronous receiver/transmitter 1 clock. */ cmuClock_LEUART1 = (CMU_LFBPRESC0_REG << CMU_DIV_REG_POS) | (CMU_NOSEL_REG << CMU_SEL_REG_POS) | (CMU_LFBCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_LFBCLKEN0_LEUART1_SHIFT << CMU_EN_BIT_POS) | (CMU_LEUART1_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif /***************/ /* LF C branch */ /***************/ /** Low frequency C clock */ #if defined( _CMU_LFCLKSEL_LFC_MASK ) cmuClock_LFC = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_LFCCLKSEL_REG << CMU_SEL_REG_POS) | (CMU_NO_EN_REG << CMU_EN_REG_POS) | (0 << CMU_EN_BIT_POS) | (CMU_LFC_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif #if defined(_CMU_LFCCLKEN0_USBLE_MASK) /** USB LE clock. */ cmuClock_USBLE = (CMU_NODIV_REG << CMU_DIV_REG_POS) | (CMU_LFCCLKSEL_REG << CMU_SEL_REG_POS) | (CMU_LFCCLKEN0_EN_REG << CMU_EN_REG_POS) | (_CMU_LFCCLKEN0_USBLE_SHIFT << CMU_EN_BIT_POS) | (CMU_USBLE_CLK_BRANCH << CMU_CLK_BRANCH_POS), #endif } CMU_Clock_TypeDef; /** Oscillator types. */ typedef enum { cmuOsc_LFXO, /**< Low frequency crystal oscillator. */ cmuOsc_LFRCO, /**< Low frequency RC oscillator. */ cmuOsc_HFXO, /**< High frequency crystal oscillator. */ cmuOsc_HFRCO, /**< High frequency RC oscillator. */ cmuOsc_AUXHFRCO, /**< Auxiliary high frequency RC oscillator. */ #if defined( _CMU_STATUS_USHFRCOENS_MASK ) cmuOsc_USHFRCO, /**< USB high frequency RC oscillator */ #endif #if defined( _CMU_LFCLKSEL_LFAE_ULFRCO ) cmuOsc_ULFRCO /**< Ultra low frequency RC oscillator. */ #endif } CMU_Osc_TypeDef; /** Selectable clock sources. */ typedef enum { cmuSelect_Error, /**< Usage error. */ cmuSelect_Disabled, /**< Clock selector disabled. */ cmuSelect_LFXO, /**< Low frequency crystal oscillator. */ cmuSelect_LFRCO, /**< Low frequency RC oscillator. */ cmuSelect_HFXO, /**< High frequency crystal oscillator. */ cmuSelect_HFRCO, /**< High frequency RC oscillator. */ cmuSelect_CORELEDIV2, /**< Core low energy clock divided by 2. */ cmuSelect_AUXHFRCO, /**< Auxilliary clock source can be used for debug clock */ cmuSelect_HFCLK, /**< Divided HFCLK on Giant for debug clock, undivided on Tiny Gecko and for USBC (not used on Gecko) */ #if defined( _CMU_STATUS_USHFRCOENS_MASK ) cmuSelect_USHFRCO, /**< USB high frequency RC oscillator */ #endif #if defined( _CMU_CMD_HFCLKSEL_USHFRCODIV2 ) cmuSelect_USHFRCODIV2,/**< USB high frequency RC oscillator */ #endif #if defined( _CMU_LFCLKSEL_LFAE_ULFRCO ) cmuSelect_ULFRCO, /**< Ultra low frequency RC oscillator. */ #endif } CMU_Select_TypeDef; /******************************************************************************* ***************************** PROTOTYPES ********************************** ******************************************************************************/ void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable); uint32_t CMU_ClockFreqGet(CMU_Clock_TypeDef clock); CMU_ClkDiv_TypeDef CMU_ClockDivGet(CMU_Clock_TypeDef clock); CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock); void CMU_ClockDivSet(CMU_Clock_TypeDef clock, CMU_ClkDiv_TypeDef div); void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref); CMU_HFRCOBand_TypeDef CMU_HFRCOBandGet(void); void CMU_HFRCOBandSet(CMU_HFRCOBand_TypeDef band); #if defined( _CMU_AUXHFRCOCTRL_BAND_MASK ) CMU_AUXHFRCOBand_TypeDef CMU_AUXHFRCOBandGet(void); void CMU_AUXHFRCOBandSet(CMU_AUXHFRCOBand_TypeDef band); #endif #if defined( _CMU_USHFRCOCONF_BAND_MASK ) CMU_USHFRCOBand_TypeDef CMU_USHFRCOBandGet(void); void CMU_USHFRCOBandSet(CMU_USHFRCOBand_TypeDef band); #endif void CMU_HFRCOStartupDelaySet(uint32_t delay); uint32_t CMU_HFRCOStartupDelayGet(void); void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait); uint32_t CMU_OscillatorTuningGet(CMU_Osc_TypeDef osc); void CMU_OscillatorTuningSet(CMU_Osc_TypeDef osc, uint32_t val); bool CMU_PCNTClockExternalGet(unsigned int inst); void CMU_PCNTClockExternalSet(unsigned int inst, bool external); uint32_t CMU_LCDClkFDIVGet(void); void CMU_LCDClkFDIVSet(uint32_t div); void CMU_FreezeEnable(bool enable); uint32_t CMU_Calibrate(uint32_t HFCycles, CMU_Osc_TypeDef reference); #if defined( _CMU_CALCTRL_UPSEL_MASK ) && defined( _CMU_CALCTRL_DOWNSEL_MASK ) void CMU_CalibrateConfig(uint32_t downCycles, CMU_Osc_TypeDef downSel, CMU_Osc_TypeDef upSel); #endif /***************************************************************************//** * @brief * Clear one or more pending CMU interrupts. * * @param[in] flags * CMU interrupt sources to clear. ******************************************************************************/ __STATIC_INLINE void CMU_IntClear(uint32_t flags) { CMU->IFC = flags; } /***************************************************************************//** * @brief * Disable one or more CMU interrupts. * * @param[in] flags * CMU interrupt sources to disable. ******************************************************************************/ __STATIC_INLINE void CMU_IntDisable(uint32_t flags) { CMU->IEN &= ~flags; } /***************************************************************************//** * @brief * Enable one or more CMU interrupts. * * @note * Depending on the use, a pending interrupt may already be set prior to * enabling the interrupt. Consider using CMU_IntClear() prior to enabling * if such a pending interrupt should be ignored. * * @param[in] flags * CMU interrupt sources to enable. ******************************************************************************/ __STATIC_INLINE void CMU_IntEnable(uint32_t flags) { CMU->IEN |= flags; } /***************************************************************************//** * @brief * Get pending CMU interrupts. * * @return * CMU interrupt sources pending. ******************************************************************************/ __STATIC_INLINE uint32_t CMU_IntGet(void) { return CMU->IF; } /***************************************************************************//** * @brief * Get enabled and pending CMU interrupt flags. * * @details * Useful for handling more interrupt sources in the same interrupt handler. * * @note * The event bits are not cleared by the use of this function. * * @return * Pending and enabled CMU interrupt sources. * The return value is the bitwise AND combination of * - the OR combination of enabled interrupt sources in CMU_IEN_nnn * register (CMU_IEN_nnn) and * - the OR combination of valid interrupt flags of the CMU module * (CMU_IF_nnn). ******************************************************************************/ __STATIC_INLINE uint32_t CMU_IntGetEnabled(void) { uint32_t tmp = 0U; /* Store LESENSE->IEN in temporary variable in order to define explicit order * of volatile accesses. */ tmp = CMU->IEN; /* Bitwise AND of pending and enabled interrupts */ return CMU->IF & tmp; } /**************************************************************************//** * @brief * Set one or more pending CMU interrupts from SW. * * @param[in] flags * CMU interrupt sources to set to pending. *****************************************************************************/ __STATIC_INLINE void CMU_IntSet(uint32_t flags) { CMU->IFS = flags; } /***************************************************************************//** * @brief * Lock the CMU in order to protect some of its registers against unintended * modification. * * @details * Please refer to the reference manual for CMU registers that will be * locked. * * @note * If locking the CMU registers, they must be unlocked prior to using any * CMU API functions modifying CMU registers protected by the lock. ******************************************************************************/ __STATIC_INLINE void CMU_Lock(void) { CMU->LOCK = CMU_LOCK_LOCKKEY_LOCK; } /***************************************************************************//** * @brief * Unlock the CMU so that writing to locked registers again is possible. ******************************************************************************/ __STATIC_INLINE void CMU_Unlock(void) { CMU->LOCK = CMU_LOCK_LOCKKEY_UNLOCK; } /***************************************************************************//** * @brief * Get calibration count register * @note * If continuous calibrartion mode is active, calibration busy will allmost * always be on, and we just need to read the value, where the normal case * would be that this function call has been triggered by the CALRDY * interrupt flag. * @return * Calibration count, the number of UPSEL clocks (see CMU_CalibrateConfig) * in the period of DOWNSEL oscillator clock cycles configured by a previous * write operation to CMU->CALCNT ******************************************************************************/ __STATIC_INLINE uint32_t CMU_CalibrateCountGet(void) { /* Wait until calibration completes, UNLESS continuous calibration mode is */ /* active */ #if defined( CMU_CALCTRL_CONT ) if (!(CMU->CALCTRL & CMU_CALCTRL_CONT)) { while (CMU->STATUS & CMU_STATUS_CALBSY) ; } #else while (CMU->STATUS & CMU_STATUS_CALBSY) ; #endif return CMU->CALCNT; } /***************************************************************************//** * @brief * Starts calibration * @note * This call is usually invoked after CMU_CalibrateConfig() and possibly * CMU_CalibrateCont() ******************************************************************************/ __STATIC_INLINE void CMU_CalibrateStart(void) { CMU->CMD = CMU_CMD_CALSTART; } #if defined( CMU_CMD_CALSTOP ) /***************************************************************************//** * @brief * Stop the calibration counters ******************************************************************************/ __STATIC_INLINE void CMU_CalibrateStop(void) { CMU->CMD = CMU_CMD_CALSTOP; } #endif #if defined( CMU_CALCTRL_CONT ) /***************************************************************************//** * @brief * Configures continuous calibration mode * @param[in] enable * If true, enables continuous calibration, if false disables continuous * calibrartion ******************************************************************************/ __STATIC_INLINE void CMU_CalibrateCont(bool enable) { BITBAND_Peripheral(&(CMU->CALCTRL), _CMU_CALCTRL_CONT_SHIFT, enable); } #endif /** @} (end addtogroup CMU) */ /** @} (end addtogroup EM_Library) */ #ifdef __cplusplus } #endif #endif /* defined( CMU_PRESENT ) */ #endif /* __SILICON_LABS_EM_CMU_H_ */