Xmega Application Note


osc.h

Go to the documentation of this file.
00001 
00038 #ifndef XMEGA_OSC_H_INCLUDED
00039 #define XMEGA_OSC_H_INCLUDED
00040 
00041 #include <compiler.h>
00042 #include <board.h>
00043 
00053 
00054 
00055 
00056 #define OSC_ID_RC2MHZ         OSC_RC2MEN_bm
00057 
00058 #define OSC_ID_RC32MHZ        OSC_RC32MEN_bm
00059 
00060 #define OSC_ID_RC32KHZ        OSC_RC32KEN_bm
00061 
00062 #define OSC_ID_XOSC           OSC_XOSCEN_bm
00063 
00068 #define OSC_ID_USBSOF         0xff
00069 
00070 
00072 
00073 #define XOSC_TYPE_EXTERNAL    0   //!< External clock signal
00074 #define XOSC_TYPE_32KHZ       2   //!< 32.768 kHz resonator on TOSC
00075 #define XOSC_TYPE_XTAL        3   //!< 0.4 to 16 MHz resonator on XTAL
00076 
00077 
00082 #ifdef __DOXYGEN__
00083 # define CONFIG_XOSC_32KHZ_LPM
00084 #endif /* __DOXYGEN__ */
00085 
00096 
00097 
00098 #define XOSC_STARTUP_256      0   //!< 256 cycle start-up time
00099 #define XOSC_STARTUP_1024     1   //!< 1 k cycle start-up time
00100 #define XOSC_STARTUP_16384    2   //!< 16 k cycle start-up time
00101 
00102 
00112 
00113 
00114 
00115 #define XOSC_RANGE_04TO2      OSC_FRQRANGE_04TO2_gc
00116 
00117 #define XOSC_RANGE_2TO9       OSC_FRQRANGE_2TO9_gc
00118 
00119 #define XOSC_RANGE_9TO12      OSC_FRQRANGE_9TO12_gc
00120 
00121 #define XOSC_RANGE_12TO16     
00122 
00123 
00124 // If application intends to use XOSC.
00125 #ifdef BOARD_XOSC_HZ
00126 // Get start-up config for XOSC, if not manually set.
00127 # ifndef CONFIG_XOSC_STARTUP
00128 #  ifndef BOARD_XOSC_STARTUP_US
00129 #   error BOARD_XOSC_STARTUP_US must be configured.
00130 #  else
00131 
00132 #   define BOARD_XOSC_STARTUP_CYCLES \
00133                 (BOARD_XOSC_HZ / 1000000 * BOARD_XOSC_STARTUP_US)
00134 
00135 #   if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL)
00136 #    if (BOARD_XOSC_STARTUP_CYCLES > 16384)
00137 #     error BOARD_XOSC_STARTUP_US is too high for current BOARD_XOSC_HZ.
00138 
00139 #    elif (BOARD_XOSC_STARTUP_CYCLES > 1024)
00140 #     define CONFIG_XOSC_STARTUP    XOSC_STARTUP_16384
00141 
00142 #    elif (BOARD_XOSC_STARTUP_CYCLES > 256)
00143 #     define CONFIG_XOSC_STARTUP    XOSC_STARTUP_1024
00144 
00145 #    else
00146 #     define CONFIG_XOSC_STARTUP    XOSC_STARTUP_256
00147 #    endif
00148 #   else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */
00149 #    define CONFIG_XOSC_STARTUP     0
00150 #   endif
00151 #  endif /* BOARD_XOSC_STARTUP_US */
00152 # endif /* CONFIG_XOSC_STARTUP */
00153 
00154 // Get frequency range setting for XOSC, if not manually set.
00155 # ifndef CONFIG_XOSC_RANGE
00156 #  if (BOARD_XOSC_TYPE == XOSC_TYPE_XTAL)
00157 #   if (BOARD_XOSC_HZ < 400000)
00158 #    error BOARD_XOSC_HZ is below minimum frequency of 400 kHz.
00159 
00160 #   elif (BOARD_XOSC_HZ < 2000000)
00161 #    define CONFIG_XOSC_RANGE    XOSC_RANGE_04TO2
00162 
00163 #   elif (BOARD_XOSC_HZ < 9000000)
00164 #    define CONFIG_XOSC_RANGE    XOSC_RANGE_2TO9
00165 
00166 #   elif (BOARD_XOSC_HZ < 12000000)
00167 #    define CONFIG_XOSC_RANGE    XOSC_RANGE_9TO12
00168 
00169 #   elif (BOARD_XOSC_HZ <= 16000000)
00170 #    define CONFIG_XOSC_RANGE    XOSC_RANGE_12TO16
00171 
00172 #   else
00173 #    error BOARD_XOSC_HZ is above maximum frequency of 16 MHz.
00174 #   endif
00175 #  else /* BOARD_XOSC_TYPE == XOSC_TYPE_XTAL */
00176 #   define CONFIG_XOSC_RANGE     0
00177 #  endif
00178 # endif /* CONFIG_XOSC_RANGE */
00179 #endif /* BOARD_XOSC_HZ */
00180 
00181 #ifndef __ASSEMBLY__
00182 
00189 static inline void osc_enable_internal(uint8_t id)
00190 {
00191         irqflags_t flags;
00192 
00193         Assert(id != OSC_ID_USBSOF);
00194 
00195         flags = cpu_irq_save();
00196         OSC.CTRL |= id;
00197         cpu_irq_restore(flags);
00198 }
00199 
00200 #if defined(BOARD_XOSC_HZ) || defined(__DOXYGEN__)
00201 
00210 static inline void osc_enable_external(uint8_t id)
00211 {
00212         irqflags_t flags;
00213 
00214         Assert(id == OSC_ID_XOSC);
00215 
00216 #ifndef CONFIG_XOSC_32KHZ_LPM
00217         OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) |
00218                         CONFIG_XOSC_RANGE;
00219 #else
00220         OSC.XOSCCTRL = BOARD_XOSC_TYPE | (CONFIG_XOSC_STARTUP << 2) |
00221                         CONFIG_XOSC_RANGE | OSC_X32KLPM_bm;
00222 #endif /* CONFIG_XOSC_32KHZ_LPM */
00223 
00224         flags = cpu_irq_save();
00225         OSC.CTRL |= id;
00226         cpu_irq_restore(flags);
00227 }
00228 #else
00229 //ERROR_FUNC(osc_no_external, "No external oscillator on the selected board");
00230 
00231 static inline void osc_enable_external(uint8_t id)
00232 {
00233         osc_no_external();
00234 }
00235 #endif
00236 
00237 static inline void osc_disable(uint8_t id)
00238 {
00239         irqflags_t flags;
00240 
00241         Assert(id != OSC_ID_USBSOF);
00242 
00243         flags = cpu_irq_save();
00244         OSC.CTRL &= ~id;
00245         cpu_irq_restore(flags);
00246 }
00247 
00248 static inline bool osc_is_ready(uint8_t id)
00249 {
00250         Assert(id != OSC_ID_USBSOF);
00251 
00252         return OSC.STATUS & id;
00253 }
00254 
00256 
00257 
00282 static inline void osc_enable_autocalibration(uint8_t id, uint8_t ref_id)
00283 {
00284         irqflags_t flags;
00285 
00286         flags = cpu_irq_save();
00287         switch (id) {
00288         case OSC_ID_RC2MHZ:
00289                 Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC));
00290 
00291                 if (ref_id == OSC_ID_XOSC) {
00292                         OSC.DFLLCTRL |= OSC_RC2MCREF_bm;
00293                 } else {
00294                         OSC.DFLLCTRL &= ~(OSC_RC2MCREF_bm);
00295                 }
00296                 DFLLRC2M.CTRL |= DFLL_ENABLE_bm;
00297                 break;
00298 
00299         case OSC_ID_RC32MHZ:
00300 #if XMEGA_USB
00301                 Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC)
00302                                 || (ref_id == OSC_ID_USBSOF));
00303                 OSC.DFLLCTRL &= ~(OSC_RC32MREF_gm);
00304                 if (ref_id == OSC_ID_XOSC) {
00305                         OSC.DFLLCTRL |= OSC_RC32MREF_XOSC32K_gc;         
00306                 } else if (ref_id == OSC_ID_USBSOF) {
00307                         // Calibrate 32MRC at 48MHz using USB SOF
00308                         // 48MHz/1kHz=0xBB80
00309                         DFLLRC32M.COMP1=0x80;
00310                         DFLLRC32M.COMP2=0xBB;
00311                         OSC.DFLLCTRL |= OSC_RC32MREF_USBSOF_gc;
00312                 }
00313 #else
00314                 Assert((ref_id == OSC_ID_RC32KHZ) || (ref_id == OSC_ID_XOSC));
00315                 if (ref_id == OSC_ID_XOSC) {
00316                         OSC.DFLLCTRL |= OSC_RC32MCREF_bm;
00317                 } else {
00318                         OSC.DFLLCTRL &= ~(OSC_RC32MCREF_bm);
00319                 }
00320 #endif
00321                 DFLLRC32M.CTRL |= DFLL_ENABLE_bm;
00322                 break;
00323 
00324         default:
00325                 //unhandled_case(id);
00326                 break;
00327         }
00328         cpu_irq_restore(flags);
00329 }
00330 
00341 static inline void osc_disable_autocalibration(uint8_t id)
00342 {
00343         switch (id) {
00344         case OSC_ID_RC2MHZ:
00345                 DFLLRC2M.CTRL = 0;
00346                 break;
00347 
00348         case OSC_ID_RC32MHZ:
00349                 DFLLRC32M.CTRL = 0;
00350                 break;
00351 
00352         default:
00353                 // unhandled_case(id);
00354                 break;
00355         }
00356 }
00366 static inline void osc_user_calibration(uint8_t id, uint16_t calib)
00367 {
00368         switch (id) {
00369         case OSC_ID_RC2MHZ:
00370                 DFLLRC2M.CALA=LSB(calib);
00371                 DFLLRC2M.CALB=MSB(calib);
00372 
00373         case OSC_ID_RC32MHZ:
00374                 DFLLRC32M.CALA=LSB(calib);
00375                 DFLLRC32M.CALB=MSB(calib);
00376 
00377         default:
00378                 // unhandled_case(id);
00379                 break;
00380         }
00381 }
00383 
00384 static inline void osc_enable(uint8_t id)
00385 {
00386         if (id != OSC_ID_XOSC) {
00387                 osc_enable_internal(id);
00388         } else {
00389                 osc_enable_external(id);
00390         }
00391 }
00392 
00393 static inline uint32_t osc_get_rate(uint8_t id)
00394 {
00395         Assert(id != OSC_ID_USBSOF);
00396 
00397         switch (id) {
00398         case OSC_ID_RC2MHZ:
00399                 return 2000000UL;
00400 
00401         case OSC_ID_RC32MHZ:
00402 #ifdef CONFIG_OSC_RC32_CAL
00403                 return CONFIG_OSC_RC32_CAL;
00404 #else
00405                 return 32000000UL;
00406 #endif
00407 
00408         case OSC_ID_RC32KHZ:
00409                 return 32768UL;
00410 
00411 #ifdef BOARD_XOSC_HZ
00412         case OSC_ID_XOSC:
00413                 return BOARD_XOSC_HZ;
00414 #endif
00415 
00416         default:
00417                 // unhandled_case(id);
00418                 return 0;
00419         }
00420 }
00421 
00422 #endif /* __ASSEMBLY__ */
00423 
00425 
00426 #endif /* XMEGA_OSC_H_INCLUDED */
@DOC_TITLE@
Generated on Fri Oct 22 12:15:25 2010 for AVR1300 Using the Xmega ADC by doxygen 1.6.3