/Software/Testing/outeradc/code/asf/xmega/services/basic/clock/validation/zephyr_tripoli/osc.h
C Header | 429 lines | 228 code | 28 blank | 173 comment | 10 complexity | c75ba2dbd98dc587786da439269fbf02 MD5 | raw file
- /**
- * \file
- *
- * \brief Chip-specific oscillator management functions
- *
- * Copyright (C) 2010 Atmel Corporation. All rights reserved.
- *
- * \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 AVR 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.
- */
- #ifndef CHIP_OSC_H_INCLUDED
- #define CHIP_OSC_H_INCLUDED
-
- #include <board.h>
-
- /**
- * \weakgroup osc_group
- * @{
- */
-
- //! \name Oscillator identifiers
- //@{
- #define OSC_ID_OSC0 0 //!< External Oscillator 0
- #define OSC_ID_OSC1 1 //!< External Oscillator 1
- #define OSC_ID_OSC32 2 //!< External 32 kHz oscillator
- //@}
-
- //! \name OSC0/OSC1 mode values
- //@{
- //! External clock connected to XIN
- #define OSC_MODE_EXTERNAL AVR32_PM_MODE_EXT_CLOCK
- //! Crystal connected to XIN/XOUT. Use oscillator gain G0 (400 kHz to 900 kHz)
- #define OSC_MODE_XTAL_G0 AVR32_PM_MODE_CRYSTAL_G0
- //! Crystal connected to XIN/XOUT. Use oscillator gain G1 (900 kHz to 3 MHz)
- #define OSC_MODE_XTAL_G1 AVR32_PM_MODE_CRYSTAL_G1
- //! Crystal connected to XIN/XOUT. Use oscillator gain G2 (3 MHz to 8 MHz)
- #define OSC_MODE_XTAL_G2 AVR32_PM_MODE_CRYSTAL_G2
- //! Crystal connected to XIN/XOUT. Use oscillator gain G3 (8 MHz and higher)
- #define OSC_MODE_XTAL_G3 AVR32_PM_MODE_CRYSTAL_G3
- //@}
-
- //! \name OSC32 mode values
- //@{
- //! External clock connected to XIN32
- #define OSC32_MODE_EXTERNAL AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK
- //! Crystal connected to XIN32/XOUT32. Use automatic gain control
- #define OSC32_MODE_XTAL AVR32_PM_OSCCTRL32_MODE_CRYSTAL
- //@}
-
- //! \name OSC0/OSC1 startup values
- //@{
- //! 0 cycles
- #define OSC_STARTUP_0 AVR32_PM_OSCCTRL0_STARTUP_0_RCOSC
- //! 64 cycles (560 us)
- #define OSC_STARTUP_64 AVR32_PM_OSCCTRL0_STARTUP_64_RCOSC
- //! 128 cycles (1.1 ms)
- #define OSC_STARTUP_128 AVR32_PM_OSCCTRL0_STARTUP_128_RCOSC
- //! 2048 cycles (18 ms)
- #define OSC_STARTUP_2048 AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC
- //! 4096 cycles (36 ms)
- #define OSC_STARTUP_4096 AVR32_PM_OSCCTRL0_STARTUP_4096_RCOSC
- //! 8192 cycles (71 ms)
- #define OSC_STARTUP_8192 AVR32_PM_OSCCTRL0_STARTUP_8192_RCOSC
- //! 16384 cycles (142 ms)
- #define OSC_STARTUP_16384 AVR32_PM_OSCCTRL0_STARTUP_16384_RCOSC
- //@}
-
- //! \name OSC32 startup values
- //@{
- //! 0 cycles
- #define OSC32_STARTUP_0 AVR32_PM_OSCCTRL32_STARTUP_0_RCOSC
- //! 128 cycles (1.1 ms)
- #define OSC32_STARTUP_128 AVR32_PM_OSCCTRL32_STARTUP_128_RCOSC
- //! 8192 cycles (72.3 ms)
- #define OSC32_STARTUP_8192 AVR32_PM_OSCCTRL32_STARTUP_8192_RCOSC
- //! 16384 cycles (143 ms)
- #define OSC32_STARTUP_16384 AVR32_PM_OSCCTRL32_STARTUP_16384_RCOSC
- //! 65536 cycles (570 ms)
- #define OSC32_STARTUP_65536 AVR32_PM_OSCCTRL32_STARTUP_65536_RCOSC
- //! 131072 cycles (1.1 s)
- #define OSC32_STARTUP_131072 AVR32_PM_OSCCTRL32_STARTUP_131072_RCOSC
- //! 262144 cycles (2.3 s)
- #define OSC32_STARTUP_262144 AVR32_PM_OSCCTRL32_STARTUP_262144_RCOSC
- //! 524288 cycles (4.6 s)
- #define OSC32_STARTUP_524288 AVR32_PM_OSCCTRL32_STARTUP_524288_RCOSC
- //@}
-
- /**
- * \def OSC0_STARTUP_TIMEOUT
- * \brief Number of slow clock cycles to wait for OSC0 to start
- *
- * This is the number of slow clock cycles corresponding to
- * OSC0_STARTUP_VALUE with an additional 25% safety margin. If the
- * oscillator isn't running when this timeout has expired, it is assumed
- * to have failed to start.
- */
- /**
- * \def OSC0_MODE_VALUE
- * \brief Board-dependent value written to the MODE bitfield of
- * PM_OSCCTRL(0)
- */
- /**
- * \def OSC0_STARTUP_VALUE
- * \brief Board-dependent value written to the STARTUP bitfield of
- * PM_OSCCTRL(0)
- */
-
- #if defined(BOARD_OSC0_STARTUP_US)
- # if BOARD_OSC0_STARTUP_US == 0
- # define OSC0_STARTUP_VALUE OSC_STARTUP_0
- # define OSC0_STARTUP_TIMEOUT 8
- # elif BOARD_OSC0_STARTUP_US <= 560
- # define OSC0_STARTUP_VALUE OSC_STARTUP_64
- # define OSC0_STARTUP_TIMEOUT 80
- # elif BOARD_OSC0_STARTUP_US <= 1100
- # define OSC0_STARTUP_VALUE OSC_STARTUP_128
- # define OSC0_STARTUP_TIMEOUT 160
- # elif BOARD_OSC0_STARTUP_US <= 18000
- # define OSC0_STARTUP_VALUE OSC_STARTUP_2048
- # define OSC0_STARTUP_TIMEOUT 2560
- # elif BOARD_OSC0_STARTUP_US <= 36000
- # define OSC0_STARTUP_VALUE OSC_STARTUP_4096
- # define OSC0_STARTUP_TIMEOUT 5120
- # elif BOARD_OSC0_STARTUP_US <= 71000
- # define OSC0_STARTUP_VALUE OSC_STARTUP_8192
- # define OSC0_STARTUP_TIMEOUT 10240
- # elif BOARD_OSC0_STARTUP_US <= 142000
- # define OSC0_STARTUP_VALUE OSC_STARTUP_16384
- # define OSC0_STARTUP_TIMEOUT 20480
- # else
- # error BOARD_OSC0_STARTUP_US is too high
- # endif
- # if BOARD_OSC0_IS_XTAL == true
- # if BOARD_OSC0_HZ < 900000
- # define OSC0_MODE_VALUE OSC_MODE_XTAL_G0
- # elif BOARD_OSC0_HZ < 3000000
- # define OSC0_MODE_VALUE OSC_MODE_XTAL_G1
- # elif BOARD_OSC0_HZ < 8000000
- # define OSC0_MODE_VALUE OSC_MODE_XTAL_G2
- # else
- # define OSC0_MODE_VALUE OSC_MODE_XTAL_G3
- # endif
- # else
- # define OSC0_MODE_VALUE OSC_MODE_EXTERNAL
- # endif
- #else
- # ifdef BOARD_OSC0_HZ
- # error BOARD_OSC0_STARTUP_US must be defined by the board code
- # endif
- # ifdef __DOXYGEN__
- # define OSC0_STARTUP_VALUE UNDEFINED
- # define OSC0_STARTUP_TIMEOUT UNDEFINED
- # define OSC0_MODE_VALUE UNDEFINED
- # endif
- #endif
-
- /**
- * \def OSC1_STARTUP_VALUE
- * \brief Board-dependent value written to the STARTUP bitfield of
- * PM_OSCCTRL(1)
- */
- /**
- * \def OSC1_STARTUP_TIMEOUT
- * \brief Number of slow clock cycles to wait for OSC1 to start
- *
- * This is the number of slow clock cycles corresponding to
- * OSC1_STARTUP_VALUE with an additional 25% safety margin. If the
- * oscillator isn't running when this timeout has expired, it is assumed
- * to have failed to start.
- */
- /**
- * \def OSC1_MODE_VALUE
- * \brief Board-dependent value written to the MODE bitfield of
- * PM_OSCCTRL(1)
- */
- #if defined(BOARD_OSC1_STARTUP_US)
- # if BOARD_OSC1_STARTUP_US == 0
- # define OSC1_STARTUP_VALUE OSC_STARTUP_0
- # define OSC1_STARTUP_TIMEOUT 8
- # elif BOARD_OSC1_STARTUP_US <= 560
- # define OSC1_STARTUP_VALUE OSC_STARTUP_64
- # define OSC1_STARTUP_TIMEOUT 80
- # elif BOARD_OSC1_STARTUP_US <= 1100
- # define OSC1_STARTUP_VALUE OSC_STARTUP_128
- # define OSC1_STARTUP_TIMEOUT 160
- # elif BOARD_OSC1_STARTUP_US <= 18000
- # define OSC1_STARTUP_VALUE OSC_STARTUP_2048
- # define OSC1_STARTUP_TIMEOUT 2560
- # elif BOARD_OSC1_STARTUP_US <= 36000
- # define OSC1_STARTUP_VALUE OSC_STARTUP_4096
- # define OSC1_STARTUP_TIMEOUT 5120
- # elif BOARD_OSC1_STARTUP_US <= 71000
- # define OSC1_STARTUP_VALUE OSC_STARTUP_8192
- # define OSC1_STARTUP_TIMEOUT 10240
- # elif BOARD_OSC1_STARTUP_US <= 142000
- # define OSC1_STARTUP_VALUE OSC_STARTUP_16384
- # define OSC1_STARTUP_TIMEOUT 20480
- # else
- # error BOARD_OSC1_STARTUP_US is too high
- # endif
- # ifdef BOARD_OSC1_IS_XTAL
- # if BOARD_OSC1_HZ < 900000
- # define OSC1_MODE_VALUE OSC_MODE_XTAL_G0
- # elif BOARD_OSC1_HZ < 3000000
- # define OSC1_MODE_VALUE OSC_MODE_XTAL_G1
- # elif BOARD_OSC1_HZ < 8000000
- # define OSC1_MODE_VALUE OSC_MODE_XTAL_G2
- # else
- # define OSC1_MODE_VALUE OSC_MODE_XTAL_G3
- # endif
- # else
- # define OSC1_MODE_VALUE OSC_MODE_EXTERNAL
- # endif
- #else
- # ifdef __DOXYGEN__
- # define OSC1_STARTUP_VALUE UNDEFINED
- # define OSC1_STARTUP_TIMEOUT UNDEFINED
- # define OSC1_MODE_VALUE UNDEFINED
- # endif
- #endif
-
- /**
- * \name Board-specific configuration parameters
- * The following definitions must be provided by the board code for all
- * working oscillators on the board.
- */
- //@{
- /**
- * \def BOARD_OSC0_HZ
- * \brief Clock frequency of OSC0 in Hz
- */
- /**
- * \def BOARD_OSC0_STARTUP_US
- * \brief Startup time of OSC0 in microseconds
- */
- /**
- * \def BOARD_OSC0_IS_XTAL
- * \brief OSC0 uses a crystal, not an external clock
- */
- /**
- * \def BOARD_OSC1_HZ
- * \brief Clock frequency of OSC1 in Hz
- */
- /**
- * \def BOARD_OSC1_STARTUP_US
- * \brief Startup time of OSC1 in microseconds
- */
- /**
- * \def BOARD_OSC1_IS_XTAL
- * \brief OSC1 uses a crystal, not an external clock
- */
- /**
- * \def BOARD_OSC32_HZ
- * \brief Clock frequency of OSC32 in Hz
- */
- /**
- * \def BOARD_OSC32_STARTUP_US
- * \brief Startup time of OSC32 in microseconds
- */
- /**
- * \def BOARD_OSC32_IS_XTAL
- * \brief OSC32 uses a crystal, not an external clock
- */
- #if !defined(BOARD_OSC0_HZ)
- # ifdef __DOXYGEN__
- # define BOARD_OSC0_HZ UNDEFINED
- # endif
- #endif
- #if !defined(BOARD_OSC0_STARTUP_US)
- # ifdef __DOXYGEN__
- # define BOARD_OSC0_STARTUP_US UNDEFINED
- # endif
- #endif
- #if !defined(BOARD_OSC0_IS_XTAL)
- # ifdef __DOXYGEN__
- # define BOARD_OSC0_IS_XTAL UNDEFINED
- # endif
- #endif
- #if !defined(BOARD_OSC1_HZ)
- # ifdef __DOXYGEN__
- # define BOARD_OSC1_HZ UNDEFINED
- # endif
- #endif
- #if !defined(BOARD_OSC1_STARTUP_US)
- # ifdef __DOXYGEN__
- # define BOARD_OSC1_STARTUP_US UNDEFINED
- # endif
- #endif
- #if !defined(BOARD_OSC1_IS_XTAL)
- # ifdef __DOXYGEN__
- # define BOARD_OSC1_IS_XTAL UNDEFINED
- # endif
- #endif
- #if !defined(BOARD_OSC32_HZ)
- # ifdef __DOXYGEN__
- # define BOARD_OSC32_HZ UNDEFINED
- # endif
- #endif
- #if !defined(BOARD_OSC32_STARTUP_US)
- # ifdef __DOXYGEN__
- # define BOARD_OSC32_STARTUP_US UNDEFINED
- # endif
- #endif
- #if !defined(BOARD_OSC32_IS_XTAL)
- # ifdef __DOXYGEN__
- # define BOARD_OSC32_IS_XTAL UNDEFINED
- # endif
- #endif
- /**
- * \name Slow clock frequency limits
- * The slow clock is an internal RC oscillator whose frequency may drift
- * a bit as a result of temperature changes. These definitions provide
- * upper and lower limits which may be used to calculate upper and lower
- * limits of timeouts, derived clock frequencies, etc.
- */
- //@{
- //! Nominal frequency of the slow clock in Hz
- #define OSC_SLOW_NOMINAL_HZ AVR32_PM_RCOSC_FREQUENCY
- //! Minimum frequency of the slow clock in Hz
- #define OSC_SLOW_MIN_HZ 100000
- //! Maximum frequency of the slow clock in Hz
- #define OSC_SLOW_MAX_HZ 120000
- //@}
-
- #ifndef __ASSEMBLY__
-
- #include <stdbool.h>
- #include <stdint.h>
- #include <avr32/io.h>
-
- static inline void osc_enable(uint8_t id)
- {
- irqflags_t flags;
- uint32_t oscctrl;
-
- flags = cpu_irq_save();
-
- switch (id) {
- #ifdef BOARD_OSC0_HZ
- case OSC_ID_OSC0:
- oscctrl = (OSC0_STARTUP_VALUE << AVR32_PM_OSCCTRL0_STARTUP_OFFSET);
- oscctrl |= (OSC0_MODE_VALUE << AVR32_PM_OSCCTRL0_MODE_OFFSET);
- AVR32_PM.oscctrl0 = oscctrl;
- AVR32_PM.mcctrl |= (1 << AVR32_PM_MCCTRL_OSC0EN);
- break;
- #endif
-
- #ifdef BOARD_OSC1_HZ
- case OSC_ID_OSC1:
- oscctrl = (OSC1_STARTUP_VALUE << AVR32_PM_OSCCTRL1_STARTUP_OFFSET);
- oscctrl |= (OSC1_MODE_VALUE << AVR32_PM_OSCCTRL1_MODE_OFFSET);
- AVR32_PM.oscctrl1 = oscctrl;
- AVR32_PM.mcctrl |= (1 << AVR32_PM_MCCTRL_OSC1EN);
- break;
- #endif
-
- default:
- /* unhandled_case(id); */
- break;
- }
-
- cpu_irq_restore(flags);
- }
-
- static inline void osc_disable(uint8_t id)
- {
- irqflags_t flags;
-
- flags = cpu_irq_save();
- AVR32_PM.mcctrl &= ~(1U << (AVR32_PM_MCCTRL_OSC0EN + id));
- cpu_irq_restore(flags);
- }
-
- static inline bool osc_is_ready(uint8_t id)
- {
- return !!(AVR32_PM.poscsr & (1U << (AVR32_PM_POSCSR_OSC0RDY + id)));
- }
-
- static inline uint32_t osc_get_rate(uint8_t id)
- {
- switch (id) {
- #ifdef BOARD_OSC0_HZ
- case OSC_ID_OSC0:
- return BOARD_OSC0_HZ;
- #endif
-
- #ifdef BOARD_OSC1_HZ
- case OSC_ID_OSC1:
- return BOARD_OSC1_HZ;
- #endif
-
- default:
- /* unhandled_case(id); */
- return 0;
- }
- }
-
- #endif /* !__ASSEMBLY__ */
-
- //! @}
-
- #endif /* CHIP_OSC_H_INCLUDED */