/** * \file * * \brief Chip-specific system clock management functions * * Copyright (c) 2010-2015 Atmel Corporation. All rights reserved. * * \asf_license_start * * \page License * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * 3. The name of Atmel may not be used to endorse or promote products derived * from this software without specific prior written permission. * * 4. This software may only be redistributed and used in connection with an * Atmel microcontroller product. * * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * \asf_license_stop * */ /* * Support and FAQ: visit Atmel Support */ #ifndef XMEGA_SYSCLK_H_INCLUDED #define XMEGA_SYSCLK_H_INCLUDED #include #include #include #include #include #include // Include clock configuration for the project. #include #ifdef __cplusplus extern "C" { #endif /** * \page sysclk_quickstart Quick Start Guide for the System Clock Management service (XMEGA) * * This is the quick start guide for the \ref sysclk_group "System Clock Management" * service, with step-by-step instructions on how to configure and use the service for * specific use cases. * * \section sysclk_quickstart_usecases System Clock Management use cases * - \ref sysclk_quickstart_basic * - \ref sysclk_quickstart_use_case_2 * - \ref sysclk_quickstart_use_case_3 * * \section sysclk_quickstart_basic Basic usage of the System Clock Management service * This section will present a basic use case for the System Clock Management service. * This use case will configure the main system clock to 32MHz, using an internal PLL * module to multiply the frequency of a crystal attached to the microcontroller. The * secondary peripheral bus clock and CPU clock are scaled down from the speed of the * main system clock. * * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites * - None * * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code * Add to the application initialization code: * \code sysclk_init(); \endcode * * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow * -# Configure the system clocks according to the settings in conf_clock.h: * \code sysclk_init(); \endcode * * \subsection sysclk_quickstart_use_case_1_example_code Example code * Add or uncomment the following in your conf_clock.h header file, commenting out all other * definitions of the same symbol(s): * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL // Fpll0 = (Fclk * PLL_mul) / PLL_div #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) #define CONFIG_PLL0_DIV 1 // Fbus = Fsys / (2 ^ BUS_div) #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 \endcode * * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow * -# Configure the main system clock to use the output of the PLL module as its source: * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: * \code #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) #define CONFIG_PLL0_DIV 1 \endcode * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration * file as the frequency of the crystal attached to XOSC. * -# Configure the main CPU clock and slow peripheral bus to run at 16MHz, run the fast peripheral bus * at the full 32MHz speed: * \code #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 \endcode * \note Some dividers are powers of two, while others are integer division factors. Refer to the * formulas in the conf_clock.h template commented above each division define. */ /** * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management (XMEGA) * * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock Management * This section will present a more advanced use case for the System Clock Management service. * This use case will configure the main system clock to 32MHz, using an internal PLL * module to multiply the frequency of a crystal attached to the microcontroller. The peripheral bus * clocks will run at the same speed as the CPU clock, and the USB clock will be configured to use * the internal 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB Start-of-Frame as the * calibration reference. * * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites * - None * * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code * Add to the application initialization code: * \code sysclk_init(); \endcode * * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow * -# Configure the system clocks according to the settings in conf_clock.h: * \code sysclk_init(); \endcode * * \subsection sysclk_quickstart_use_case_2_example_code Example code * Add or uncomment the following in your conf_clock.h header file, commenting out all other * definitions of the same symbol(s): * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL // Fpll0 = (Fclk * PLL_mul) / PLL_div #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) #define CONFIG_PLL0_DIV 1 // Fbus = Fsys / (2 ^ BUS_div) #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC #define CONFIG_OSC_RC32_CAL 48000000UL #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF \endcode * * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow * -# Configure the main system clock to use the output of the PLL module as its source: * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLL \endcode * -# Configure the PLL0 module to use external crystal oscillator XOSC as its source: * \code #define CONFIG_PLL0_SOURCE PLL_SRC_XOSC \endcode * -# Configure the PLL0 module to multiply the external oscillator XOSC frequency up to 32MHz: * \code #define CONFIG_PLL0_MUL (32000000UL / BOARD_XOSC_HZ) #define CONFIG_PLL0_DIV 1 \endcode * \note For user boards, \c BOARD_XOSC_HZ should be defined in the board \c conf_board.h configuration * file as the frequency of the crystal attached to XOSC. * -# Configure the main CPU and peripheral bus clocks to run at 32MHz: * \code #define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 #define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_2 \endcode * \note Some dividers are powers of two, while others are integer division factors. Refer to the * formulas in the conf_clock.h template commented above each division define. * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: * \code #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC \endcode * \note When the internal RC oscillator is used for the USB module, it must be recalibrated to 48MHz for * the USB peripheral to function. If this oscillator is then used as the main system clock source, * the clock must be divided down via the peripheral and CPU bus clock division constants to ensure * that the maximum allowable CPU frequency is not exceeded. * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz using the USB Start of Frame (SOF) * as the calibration reference: * \code #define CONFIG_OSC_RC32_CAL 48000000UL #define CONFIG_OSC_AUTOCAL OSC_ID_RC32MHZ #define CONFIG_OSC_AUTOCAL_REF_OSC OSC_ID_USBSOF \endcode */ /** * \page sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration (XMEGA) * * \section sysclk_quickstart_use_case_3 Advanced use case - DFLL auto-calibration * This section will present a more advanced use case for the System Clock * Management service. This use case will configure the main system clock to * 2MHz, using the internal 2MHz RC oscillator calibrated against the internal * 32KHz oscillator. The peripheral bus clocks will run at the same speed as * the CPU clock, and the USB clock will be configured to use the internal * 32MHz (nominal) RC oscillator calibrated to 48MHz with the USB * Start-of-Frame as the calibration reference. * * \subsection sysclk_quickstart_use_case_3_prereq Prerequisites * - None * * \subsection sysclk_quickstart_use_case_3_setup_steps Initialization code * Add to the application initialization code: * \code sysclk_init(); \endcode * * \subsection sysclk_quickstart_use_case_3_setup_steps_workflow Workflow * -# Configure the system clocks according to the settings in conf_clock.h: * \code sysclk_init(); \endcode * * \subsection sysclk_quickstart_use_case_3_example_code Example code * Add or uncomment the following in your conf_clock.h header file, * commenting out all other definitions of the same symbol(s): * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC #define CONFIG_OSC_RC32_CAL 48000000UL #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF \endcode * * \subsection sysclk_quickstart_use_case_3_example_workflow Workflow * -# Configure the main system clock to use the internal 2MHz RC oscillator * as its source: * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ \endcode * -# Configure the 2MHz DFLL auto-calibration to use the internal 32KHz RC * oscillator: * \code #define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC OSC_ID_RC32KHZ \endcode * \note For auto-calibration it's typically more relevant to use an external * 32KHz crystal. So if that's the case use OSC_ID_XOSC instead. * -# Configure the USB module clock to use the internal fast (32MHz) RC oscillator: * \code #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC \endcode * -# Configure the internal fast (32MHz) RC oscillator to calibrate to 48MHz * using the USB Start of Frame (SOF) as the calibration reference: * \code #define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC #define CONFIG_OSC_RC32_CAL 48000000UL #define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC OSC_ID_USBSOF \endcode */ /* Wrap old config into new one */ #ifdef CONFIG_OSC_AUTOCAL # if CONFIG_OSC_AUTOCAL == OSC_ID_RC2MHZ # define CONFIG_OSC_AUTOCAL_RC2MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC # elif CONFIG_OSC_AUTOCAL == OSC_ID_RC32MHZ # define CONFIG_OSC_AUTOCAL_RC32MHZ_REF_OSC CONFIG_OSC_AUTOCAL_REF_OSC # else # error Bad configuration of CONFIG_OSC_AUTOCAL and/or CONFIG_OSC_AUTOCAL_REF_OSC # endif #endif // Use 2 MHz with no prescaling if config was empty. #ifndef CONFIG_SYSCLK_SOURCE # define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_RC2MHZ #endif /* CONFIG_SYSCLK_SOURCE */ #ifndef CONFIG_SYSCLK_PSADIV # define CONFIG_SYSCLK_PSADIV SYSCLK_PSADIV_1 #endif /* CONFIG_SYSCLK_PSADIV */ #ifndef CONFIG_SYSCLK_PSBCDIV # define CONFIG_SYSCLK_PSBCDIV SYSCLK_PSBCDIV_1_1 #endif /* CONFIG_SYSCLK_PSBCDIV */ /** * \weakgroup sysclk_group * * \section sysclk_group_config Configuration Symbols * * The following configuration symbols may be used to specify the * initial system clock configuration. If any of the symbols are not * set, reasonable defaults will be provided. * - \b CONFIG_SYSCLK_SOURCE: The initial system clock source. * - \b CONFIG_SYSCLK_PSADIV: The initial Prescaler A setting. * - \b CONFIG_SYSCLK_PSBCDIV: The initial Prescaler B setting. * - \b CONFIG_USBCLK_SOURCE: The initial USB clock source. * * @{ */ //! \name System Clock Sources //@{ //! Internal 2 MHz RC oscillator #define SYSCLK_SRC_RC2MHZ CLK_SCLKSEL_RC2M_gc //! Internal 32 MHz RC oscillator #define SYSCLK_SRC_RC32MHZ CLK_SCLKSEL_RC32M_gc //! Internal 32 KHz RC oscillator #define SYSCLK_SRC_RC32KHZ CLK_SCLKSEL_RC32K_gc //! External oscillator #define SYSCLK_SRC_XOSC CLK_SCLKSEL_XOSC_gc //! Phase-Locked Loop #define SYSCLK_SRC_PLL CLK_SCLKSEL_PLL_gc #if XMEGA_E //! Internal 8 MHz RC oscillator # define SYSCLK_SRC_RC8MHZ CLK_SCLKSEL_RC8M_gc #endif //@} //! \name Prescaler A Setting (relative to CLKsys) //@{ #define SYSCLK_PSADIV_1 CLK_PSADIV_1_gc //!< Do not prescale #define SYSCLK_PSADIV_2 CLK_PSADIV_2_gc //!< Prescale CLKper4 by 2 #define SYSCLK_PSADIV_4 CLK_PSADIV_4_gc //!< Prescale CLKper4 by 4 #define SYSCLK_PSADIV_8 CLK_PSADIV_8_gc //!< Prescale CLKper4 by 8 #define SYSCLK_PSADIV_16 CLK_PSADIV_16_gc //!< Prescale CLKper4 by 16 #define SYSCLK_PSADIV_32 CLK_PSADIV_32_gc //!< Prescale CLKper4 by 32 #define SYSCLK_PSADIV_64 CLK_PSADIV_64_gc //!< Prescale CLKper4 by 64 #define SYSCLK_PSADIV_128 CLK_PSADIV_128_gc //!< Prescale CLKper4 by 128 #define SYSCLK_PSADIV_256 CLK_PSADIV_256_gc //!< Prescale CLKper4 by 256 #define SYSCLK_PSADIV_512 CLK_PSADIV_512_gc //!< Prescale CLKper4 by 512 #if XMEGA_E # define SYSCLK_PSADIV_6 CLK_PSADIV_6_gc //!< Prescale CLKper4 by 6 # define SYSCLK_PSADIV_10 CLK_PSADIV_10_gc //!< Prescale CLKper4 by 10 # define SYSCLK_PSADIV_12 CLK_PSADIV_12_gc //!< Prescale CLKper4 by 12 # define SYSCLK_PSADIV_24 CLK_PSADIV_24_gc //!< Prescale CLKper4 by 24 # define SYSCLK_PSADIV_48 CLK_PSADIV_48_gc //!< Prescale CLKper4 by 48 #endif //@} //! \name Prescaler B and C Setting (relative to CLKper4) //@{ //! Do not prescale #define SYSCLK_PSBCDIV_1_1 CLK_PSBCDIV_1_1_gc //! Prescale CLKper and CLKcpu by 2 #define SYSCLK_PSBCDIV_1_2 CLK_PSBCDIV_1_2_gc //! Prescale CLKper2, CLKper and CLKcpu by 4 #define SYSCLK_PSBCDIV_4_1 CLK_PSBCDIV_4_1_gc //! Prescale CLKper2 by 2, CLKper and CLKcpu by 4 #define SYSCLK_PSBCDIV_2_2 CLK_PSBCDIV_2_2_gc //@} //! \name System Clock Port Numbers enum sysclk_port_id { SYSCLK_PORT_GEN, //!< Devices not associated with a specific port. SYSCLK_PORT_A, //!< Devices on PORTA SYSCLK_PORT_B, //!< Devices on PORTB SYSCLK_PORT_C, //!< Devices on PORTC SYSCLK_PORT_D, //!< Devices on PORTD SYSCLK_PORT_E, //!< Devices on PORTE SYSCLK_PORT_F, //!< Devices on PORTF }; /*! \name Clocks not associated with any port * * \note See the datasheet for available modules in the device. */ //@{ #define SYSCLK_DMA PR_DMA_bm //!< DMA Controller #define SYSCLK_EDMA PR_EDMA_bm //!< EDMA Controller #define SYSCLK_EVSYS PR_EVSYS_bm //!< Event System #define SYSCLK_RTC PR_RTC_bm //!< Real-Time Counter #define SYSCLK_EBI PR_EBI_bm //!< Ext Bus Interface #define SYSCLK_AES PR_AES_bm //!< AES Module #define SYSCLK_USB PR_USB_bm //!< USB Module #define SYSCLK_XCL PR_XCL_bm //!< USB Module //@} /*! \name Clocks on PORTA and PORTB * * \note See the datasheet for available modules in the device. */ //@{ #define SYSCLK_AC PR_AC_bm //!< Analog Comparator #define SYSCLK_ADC PR_ADC_bm //!< A/D Converter #define SYSCLK_DAC PR_DAC_bm //!< D/A Converter //@} /*! \name Clocks on PORTC, PORTD, PORTE and PORTF * * \note See the datasheet for available modules in the device. */ //@{ #define SYSCLK_TC0 PR_TC0_bm //!< Timer/Counter 0 #define SYSCLK_TC1 PR_TC1_bm //!< Timer/Counter 1 #define SYSCLK_TC4 PR_TC4_bm //!< Timer/Counter 0 #define SYSCLK_TC5 PR_TC5_bm //!< Timer/Counter 1 #define SYSCLK_HIRES PR_HIRES_bm //!< Hi-Res Extension #define SYSCLK_SPI PR_SPI_bm //!< SPI controller #define SYSCLK_USART0 PR_USART0_bm //!< USART 0 #define SYSCLK_USART1 PR_USART1_bm //!< USART 1 #define SYSCLK_TWI PR_TWI_bm //!< TWI controller //@} /** * \name RTC clock source identifiers * * @{ */ /** 1kHz from internal ULP oscillator. Low precision */ #define SYSCLK_RTCSRC_ULP CLK_RTCSRC_ULP_gc /** 1.024kHz from 32.768kHz crystal oscillator TOSC */ #define SYSCLK_RTCSRC_TOSC CLK_RTCSRC_TOSC_gc /** 1.024kHz from 32.768kHz internal RC oscillator */ #define SYSCLK_RTCSRC_RCOSC CLK_RTCSRC_RCOSC_gc /** 32.768kHz from crystal oscillator TOSC */ #define SYSCLK_RTCSRC_TOSC32 CLK_RTCSRC_TOSC32_gc /** 32.768kHz from internal RC oscillator */ #define SYSCLK_RTCSRC_RCOSC32 CLK_RTCSRC_RCOSC32_gc /** External clock on TOSC1 */ #define SYSCLK_RTCSRC_EXTCLK CLK_RTCSRC_EXTCLK_gc /** @} */ #if XMEGA_AU || XMEGA_B || XMEGA_C //! \name USB Clock Sources //@{ //! Internal 32 MHz RC oscillator #define USBCLK_SRC_RCOSC 0 //! Phase-Locked Loop #define USBCLK_SRC_PLL 1 //@} /** * \def CONFIG_USBCLK_SOURCE * \brief Configuration symbol for the USB clock source * * If the device features an USB module, and this is intended to be used, this * symbol must be defined with the clock source configuration. * * Define this as one of the \c USBCLK_SRC_xxx definitions. If the PLL is * selected, it must be configured to run at 48 MHz. If the 32 MHz RC oscillator * is selected, it must be tuned to 48 MHz by means of the DFLL. */ #ifdef __DOXYGEN__ # define CONFIG_USBCLK_SOURCE #endif #endif // XMEGA_AU || XMEGA_B || XMEGA_C #ifndef __ASSEMBLY__ /** * \name Querying the system clock and its derived clocks */ //@{ /** * \brief Return the current rate in Hz of the main system clock * * \todo This function assumes that the main clock source never changes * once it's been set up, and that PLL0 always runs at the compile-time * configured default rate. While this is probably the most common * configuration, which we want to support as a special case for * performance reasons, we will at some point need to support more * dynamic setups as well. * * \return Frequency of the main system clock, in Hz. */ static inline uint32_t sysclk_get_main_hz(void) { switch (CONFIG_SYSCLK_SOURCE) { case SYSCLK_SRC_RC2MHZ: return 2000000UL; #if XMEGA_E case SYSCLK_SRC_RC8MHZ: return 8000000UL; #endif case SYSCLK_SRC_RC32MHZ: #ifdef CONFIG_OSC_RC32_CAL return CONFIG_OSC_RC32_CAL; #else return 32000000UL; #endif case SYSCLK_SRC_RC32KHZ: return 32768UL; #ifdef BOARD_XOSC_HZ case SYSCLK_SRC_XOSC: return BOARD_XOSC_HZ; #endif #ifdef CONFIG_PLL0_SOURCE case SYSCLK_SRC_PLL: return pll_get_default_rate(0); #endif default: //unhandled_case(CONFIG_SYSCLK_SOURCE); return 0; } } /** * \brief Return the current rate in Hz of clk_PER4. * * This clock can run up to four times faster than the CPU clock. * * \return Frequency of the clk_PER4 clock, in Hz. */ static inline uint32_t sysclk_get_per4_hz(void) { uint8_t shift = 0; #if XMEGA_E if (CONFIG_SYSCLK_PSADIV > SYSCLK_PSADIV_512) { switch (CONFIG_SYSCLK_PSADIV) { case SYSCLK_PSADIV_6: return sysclk_get_main_hz() / 6; case SYSCLK_PSADIV_10: return sysclk_get_main_hz() / 10; case SYSCLK_PSADIV_12: return sysclk_get_main_hz() / 12; case SYSCLK_PSADIV_24: return sysclk_get_main_hz() / 24; case SYSCLK_PSADIV_48: return sysclk_get_main_hz() / 48; default: //unhandled_case; return 0; } } #endif if (CONFIG_SYSCLK_PSADIV & (1U << CLK_PSADIV_gp)) { shift = (CONFIG_SYSCLK_PSADIV >> (1 + CLK_PSADIV_gp)) + 1; } return sysclk_get_main_hz() >> shift; } /** * \brief Return the current rate in Hz of clk_PER2. * * This clock can run up to two times faster than the CPU clock. * * \return Frequency of the clk_PER2 clock, in Hz. */ static inline uint32_t sysclk_get_per2_hz(void) { switch (CONFIG_SYSCLK_PSBCDIV) { case SYSCLK_PSBCDIV_1_1: /* Fall through */ case SYSCLK_PSBCDIV_1_2: return sysclk_get_per4_hz(); case SYSCLK_PSBCDIV_4_1: return sysclk_get_per4_hz() / 4; case SYSCLK_PSBCDIV_2_2: return sysclk_get_per4_hz() / 2; default: //unhandled_case(CONFIG_SYSCLK_PSBCDIV); return 0; } } /** * \brief Return the current rate in Hz of clk_PER. * * This clock always runs at the same rate as the CPU clock unless the divider * is set. * * \return Frequency of the clk_PER clock, in Hz. */ static inline uint32_t sysclk_get_per_hz(void) { if (CONFIG_SYSCLK_PSBCDIV & (1U << CLK_PSBCDIV_gp)) return sysclk_get_per2_hz() / 2; else return sysclk_get_per2_hz(); } /** * \brief Return the current rate in Hz of the CPU clock. * * \return Frequency of the CPU clock, in Hz. */ static inline uint32_t sysclk_get_cpu_hz(void) { return sysclk_get_per_hz(); } /** * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached * to the specified peripheral. * * \param module Pointer to the module's base address. * * \return Frequency of the bus attached to the specified peripheral, in Hz. */ static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) { if (module == NULL) { Assert(false); return 0; } #ifdef AES else if (module == &AES) { return sysclk_get_per_hz(); } #endif #ifdef EBI else if (module == &EBI) { return sysclk_get_per2_hz(); } #endif #ifdef RTC else if (module == &RTC) { return sysclk_get_per_hz(); } #endif #ifdef EVSYS else if (module == &EVSYS) { return sysclk_get_per_hz(); } #endif #ifdef DMA else if (module == &DMA) { return sysclk_get_per_hz(); } #endif #ifdef EDMA else if (module == &EDMA) { return sysclk_get_per_hz(); } #endif #ifdef ACA else if (module == &ACA) { return sysclk_get_per_hz(); } #endif #ifdef ACB else if (module == &ACB) { return sysclk_get_per_hz(); } #endif #ifdef ADCA else if (module == &ADCA) { return sysclk_get_per_hz(); } #endif #ifdef ADCB else if (module == &ADCB) { return sysclk_get_per_hz(); } #endif #ifdef DACA else if (module == &DACA) { return sysclk_get_per_hz(); } #endif // Workaround for bad XMEGA D header file #if !XMEGA_D #ifdef DACB else if (module == &DACB) { return sysclk_get_per_hz(); } #endif #endif // Workaround end #ifdef FAULTC0 else if (module == &FAULTC0) { return sysclk_get_per_hz(); } #endif #ifdef FAULTC1 else if (module == &FAULTC1) { return sysclk_get_per_hz(); } #endif #ifdef TCC0 else if (module == &TCC0) { return sysclk_get_per_hz(); } #endif #ifdef TCD0 else if (module == &TCD0) { return sysclk_get_per_hz(); } #endif #ifdef TCE0 else if (module == &TCE0) { return sysclk_get_per_hz(); } #endif #ifdef TCF0 else if (module == &TCF0) { return sysclk_get_per_hz(); } #endif #ifdef TCC1 else if (module == &TCC1) { return sysclk_get_per_hz(); } #endif #ifdef TCD1 else if (module == &TCD1) { return sysclk_get_per_hz(); } #endif #ifdef TCE1 else if (module == &TCE1) { return sysclk_get_per_hz(); } #endif #ifdef TCF1 else if (module == &TCF1) { return sysclk_get_per_hz(); } #endif #ifdef TCC4 else if (module == &TCC4) { return sysclk_get_per_hz(); } #endif #ifdef TCC5 else if (module == &TCC5) { return sysclk_get_per_hz(); } #endif #ifdef TCD4 else if (module == &TCD4) { return sysclk_get_per_hz(); } #endif #ifdef TCD5 else if (module == &TCD5) { return sysclk_get_per_hz(); } #endif #ifdef HIRESC else if (module == &HIRESC) { return sysclk_get_per4_hz(); } #endif #ifdef HIRESD else if (module == &HIRESD) { return sysclk_get_per4_hz(); } #endif #ifdef HIRESE else if (module == &HIRESE) { return sysclk_get_per4_hz(); } #endif #ifdef HIRESF else if (module == &HIRESF) { return sysclk_get_per4_hz(); } #endif #ifdef SPIC else if (module == &SPIC) { return sysclk_get_per_hz(); } #endif #ifdef SPID else if (module == &SPID) { return sysclk_get_per_hz(); } #endif #ifdef SPIE else if (module == &SPIE) { return sysclk_get_per_hz(); } #endif #ifdef SPIF else if (module == &SPIF) { return sysclk_get_per_hz(); } #endif #ifdef USARTC0 else if (module == &USARTC0) { return sysclk_get_per_hz(); } #endif #ifdef USARTD0 else if (module == &USARTD0) { return sysclk_get_per_hz(); } #endif #ifdef USARTE0 else if (module == &USARTE0) { return sysclk_get_per_hz(); } #endif #ifdef USARTF0 else if (module == &USARTF0) { return sysclk_get_per_hz(); } #endif #ifdef USARTC1 else if (module == &USARTC1) { return sysclk_get_per_hz(); } #endif #ifdef USARTD1 else if (module == &USARTD1) { return sysclk_get_per_hz(); } #endif #ifdef USARTE1 else if (module == &USARTE1) { return sysclk_get_per_hz(); } #endif #ifdef USARTF1 else if (module == &USARTF1) { return sysclk_get_per_hz(); } #endif #ifdef TWIC else if (module == &TWIC) { return sysclk_get_per_hz(); } #endif #ifdef TWID else if (module == &TWID) { return sysclk_get_per_hz(); } #endif #ifdef TWIE else if (module == &TWIE) { return sysclk_get_per_hz(); } #endif #ifdef TWIF else if (module == &TWIF) { return sysclk_get_per_hz(); } #endif #ifdef XCL else if (module == &XCL) { return sysclk_get_per_hz(); } #endif else { Assert(false); return 0; } } //@} //! \name Enabling and disabling synchronous clocks //@{ /** * \brief Enable the clock to peripheral \a id on port \a port * * \param port ID of the port to which the module is connected (one of * the \c SYSCLK_PORT_* definitions). * \param id The ID (bitmask) of the peripheral module to be enabled. */ extern void sysclk_enable_module(enum sysclk_port_id port, uint8_t id); /** * \brief Disable the clock to peripheral \a id on port \a port * * \param port ID of the port to which the module is connected (one of * the \c SYSCLK_PORT_* definitions). * \param id The ID (bitmask) of the peripheral module to be disabled. */ extern void sysclk_disable_module(enum sysclk_port_id port, uint8_t id); /** * \brief Enable a peripheral's clock from its base address. * * Enables the clock to a peripheral, given its base address. If the peripheral * has an associated clock on the HSB bus, this will be enabled also. * * \param module Pointer to the module's base address. */ static inline void sysclk_enable_peripheral_clock(const volatile void *module) { if (module == NULL) { Assert(false); } #ifdef AES else if (module == &AES) { sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_AES); } #endif #ifdef EBI else if (module == &EBI) { sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); } #endif #ifdef RTC else if (module == &RTC) { sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); } #endif #ifdef EVSYS else if (module == &EVSYS) { sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); } #endif #ifdef DMA else if (module == &DMA) { sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); } #endif #ifdef EDMA else if (module == &EDMA) { sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_EDMA); } #endif #ifdef ACA else if (module == &ACA) { sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_AC); } #endif #ifdef ACB else if (module == &ACB) { sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_AC); } #endif #ifdef ADCA else if (module == &ADCA) { sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_ADC); } #endif #ifdef ADCB else if (module == &ADCB) { sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_ADC); } #endif #ifdef DACA else if (module == &DACA) { sysclk_enable_module(SYSCLK_PORT_A, SYSCLK_DAC); } #endif // Workaround for bad XMEGA D header file #if !XMEGA_D #ifdef DACB else if (module == &DACB) { sysclk_enable_module(SYSCLK_PORT_B, SYSCLK_DAC); } #endif #endif // Workaround end #ifdef TCC0 else if (module == &TCC0) { sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC0); } #endif #ifdef TCD0 else if (module == &TCD0) { sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC0); } #endif #ifdef TCE0 else if (module == &TCE0) { sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC0); } #endif #ifdef TCF0 else if (module == &TCF0) { sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC0); } #endif #ifdef TCC1 else if (module == &TCC1) { sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC1); } #endif #ifdef TCD1 else if (module == &TCD1) { sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC1); } #endif #ifdef TCE1 else if (module == &TCE1) { sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TC1); } #endif #ifdef TCF1 else if (module == &TCF1) { sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TC1); } #endif #ifdef TCC4 else if (module == &TCC4) { sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC4); } #endif #ifdef TCC5 else if (module == &TCC5) { sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TC5); } #endif #ifdef TCD4 else if (module == &TCD4) { sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC4); } #endif #ifdef TCD5 else if (module == &TCD5) { sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TC5); } #endif #ifdef HIRESC else if (module == &HIRESC) { sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_HIRES); } #endif #ifdef HIRESD else if (module == &HIRESD) { sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_HIRES); } #endif #ifdef HIRESE else if (module == &HIRESE) { sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_HIRES); } #endif #ifdef HIRESF else if (module == &HIRESF) { sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_HIRES); } #endif #ifdef SPIC else if (module == &SPIC) { sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_SPI); } #endif #ifdef SPID else if (module == &SPID) { sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_SPI); } #endif #ifdef SPIE else if (module == &SPIE) { sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_SPI); } #endif #ifdef SPIF else if (module == &SPIF) { sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_SPI); } #endif #ifdef USARTC0 else if (module == &USARTC0) { sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART0); } #endif #ifdef USARTD0 else if (module == &USARTD0) { sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART0); } #endif #ifdef USARTE0 else if (module == &USARTE0) { sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART0); } #endif #ifdef USARTF0 else if (module == &USARTF0) { sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART0); } #endif #ifdef USARTC1 else if (module == &USARTC1) { sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_USART1); } #endif #ifdef USARTD1 else if (module == &USARTD1) { sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_USART1); } #endif #ifdef USARTE1 else if (module == &USARTE1) { sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_USART1); } #endif #ifdef USARTF1 else if (module == &USARTF1) { sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_USART1); } #endif #ifdef TWIC else if (module == &TWIC) { sysclk_enable_module(SYSCLK_PORT_C, SYSCLK_TWI); } #endif #ifdef TWID else if (module == &TWID) { sysclk_enable_module(SYSCLK_PORT_D, SYSCLK_TWI); } #endif #ifdef TWIE else if (module == &TWIE) { sysclk_enable_module(SYSCLK_PORT_E, SYSCLK_TWI); } #endif #ifdef TWIF else if (module == &TWIF) { sysclk_enable_module(SYSCLK_PORT_F, SYSCLK_TWI); } #endif #ifdef XCL else if (module == &XCL) { sysclk_enable_module(SYSCLK_PORT_GEN, SYSCLK_XCL); } #endif else { Assert(false); } } /** * \brief Disable a peripheral's clock from its base address. * * Disables the clock to a peripheral, given its base address. If the peripheral * has an associated clock on the HSB bus, this will be disabled also. * * \param module Pointer to the module's base address. */ static inline void sysclk_disable_peripheral_clock(const volatile void *module) { if (module == NULL) { Assert(false); } #ifdef AES else if (module == &AES) { sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_AES); } #endif #ifdef EBI else if (module == &EBI) { sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EBI); } #endif #ifdef RTC else if (module == &RTC) { sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_RTC); } #endif #ifdef EVSYS else if (module == &EVSYS) { sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EVSYS); } #endif #ifdef DMA else if (module == &DMA) { sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_DMA); } #endif #ifdef EDMA else if (module == &EDMA) { sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_EDMA); } #endif #ifdef ACA else if (module == &ACA) { sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_AC); } #endif #ifdef ACB else if (module == &ACB) { sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_AC); } #endif #ifdef ADCA else if (module == &ADCA) { sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_ADC); } #endif #ifdef ADCB else if (module == &ADCB) { sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_ADC); } #endif #ifdef DACA else if (module == &DACA) { sysclk_disable_module(SYSCLK_PORT_A, SYSCLK_DAC); } #endif // Workaround for bad XMEGA D header file #if !XMEGA_D #ifdef DACB else if (module == &DACB) { sysclk_disable_module(SYSCLK_PORT_B, SYSCLK_DAC); } #endif #endif // Workaround end #ifdef TCC0 else if (module == &TCC0) { sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC0); } #endif #ifdef TCD0 else if (module == &TCD0) { sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC0); } #endif #ifdef TCE0 else if (module == &TCE0) { sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC0); } #endif #ifdef TCF0 else if (module == &TCF0) { sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC0); } #endif #ifdef TCC1 else if (module == &TCC1) { sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC1); } #endif #ifdef TCD1 else if (module == &TCD1) { sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC1); } #endif #ifdef TCE1 else if (module == &TCE1) { sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TC1); } #endif #ifdef TCF1 else if (module == &TCF1) { sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TC1); } #endif #ifdef TCC4 else if (module == &TCC4) { sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC4); } #endif #ifdef TCC5 else if (module == &TCC5) { sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TC5); } #endif #ifdef TCD4 else if (module == &TCD4) { sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC4); } #endif #ifdef TCD5 else if (module == &TCD5) { sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TC5); } #endif #ifdef HIRESC else if (module == &HIRESC) { sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_HIRES); } #endif #ifdef HIRESD else if (module == &HIRESD) { sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_HIRES); } #endif #ifdef HIRESE else if (module == &HIRESE) { sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_HIRES); } #endif #ifdef HIRESF else if (module == &HIRESF) { sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_HIRES); } #endif #ifdef SPIC else if (module == &SPIC) { sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_SPI); } #endif #ifdef SPID else if (module == &SPID) { sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_SPI); } #endif #ifdef SPIE else if (module == &SPIE) { sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_SPI); } #endif #ifdef SPIF else if (module == &SPIF) { sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_SPI); } #endif #ifdef USARTC0 else if (module == &USARTC0) { sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART0); } #endif #ifdef USARTD0 else if (module == &USARTD0) { sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART0); } #endif #ifdef USARTE0 else if (module == &USARTE0) { sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART0); } #endif #ifdef USARTF0 else if (module == &USARTF0) { sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART0); } #endif #ifdef USARTC1 else if (module == &USARTC1) { sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_USART1); } #endif #ifdef USARTD1 else if (module == &USARTD1) { sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_USART1); } #endif #ifdef USARTE1 else if (module == &USARTE1) { sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_USART1); } #endif #ifdef USARTF1 else if (module == &USARTF1) { sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_USART1); } #endif #ifdef TWIC else if (module == &TWIC) { sysclk_disable_module(SYSCLK_PORT_C, SYSCLK_TWI); } #endif #ifdef TWID else if (module == &TWID) { sysclk_disable_module(SYSCLK_PORT_D, SYSCLK_TWI); } #endif #ifdef TWIE else if (module == &TWIE) { sysclk_disable_module(SYSCLK_PORT_E, SYSCLK_TWI); } #endif #ifdef TWIF else if (module == &TWIF) { sysclk_disable_module(SYSCLK_PORT_F, SYSCLK_TWI); } #endif #ifdef XCL else if (module == &XCL) { sysclk_disable_module(SYSCLK_PORT_GEN, SYSCLK_XCL); } #endif else { Assert(false); } } /** * \brief Check if the synchronous clock is enabled for a module * * \param port ID of the port to which the module is connected (one of * the \c SYSCLK_PORT_* definitions). * \param id The ID (bitmask) of the peripheral module to check (one of * the \c SYSCLK_* module definitions). * * \retval true If the clock for module \a id on \a port is enabled. * \retval false If the clock for module \a id on \a port is disabled. */ static inline bool sysclk_module_is_enabled(enum sysclk_port_id port, uint8_t id) { uint8_t mask = *((uint8_t *)&PR.PRGEN + port); return (mask & id) == 0; } #if XMEGA_AU || XMEGA_B || XMEGA_C || defined(__DOXYGEN__) # if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) # if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_RCOSC) # define USBCLK_STARTUP_TIMEOUT 1 # elif (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL) # if (CONFIG_PLL0_SOURCE == PLL_SRC_XOSC) # define USBCLK_STARTUP_TIMEOUT XOSC_STARTUP_TIMEOUT # elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC32MHZ) # define USBCLK_STARTUP_TIMEOUT 1 # elif (CONFIG_PLL0_SOURCE == PLL_SRC_RC2MHZ) # define USBCLK_STARTUP_TIMEOUT 1 # else # error Unknow value for CONFIG_PLL0_SOURCE, see conf_clock.h. # endif # endif # else /* CONFIG_USBCLK_SOURCE not defined */ # define CONFIG_USBCLK_SOURCE USBCLK_SRC_RCOSC # define USBCLK_STARTUP_TIMEOUT 1 # endif /* CONFIG_USBCLK_SOURCE */ void sysclk_enable_usb(uint8_t frequency); void sysclk_disable_usb(void); #endif /* XMEGA_AU || XMEGA_B || XMEGA_C */ //@} //! \name System Clock Source and Prescaler configuration //@{ /** * \brief Set system clock prescaler configuration * * This function will change the system clock prescaler configuration to * match the parameters. * * \note The parameters to this function are device-specific. * * \param psadiv The prescaler A setting (one of the \c SYSCLK_PSADIV_* * definitions). This determines the clkPER4 frequency. * \param psbcdiv The prescaler B and C settings (one of the \c SYSCLK_PSBCDIV_* * definitions). These determine the clkPER2, clkPER and clkCPU frequencies. */ static inline void sysclk_set_prescalers(uint8_t psadiv, uint8_t psbcdiv) { ccp_write_io((uint8_t *)&CLK.PSCTRL, psadiv | psbcdiv); } /** * \brief Change the source of the main system clock. * * \param src The new system clock source. Must be one of the constants * from the System Clock Sources section. */ static inline void sysclk_set_source(uint8_t src) { ccp_write_io((uint8_t *)&CLK.CTRL, src); } /** * \brief Lock the system clock configuration * * This function will lock the current system clock source and prescaler * configuration, preventing any further changes. */ static inline void sysclk_lock(void) { ccp_write_io((uint8_t *)&CLK.LOCK, CLK_LOCK_bm); } //@} /** * \name RTC clock source control * @{ */ /** * \brief Enable RTC clock with specified clock source * * \param id RTC clock source ID. Select from SYSCLK_RTCSRC_ULP, * SYSCLK_RTCSRC_RCOSC, SYSCLK_RTCSRC_TOSC, SYSCLK_RTCSRC_RCOSC32, * SYSCLK_RTCSRC_TOSC32 or SYSCLK_RTCSRC_EXTCLK */ static inline void sysclk_rtcsrc_enable(uint8_t id) { Assert((id & ~CLK_RTCSRC_gm) == 0); switch (id) { case SYSCLK_RTCSRC_RCOSC: #if !XMEGA_A && !XMEGA_D case SYSCLK_RTCSRC_RCOSC32: #endif osc_enable(OSC_ID_RC32KHZ); osc_wait_ready(OSC_ID_RC32KHZ); break; case SYSCLK_RTCSRC_TOSC: case SYSCLK_RTCSRC_TOSC32: #if !XMEGA_A && !XMEGA_D case SYSCLK_RTCSRC_EXTCLK: #endif osc_enable(OSC_ID_XOSC); osc_wait_ready(OSC_ID_XOSC); break; } CLK.RTCCTRL = id | CLK_RTCEN_bm; } /** * \brief Disable RTC clock */ static inline void sysclk_rtcsrc_disable(void) { CLK.RTCCTRL = 0; } /** @} */ //! \name System Clock Initialization //@{ extern void sysclk_init(void); //@} #endif /* !__ASSEMBLY__ */ //! @} #ifdef __cplusplus } #endif #endif /* XMEGA_SYSCLK_H_INCLUDED */