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
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
00125 #ifdef BOARD_XOSC_HZ
00126
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
00149 # define CONFIG_XOSC_STARTUP 0
00150 # endif
00151 # endif
00152 # endif
00153
00154
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
00176 # define CONFIG_XOSC_RANGE 0
00177 # endif
00178 # endif
00179 #endif
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
00223
00224 flags = cpu_irq_save();
00225 OSC.CTRL |= id;
00226 cpu_irq_restore(flags);
00227 }
00228 #else
00229
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
00308
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
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
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
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
00418 return 0;
00419 }
00420 }
00421
00422 #endif
00423
00425
00426 #endif