Statistics
| Branch: | Tag: | Revision:

root / LUFA / Platform / UC3 / ClockManagement.h @ 978b99e5

History | View | Annotate | Download (13.4 KB)

1
/*
2
             LUFA Library
3
     Copyright (C) Dean Camera, 2011.
4

5
  dean [at] fourwalledcubicle [dot] com
6
           www.lufa-lib.org
7
*/
8

    
9
/*
10
  Copyright 2011  Dean Camera (dean [at] fourwalledcubicle [dot] com)
11

12
  Permission to use, copy, modify, distribute, and sell this
13
  software and its documentation for any purpose is hereby granted
14
  without fee, provided that the above copyright notice appear in
15
  all copies and that both that the copyright notice and this
16
  permission notice and warranty disclaimer appear in supporting
17
  documentation, and that the name of the author not be used in
18
  advertising or publicity pertaining to distribution of the
19
  software without specific, written prior permission.
20

21
  The author disclaim all warranties with regard to this
22
  software, including all implied warranties of merchantability
23
  and fitness.  In no event shall the author be liable for any
24
  special, indirect or consequential damages or any damages
25
  whatsoever resulting from loss of use, data or profits, whether
26
  in an action of contract, negligence or other tortious action,
27
  arising out of or in connection with the use or performance of
28
  this software.
29
*/
30

    
31
/** \file
32
 *  \brief Module Clock Driver for the AVR32 UC3 microcontrollers.
33
 *
34
 *  Clock management driver for the AVR32 UC3 microcontrollers. This driver allows for the configuration
35
 *  of the various clocks within the device to clock the various peripherals.
36
 */
37

    
38
/** \ingroup Group_PlatformDrivers
39
 *  \defgroup Group_PlatformDrivers_UC3Clocks UC3 Clock Management Driver - LUFA/Platform/UC3/ClockManagement.h
40
 *  \brief Module Clock Driver for the AVR32 UC3 microcontrollers.
41
 *
42
 *  \section Sec_Dependencies Module Source Dependencies
43
 *  The following files must be built with any user project that uses this module:
44
 *    - None
45
 *
46
 *  \section Sec_ModDescription Module Description
47
 *  Clock management driver for the AVR32 UC3 microcontrollers. This driver allows for the configuration
48
 *  of the various clocks within the device to clock the various peripherals.
49
 *
50
 *  Usage Example:
51
 *  \code
52
 *                #include <LUFA/Platform/UC3/ClockManagement.h>
53
 *
54
 *                void main(void)
55
 *                {
56
 *                        // Start the master external oscillator which will be used as the main clock reference
57
 *                        AVR32CLK_StartExternalOscillator(0, EXOSC_MODE_8MHZ_OR_MORE, EXOSC_START_0CLK);
58
 *                        
59
 *                        // Start the PLL for the CPU clock, switch CPU to it
60
 *                        AVR32CLK_StartPLL(0, CLOCK_SRC_OSC0, 12000000, F_CPU);
61
 *                        AVR32CLK_SetCPUClockSource(CLOCK_SRC_PLL0, F_CPU);
62
 *
63
 *                        // Start the PLL for the USB Generic Clock module
64
 *                        AVR32CLK_StartPLL(1, CLOCK_SRC_OSC0, 12000000, 48000000);
65
 *                }
66
 *  \endcode
67
 *
68
 *  @{
69
 */
70

    
71
#ifndef _UC3_CLOCK_MANAGEMENT_H_
72
#define _UC3_CLOCK_MANAGEMENT_H_
73

    
74
        /* Includes: */
75
                #include <LUFA/Common/Common.h>
76

    
77
        /* Enable C linkage for C++ Compilers: */
78
                #if defined(__cplusplus)
79
                        extern "C" {
80
                #endif
81

    
82
        /* Public Interface - May be used in end-application: */
83
                /* Macros: */
84
                        /** Enum for the possible external oscillator types. */
85
                        enum UC3_Extern_OSC_ClockTypes_t
86
                        {
87
                                EXOSC_MODE_CLOCK         = AVR32_PM_OSCCTRL0_MODE_EXT_CLOCK,  /**< External clock (non-crystal) mode. */
88
                                EXOSC_MODE_900KHZ_MAX    = AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G0, /**< External crystal oscillator equal to or slower than 900KHz. */
89
                                EXOSC_MODE_3MHZ_MAX      = AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G1, /**< External crystal oscillator equal to or slower than 3MHz. */
90
                                EXOSC_MODE_8MHZ_MAX      = AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G2, /**< External crystal oscillator equal to or slower than 8MHz. */
91
                                EXOSC_MODE_8MHZ_OR_MORE  = AVR32_PM_OSCCTRL0_MODE_CRYSTAL_G3, /**< External crystal oscillator equal to or faster than 8MHz. */                
92
                        };
93

    
94
                        /** Enum for the possible external oscillator statup times. */
95
                        enum UC3_Extern_OSC_ClockStartup_t
96
                        {
97
                                EXOSC_START_0CLK         = AVR32_PM_OSCCTRL0_STARTUP_0_RCOSC,     /**< Immediate startup, no delay. */
98
                                EXOSC_START_64CLK        = AVR32_PM_OSCCTRL0_STARTUP_64_RCOSC,    /**< Wait 64 clock cyles before startup for stability. */
99
                                EXOSC_START_128CLK       = AVR32_PM_OSCCTRL0_STARTUP_128_RCOSC,   /**< Wait 128 clock cyles before startup for stability. */
100
                                EXOSC_START_2048CLK      = AVR32_PM_OSCCTRL0_STARTUP_2048_RCOSC,  /**< Wait 2048 clock cyles before startup for stability. */
101
                                EXOSC_START_4096CLK      = AVR32_PM_OSCCTRL0_STARTUP_4096_RCOSC,  /**< Wait 4096 clock cyles before startup for stability. */
102
                                EXOSC_START_8192CLK      = AVR32_PM_OSCCTRL0_STARTUP_8192_RCOSC,  /**< Wait 8192 clock cyles before startup for stability. */
103
                                EXOSC_START_16384CLK     = AVR32_PM_OSCCTRL0_STARTUP_16384_RCOSC, /**< Wait 16384 clock cyles before startup for stability. */
104
                        };
105
                        
106
                        /** Enum for the possible module clock sources. */
107
                        enum UC3_System_ClockSource_t
108
                        {
109
                                CLOCK_SRC_SLOW_CLK       = 0, /**< Clock sourced from the internal slow clock. */
110
                                CLOCK_SRC_OSC0           = 1, /**< Clock sourced from the Oscillator 0 clock. */
111
                                CLOCK_SRC_OSC1           = 2, /**< Clock sourced from the Oscillator 1 clock. */
112
                                CLOCK_SRC_PLL0           = 3, /**< Clock sourced from the PLL 0 clock. */
113
                                CLOCK_SRC_PLL1           = 4, /**< Clock sourced from the PLL 1 clock. */
114
                        };
115

    
116
                /* Inline Functions: */
117
                        /** Starts the given external oscillator of the UC3 microcontroller, with the given options. This routine blocks until
118
                         *  the oscillator is ready for use.
119
                         *
120
                         *  \param[in] Channel  Index of the external oscillator to start.
121
                         *  \param[in] Type     Type of clock attached to the given oscillator channel, a value from \ref UC3_Extern_OSC_ClockTypes_t.
122
                         *  \param[in] Startup  Statup time of the external oscillator, a value from \ref UC3_Extern_OSC_ClockStartup_t.
123
                         *
124
                         *  \return Boolean \c true if the external oscillator was successfully started, \c false if invalid parameters specified.
125
                         */
126
                        static inline bool AVR32CLK_StartExternalOscillator(const uint8_t Channel,
127
                                                                            const uint8_t Type,
128
                                                                            const uint8_t Startup) ATTR_ALWAYS_INLINE;
129
                        static inline bool AVR32CLK_StartExternalOscillator(const uint8_t Channel,
130
                                                                            const uint8_t Type,
131
                                                                            const uint8_t Startup)
132
                        {
133
                                switch (Channel)
134
                                {
135
                                        case 0:
136
                                                AVR32_PM.OSCCTRL0.startup = Startup;
137
                                                AVR32_PM.OSCCTRL0.mode    = Type;
138
                                                break;
139
                                        case 1:
140
                                                AVR32_PM.OSCCTRL1.startup = Startup;
141
                                                AVR32_PM.OSCCTRL1.mode    = Type;
142
                                                break;
143
                                        default:
144
                                                return false;
145
                                }
146

    
147
                                AVR32_PM.mcctrl |= (1 << (AVR32_PM_MCCTRL_OSC0EN_OFFSET + Channel));
148

    
149
                                while (!(AVR32_PM.poscsr & (1 << (AVR32_PM_POSCSR_OSC0RDY_OFFSET + Channel))));
150
                                return true;
151
                        }
152

    
153
                        /** Stops the given external oscillator of the UC3 microcontroller.
154
                         *
155
                         *  \param[in] Channel  Index of the external oscillator to stop.
156
                         */
157
                        static inline void AVR32CLK_StopExternalOscillator(const uint8_t Channel) ATTR_ALWAYS_INLINE;
158
                        static inline void AVR32CLK_StopExternalOscillator(const uint8_t Channel)
159
                        {
160
                                AVR32_PM.mcctrl &= ~(1 << (AVR32_PM_MCCTRL_OSC0EN_OFFSET + Channel));
161
                        }
162

    
163
                        /** Starts the given PLL of the UC3 microcontroller, with the given options. This routine blocks until the PLL is ready for use.
164
                         *
165
                         *  \note The output frequency must be equal to or greater than the source frequency.
166
                         *
167
                         *  \param[in] Channel     Index of the PLL to start.
168
                         *  \param[in] Source      Clock source for the PLL, a value from \ref UC3_System_ClockSource_t.
169
                         *  \param[in] SourceFreq  Frequency of the PLL's clock source, in Hz.
170
                         *  \param[in] Frequency   Target frequency of the PLL's output.
171
                         *
172
                         *  \return Boolean \c true if the PLL was successfully started, \c false if invalid parameters specified.
173
                         */
174
                        static inline bool AVR32CLK_StartPLL(const uint8_t Channel,
175
                                                             const uint8_t Source,
176
                                                             const uint32_t SourceFreq,
177
                                                             const uint32_t Frequency) ATTR_ALWAYS_INLINE;
178
                        static inline bool AVR32CLK_StartPLL(const uint8_t Channel,
179
                                                             const uint8_t Source,
180
                                                             const uint32_t SourceFreq,
181
                                                             const uint32_t Frequency)
182
                        {
183
                                if (SourceFreq > Frequency)
184
                                  return false;
185
                        
186
                                switch (Source)
187
                                {
188
                                        case CLOCK_SRC_OSC0:
189
                                                AVR32_PM.PLL[Channel].pllosc = 0;
190
                                                break;
191
                                        case CLOCK_SRC_OSC1:
192
                                                AVR32_PM.PLL[Channel].pllosc = 1;
193
                                                break;
194
                                        default:
195
                                                return false;
196
                                }
197

    
198
                                AVR32_PM.PLL[Channel].pllmul = (Frequency / SourceFreq) ? (((Frequency / SourceFreq) - 1) / 2) : 0;
199
                                AVR32_PM.PLL[Channel].plldiv = 0;
200
                                AVR32_PM.PLL[Channel].pllen  = true;
201

    
202
                                while (!(AVR32_PM.poscsr & (1 << (AVR32_PM_POSCSR_LOCK0_OFFSET + Channel))));
203
                                return true;
204
                        }
205

    
206
                        /** Stops the given PLL of the UC3 microcontroller.
207
                         *
208
                         *  \param[in] Channel  Index of the PLL to stop.
209
                         */
210
                        static inline void AVR32CLK_StopPLL(const uint8_t Channel) ATTR_ALWAYS_INLINE;
211
                        static inline void AVR32CLK_StopPLL(const uint8_t Channel)
212
                        {
213
                                AVR32_PM.PLL[Channel].pllen = false;
214
                        }
215
                        
216
                        /** Starts the given Generic Clock of the UC3 microcontroller, with the given options.
217
                         *
218
                         *  \param[in] Channel     Index of the Generic Clock to start.
219
                         *  \param[in] Source      Clock source for the Generic Clock, a value from \ref UC3_System_ClockSource_t.
220
                         *  \param[in] SourceFreq  Frequency of the Generic Clock's clock source, in Hz.
221
                         *  \param[in] Frequency   Target frequency of the Generic Clock's output.
222
                         *
223
                         *  \return Boolean \c true if the Generic Clock was successfully started, \c false if invalid parameters specified.
224
                         */
225
                        static inline bool AVR32CLK_StartGenericClock(const uint8_t Channel,
226
                                                                      const uint8_t Source,
227
                                                                      const uint32_t SourceFreq,
228
                                                                      const uint32_t Frequency) ATTR_ALWAYS_INLINE;
229
                        static inline bool AVR32CLK_StartGenericClock(const uint8_t Channel,
230
                                                                      const uint8_t Source,
231
                                                                      const uint32_t SourceFreq,
232
                                                                      const uint32_t Frequency)
233
                        {
234
                                switch (Source)
235
                                {
236
                                        case CLOCK_SRC_OSC0:
237
                                                AVR32_PM.GCCTRL[Channel].pllsel = false;
238
                                                AVR32_PM.GCCTRL[Channel].oscsel = 0;
239
                                                break;
240
                                        case CLOCK_SRC_OSC1:
241
                                                AVR32_PM.GCCTRL[Channel].pllsel = false;
242
                                                AVR32_PM.GCCTRL[Channel].oscsel = 1;
243
                                                break;
244
                                        case CLOCK_SRC_PLL0:
245
                                                AVR32_PM.GCCTRL[Channel].pllsel = true;
246
                                                AVR32_PM.GCCTRL[Channel].oscsel = 0;
247
                                                break;
248
                                        case CLOCK_SRC_PLL1:
249
                                                AVR32_PM.GCCTRL[Channel].pllsel = true;
250
                                                AVR32_PM.GCCTRL[Channel].oscsel = 1;
251
                                                break;
252
                                        default:
253
                                                return false;
254
                                }
255
                                
256
                                if (SourceFreq < Frequency)
257
                                  return false;
258

    
259
                                AVR32_PM.GCCTRL[Channel].diven = (SourceFreq > Frequency) ? true : false;
260
                                AVR32_PM.GCCTRL[Channel].div   = (((SourceFreq / Frequency) - 1) / 2);
261
                                AVR32_PM.GCCTRL[Channel].cen   = true;
262
                                
263
                                return true;
264
                        }
265
                        
266
                        /** Stops the given generic clock of the UC3 microcontroller.
267
                         *
268
                         *  \param[in] Channel  Index of the generic clock to stop.
269
                         */
270
                        static inline void AVR32CLK_StopGenericClock(const uint8_t Channel) ATTR_ALWAYS_INLINE;
271
                        static inline void AVR32CLK_StopGenericClock(const uint8_t Channel)
272
                        {
273
                                AVR32_PM.GCCTRL[Channel].cen = false;
274
                        }
275
                        
276
                        /** Sets the clock source for the main microcontroller core. The given clock source should be configured
277
                         *  and ready for use before this function is called.
278
                         *
279
                         *  This function will configure the FLASH controller's wait states automatically to suit the given clock source.
280
                         *
281
                         *  \param[in] Source      Clock source for the CPU core, a value from \ref UC3_System_ClockSource_t.
282
                         *  \param[in] SourceFreq  Frequency of the CPU core's clock source, in Hz.
283
                         *
284
                         *  \return Boolean \c true if the CPU core clock was sucessfully altered, \c false if invalid parameters specified.
285
                         */
286
                        static inline bool AVR32CLK_SetCPUClockSource(const uint8_t Source,
287
                                                                      const uint32_t SourceFreq) ATTR_ALWAYS_INLINE;
288
                        static inline bool AVR32CLK_SetCPUClockSource(const uint8_t Source,
289
                                                                      const uint32_t SourceFreq)
290
                        {
291
                                AVR32_FLASHC.FCR.fws = (SourceFreq > 30000000) ? true : false;
292

    
293
                                switch (Source)
294
                                {
295
                                        #if defined(AVR32_PM_MCCTRL_MCSEL_SLOW)
296
                                        case CLOCK_SRC_SLOW_CLK:
297
                                                AVR32_PM.MCCTRL.mcsel = AVR32_PM_MCCTRL_MCSEL_SLOW;
298
                                                break;
299
                                        #endif
300
                                        #if defined(AVR32_PM_MCCTRL_MCSEL_OSC0)
301
                                        case CLOCK_SRC_OSC0:
302
                                                AVR32_PM.MCCTRL.mcsel = AVR32_PM_MCCTRL_MCSEL_OSC0;
303
                                                break;
304
                                        #endif
305
                                        #if defined(AVR32_PM_MCCTRL_MCSEL_PLL0)
306
                                        case CLOCK_SRC_PLL0:
307
                                                AVR32_PM.MCCTRL.mcsel = AVR32_PM_MCCTRL_MCSEL_PLL0;
308
                                                break;
309
                                        #endif
310
                                        default:
311
                                                return false;
312
                                }
313
                                
314
                                return true;
315
                        }
316

    
317
        /* Disable C linkage for C++ Compilers: */
318
                #if defined(__cplusplus)
319
                        }
320
                #endif
321

    
322
#endif
323

    
324
/** @} */