osc.h
Go to the documentation of this file.00001
00038 #ifndef CHIP_OSC_H_INCLUDED
00039 #define CHIP_OSC_H_INCLUDED
00040
00041 #include <board.h>
00042
00048
00049
00050 #define OSC_ID_OSC0 0 //!< External Oscillator 0
00051 #define OSC_ID_OSC1 1 //!< External Oscillator 1
00052 #define OSC_ID_OSC32 2 //!< External 32 kHz oscillator
00053
00054
00056
00057
00058 #define OSC_MODE_EXTERNAL AVR32_PM_MODE_EXT_CLOCK
00059
00060 #define OSC_MODE_XTAL_G0 AVR32_PM_MODE_CRYSTAL_G0
00061
00062 #define OSC_MODE_XTAL_G1 AVR32_PM_MODE_CRYSTAL_G1
00063
00064 #define OSC_MODE_XTAL_G2 AVR32_PM_MODE_CRYSTAL_G2
00065
00066 #define OSC_MODE_XTAL_G3 AVR32_PM_MODE_CRYSTAL_G3
00067
00068
00070
00071
00072 #define OSC32_MODE_EXTERNAL AVR32_PM_OSCCTRL32_MODE_EXT_CLOCK
00073
00074 #define OSC32_MODE_XTAL AVR32_PM_OSCCTRL32_MODE_CRYSTAL
00075
00076
00078
00079
00080 #define OSC_STARTUP_0 AVR32_PM_OSCCTRL0_STARTUP_0_RCOSC
00081
00082 #define OSC_STARTUP_64 AVR32_PM_OSCCTRL0_STARTUP_64_RCOSC
00083
00084 #define OSC_STARTUP_128 AVR32_PM_OSCCTRL0_STARTUP_128_RCOSC
00085
00086 #define OSC_STARTUP_2048 AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC
00087
00088 #define OSC_STARTUP_4096 AVR32_PM_OSCCTRL0_STARTUP_4096_RCOSC
00089
00090 #define OSC_STARTUP_8192 AVR32_PM_OSCCTRL0_STARTUP_8192_RCOSC
00091
00092 #define OSC_STARTUP_16384 AVR32_PM_OSCCTRL0_STARTUP_16384_RCOSC
00093
00094
00096
00097
00098 #define OSC32_STARTUP_0 AVR32_PM_OSCCTRL32_STARTUP_0_RCOSC
00099
00100 #define OSC32_STARTUP_128 AVR32_PM_OSCCTRL32_STARTUP_128_RCOSC
00101
00102 #define OSC32_STARTUP_8192 AVR32_PM_OSCCTRL32_STARTUP_8192_RCOSC
00103
00104 #define OSC32_STARTUP_16384 AVR32_PM_OSCCTRL32_STARTUP_16384_RCOSC
00105
00106 #define OSC32_STARTUP_65536 AVR32_PM_OSCCTRL32_STARTUP_65536_RCOSC
00107
00108 #define OSC32_STARTUP_131072 AVR32_PM_OSCCTRL32_STARTUP_131072_RCOSC
00109
00110 #define OSC32_STARTUP_262144 AVR32_PM_OSCCTRL32_STARTUP_262144_RCOSC
00111
00112 #define OSC32_STARTUP_524288 AVR32_PM_OSCCTRL32_STARTUP_524288_RCOSC
00113
00114
00135 #if defined(BOARD_OSC0_STARTUP_US)
00136 # if BOARD_OSC0_STARTUP_US == 0
00137 # define OSC0_STARTUP_VALUE OSC_STARTUP_0
00138 # define OSC0_STARTUP_TIMEOUT 8
00139 # elif BOARD_OSC0_STARTUP_US <= 560
00140 # define OSC0_STARTUP_VALUE OSC_STARTUP_64
00141 # define OSC0_STARTUP_TIMEOUT 80
00142 # elif BOARD_OSC0_STARTUP_US <= 1100
00143 # define OSC0_STARTUP_VALUE OSC_STARTUP_128
00144 # define OSC0_STARTUP_TIMEOUT 160
00145 # elif BOARD_OSC0_STARTUP_US <= 18000
00146 # define OSC0_STARTUP_VALUE OSC_STARTUP_2048
00147 # define OSC0_STARTUP_TIMEOUT 2560
00148 # elif BOARD_OSC0_STARTUP_US <= 36000
00149 # define OSC0_STARTUP_VALUE OSC_STARTUP_4096
00150 # define OSC0_STARTUP_TIMEOUT 5120
00151 # elif BOARD_OSC0_STARTUP_US <= 71000
00152 # define OSC0_STARTUP_VALUE OSC_STARTUP_8192
00153 # define OSC0_STARTUP_TIMEOUT 10240
00154 # elif BOARD_OSC0_STARTUP_US <= 142000
00155 # define OSC0_STARTUP_VALUE OSC_STARTUP_16384
00156 # define OSC0_STARTUP_TIMEOUT 20480
00157 # else
00158 # error BOARD_OSC0_STARTUP_US is too high
00159 # endif
00160 # if BOARD_OSC0_IS_XTAL == true
00161 # if BOARD_OSC0_HZ < 900000
00162 # define OSC0_MODE_VALUE OSC_MODE_XTAL_G0
00163 # elif BOARD_OSC0_HZ < 3000000
00164 # define OSC0_MODE_VALUE OSC_MODE_XTAL_G1
00165 # elif BOARD_OSC0_HZ < 8000000
00166 # define OSC0_MODE_VALUE OSC_MODE_XTAL_G2
00167 # else
00168 # define OSC0_MODE_VALUE OSC_MODE_XTAL_G3
00169 # endif
00170 # else
00171 # define OSC0_MODE_VALUE OSC_MODE_EXTERNAL
00172 # endif
00173 #else
00174 # ifdef BOARD_OSC0_HZ
00175 # error BOARD_OSC0_STARTUP_US must be defined by the board code
00176 # endif
00177 # ifdef __DOXYGEN__
00178 # define OSC0_STARTUP_VALUE UNDEFINED
00179 # define OSC0_STARTUP_TIMEOUT UNDEFINED
00180 # define OSC0_MODE_VALUE UNDEFINED
00181 # endif
00182 #endif
00183
00203 #if defined(BOARD_OSC1_STARTUP_US)
00204 # if BOARD_OSC1_STARTUP_US == 0
00205 # define OSC1_STARTUP_VALUE OSC_STARTUP_0
00206 # define OSC1_STARTUP_TIMEOUT 8
00207 # elif BOARD_OSC1_STARTUP_US <= 560
00208 # define OSC1_STARTUP_VALUE OSC_STARTUP_64
00209 # define OSC1_STARTUP_TIMEOUT 80
00210 # elif BOARD_OSC1_STARTUP_US <= 1100
00211 # define OSC1_STARTUP_VALUE OSC_STARTUP_128
00212 # define OSC1_STARTUP_TIMEOUT 160
00213 # elif BOARD_OSC1_STARTUP_US <= 18000
00214 # define OSC1_STARTUP_VALUE OSC_STARTUP_2048
00215 # define OSC1_STARTUP_TIMEOUT 2560
00216 # elif BOARD_OSC1_STARTUP_US <= 36000
00217 # define OSC1_STARTUP_VALUE OSC_STARTUP_4096
00218 # define OSC1_STARTUP_TIMEOUT 5120
00219 # elif BOARD_OSC1_STARTUP_US <= 71000
00220 # define OSC1_STARTUP_VALUE OSC_STARTUP_8192
00221 # define OSC1_STARTUP_TIMEOUT 10240
00222 # elif BOARD_OSC1_STARTUP_US <= 142000
00223 # define OSC1_STARTUP_VALUE OSC_STARTUP_16384
00224 # define OSC1_STARTUP_TIMEOUT 20480
00225 # else
00226 # error BOARD_OSC1_STARTUP_US is too high
00227 # endif
00228 # ifdef BOARD_OSC1_IS_XTAL
00229 # if BOARD_OSC1_HZ < 900000
00230 # define OSC1_MODE_VALUE OSC_MODE_XTAL_G0
00231 # elif BOARD_OSC1_HZ < 3000000
00232 # define OSC1_MODE_VALUE OSC_MODE_XTAL_G1
00233 # elif BOARD_OSC1_HZ < 8000000
00234 # define OSC1_MODE_VALUE OSC_MODE_XTAL_G2
00235 # else
00236 # define OSC1_MODE_VALUE OSC_MODE_XTAL_G3
00237 # endif
00238 # else
00239 # define OSC1_MODE_VALUE OSC_MODE_EXTERNAL
00240 # endif
00241 #else
00242 # ifdef __DOXYGEN__
00243 # define OSC1_STARTUP_VALUE UNDEFINED
00244 # define OSC1_STARTUP_TIMEOUT UNDEFINED
00245 # define OSC1_MODE_VALUE UNDEFINED
00246 # endif
00247 #endif
00248
00291 #if !defined(BOARD_OSC0_HZ)
00292 # ifdef __DOXYGEN__
00293 # define BOARD_OSC0_HZ UNDEFINED
00294 # endif
00295 #endif
00296 #if !defined(BOARD_OSC0_STARTUP_US)
00297 # ifdef __DOXYGEN__
00298 # define BOARD_OSC0_STARTUP_US UNDEFINED
00299 # endif
00300 #endif
00301 #if !defined(BOARD_OSC0_IS_XTAL)
00302 # ifdef __DOXYGEN__
00303 # define BOARD_OSC0_IS_XTAL UNDEFINED
00304 # endif
00305 #endif
00306 #if !defined(BOARD_OSC1_HZ)
00307 # ifdef __DOXYGEN__
00308 # define BOARD_OSC1_HZ UNDEFINED
00309 # endif
00310 #endif
00311 #if !defined(BOARD_OSC1_STARTUP_US)
00312 # ifdef __DOXYGEN__
00313 # define BOARD_OSC1_STARTUP_US UNDEFINED
00314 # endif
00315 #endif
00316 #if !defined(BOARD_OSC1_IS_XTAL)
00317 # ifdef __DOXYGEN__
00318 # define BOARD_OSC1_IS_XTAL UNDEFINED
00319 # endif
00320 #endif
00321 #if !defined(BOARD_OSC32_HZ)
00322 # ifdef __DOXYGEN__
00323 # define BOARD_OSC32_HZ UNDEFINED
00324 # endif
00325 #endif
00326 #if !defined(BOARD_OSC32_STARTUP_US)
00327 # ifdef __DOXYGEN__
00328 # define BOARD_OSC32_STARTUP_US UNDEFINED
00329 # endif
00330 #endif
00331 #if !defined(BOARD_OSC32_IS_XTAL)
00332 # ifdef __DOXYGEN__
00333 # define BOARD_OSC32_IS_XTAL UNDEFINED
00334 # endif
00335 #endif
00336
00344
00345 #define OSC_SLOW_NOMINAL_HZ AVR32_PM_RCOSC_FREQUENCY
00346
00347 #define OSC_SLOW_MIN_HZ 100000
00348
00349 #define OSC_SLOW_MAX_HZ 120000
00350
00351
00352 #ifndef __ASSEMBLY__
00353
00354 #include <stdbool.h>
00355 #include <stdint.h>
00356 #include <avr32/io.h>
00357
00358 static inline void osc_enable(uint8_t id)
00359 {
00360 irqflags_t flags;
00361 uint32_t oscctrl;
00362
00363 flags = cpu_irq_save();
00364
00365 switch (id) {
00366 #ifdef BOARD_OSC0_HZ
00367 case OSC_ID_OSC0:
00368 oscctrl = (OSC0_STARTUP_VALUE << AVR32_PM_OSCCTRL0_STARTUP_OFFSET);
00369 oscctrl |= (OSC0_MODE_VALUE << AVR32_PM_OSCCTRL0_MODE_OFFSET);
00370 AVR32_PM.oscctrl0 = oscctrl;
00371 AVR32_PM.mcctrl |= (1 << AVR32_PM_MCCTRL_OSC0EN);
00372 break;
00373 #endif
00374
00375 #ifdef BOARD_OSC1_HZ
00376 case OSC_ID_OSC1:
00377 oscctrl = (OSC1_STARTUP_VALUE << AVR32_PM_OSCCTRL1_STARTUP_OFFSET);
00378 oscctrl |= (OSC1_MODE_VALUE << AVR32_PM_OSCCTRL1_MODE_OFFSET);
00379 AVR32_PM.oscctrl1 = oscctrl;
00380 AVR32_PM.mcctrl |= (1 << AVR32_PM_MCCTRL_OSC1EN);
00381 break;
00382 #endif
00383
00384 default:
00385
00386 break;
00387 }
00388
00389 cpu_irq_restore(flags);
00390 }
00391
00392 static inline void osc_disable(uint8_t id)
00393 {
00394 irqflags_t flags;
00395
00396 flags = cpu_irq_save();
00397 AVR32_PM.mcctrl &= ~(1U << (AVR32_PM_MCCTRL_OSC0EN + id));
00398 cpu_irq_restore(flags);
00399 }
00400
00401 static inline bool osc_is_ready(uint8_t id)
00402 {
00403 return !!(AVR32_PM.poscsr & (1U << (AVR32_PM_POSCSR_OSC0RDY + id)));
00404 }
00405
00406 static inline uint32_t osc_get_rate(uint8_t id)
00407 {
00408 switch (id) {
00409 #ifdef BOARD_OSC0_HZ
00410 case OSC_ID_OSC0:
00411 return BOARD_OSC0_HZ;
00412 #endif
00413
00414 #ifdef BOARD_OSC1_HZ
00415 case OSC_ID_OSC1:
00416 return BOARD_OSC1_HZ;
00417 #endif
00418
00419 default:
00420
00421 return 0;
00422 }
00423 }
00424
00425 #endif
00426
00428
00429 #endif