]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_M4_ATSAM4L_Atmel_Studio/src/asf/common/services/clock/dfll.h
Add SAM4L demo.
[freertos] / FreeRTOS / Demo / CORTEX_M4_ATSAM4L_Atmel_Studio / src / asf / common / services / clock / dfll.h
1 /**\r
2  * \file\r
3  *\r
4  * \brief DFLL management\r
5  *\r
6  * Copyright (c) 2010-2012 Atmel Corporation. All rights reserved.\r
7  *\r
8  * \asf_license_start\r
9  *\r
10  * \page License\r
11  *\r
12  * Redistribution and use in source and binary forms, with or without\r
13  * modification, are permitted provided that the following conditions are met:\r
14  *\r
15  * 1. Redistributions of source code must retain the above copyright notice,\r
16  *    this list of conditions and the following disclaimer.\r
17  *\r
18  * 2. Redistributions in binary form must reproduce the above copyright notice,\r
19  *    this list of conditions and the following disclaimer in the documentation\r
20  *    and/or other materials provided with the distribution.\r
21  *\r
22  * 3. The name of Atmel may not be used to endorse or promote products derived\r
23  *    from this software without specific prior written permission.\r
24  *\r
25  * 4. This software may only be redistributed and used in connection with an\r
26  *    Atmel microcontroller product.\r
27  *\r
28  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED\r
29  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
31  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR\r
32  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\r
33  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\r
34  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\r
35  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\r
36  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r
37  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
38  * POSSIBILITY OF SUCH DAMAGE.\r
39  *\r
40  * \asf_license_stop\r
41  *\r
42  */\r
43 #ifndef CLK_DFLL_H_INCLUDED\r
44 #define CLK_DFLL_H_INCLUDED\r
45 \r
46 #include <parts.h>\r
47 #include "conf_clock.h"\r
48 \r
49 #if UC3L\r
50 # include "uc3l/dfll.h"\r
51 #elif SAM4L\r
52 # include "sam4l/dfll.h"\r
53 #else\r
54 # error Unsupported chip type\r
55 #endif\r
56 \r
57 /**\r
58  * \ingroup clk_group\r
59  * \defgroup dfll_group DFLL Management\r
60  *\r
61  * A Digital Frequency Locked Loop can be used to generate a highly\r
62  * accurate frequency from a slower-running reference clock, in much the\r
63  * same way as a PLL. DFLLs typically have shorter startup times and\r
64  * less jitter. They can also be used in open-loop mode to generate a\r
65  * less accurate frequency without the use of a reference clock.\r
66  *\r
67  * There may be significant variations between platforms in the support\r
68  * for certain features.\r
69  *\r
70  * \par Example: Setting up DFLL0 with default parameters and dithering enabled\r
71  *\r
72  * The following example shows how to configure and enable DFLL0 in\r
73  * closed-loop mode using the default parameters specified through\r
74  * configuration symbols.\r
75  * \code\r
76         dfll_enable_config_defaults(0); \endcode\r
77  *\r
78  * To configure and enable DFLL0 in closed-loop mode using the default\r
79  * parameters and to enable specific feature like dithering for better accuracy,\r
80  * you can use this initialization process.\r
81  * \code\r
82         struct dfll_config dfllcfg;\r
83 \r
84         dfll_enable_source(CONFIG_DFLL0_SOURCE);\r
85         dfll_config_defaults(&dfllcfg, 0);\r
86         dfll_config_enable_dithering(&dfllcfg);\r
87         dfll_enable(&dfllcfg, 0);\r
88         dfll_wait_for_accurate_lock(0); \endcode\r
89  *\r
90  * When the last function call returns, DFLL0 is running at a frequency\r
91  * which matches the default configuration as accurately as possible.\r
92  * Any additional alterations to the default configuration can be added\r
93  * at the same place as the call to dfll_config_enable_dithering(), but\r
94  * note that the DFLL will never achieve "accurate" lock if dithering is\r
95  * disabled.\r
96  *\r
97  * @{\r
98  */\r
99 \r
100 //! \name Chip-specific DFLL characteristics\r
101 //@{\r
102 /**\r
103  * \def NR_DFLLS\r
104  * \brief Number of on-chip DFLLs.\r
105  */\r
106 /**\r
107  * \def DFLL_MIN_HZ\r
108  * \brief Minimum frequency that the DFLL can generate.\r
109  */\r
110 /**\r
111  * \def DFLL_MAX_HZ\r
112  * \brief Maximum frequency that the DFLL can generate.\r
113  */\r
114 //@}\r
115 \r
116 /**\r
117  * \typedef dfll_refclk_t\r
118  * \brief Type used for identifying a reference clock source for the DFLL.\r
119  */\r
120 \r
121 //! \name DFLL Configuration\r
122 //@{\r
123 \r
124 /**\r
125  * \struct dfll_config\r
126  * \brief Hardware-specific representation of DFLL configuration.\r
127  *\r
128  * This structure contains one or more device-specific values\r
129  * representing the current DFLL configuration. The contents of this\r
130  * structure is typically different from platform to platform, and the\r
131  * user should not access any fields except through the DFLL\r
132  * configuration API.\r
133  */\r
134 \r
135 /**\r
136  * \fn void dfll_config_init_open_loop_mode(struct dfll_config *cfg)\r
137  * \brief Configure the DFLL configuration \a cfg for open-loop mode.\r
138  *\r
139  * \param cfg The DFLL configuration to be initialized.\r
140  */\r
141 /**\r
142  * \fn void dfll_config_init_closed_loop_mode(struct dfll_config *cfg,\r
143  *              dfll_refclk_t refclk, uint16_t div, uint16_t mul)\r
144  * \brief Configure the DFLL configuration \a cfg for closed-loop mode.\r
145  *\r
146  * \param cfg The DFLL configuration to be initialized.\r
147  * \param refclk The reference clock source.\r
148  * \param div Reference clock divider.\r
149  * \param mul Multiplier (integer part only).\r
150  */\r
151 /**\r
152  * \def dfll_config_defaults(cfg, dfll_id)\r
153  * \brief Initialize DFLL configuration using default parameters.\r
154  *\r
155  * After this function returns, \a cfg will contain a configuration\r
156  * which will make the DFLL run at (CONFIG_DFLLx_MUL / CONFIG_DFLLx_DIV)\r
157  * times the frequency of CONFIG_DFLLx_SOURCE. The default configuration\r
158  * will always use closed-loop mode with no fractional multiplier.\r
159  *\r
160  * \param cfg The DFLL configuration to be initialized.\r
161  * \param dfll_id Use defaults for this DFLL.\r
162  */\r
163 /**\r
164  * \def dfll_get_default_rate(dfll_id)\r
165  * \brief Return the default rate in Hz of \a dfll_id.\r
166  */\r
167 \r
168 /**\r
169  * \fn void dfll_config_set_fractional_multiplier(struct dfll_config *cfg,\r
170  *              uint16_t mul_i, uint16_t mul_f)\r
171  * \brief Set a fractional multiplier.\r
172  *\r
173  * This function has no effect in open-loop mode, and is only available\r
174  * on devices which support fractional multipliers.\r
175  *\r
176  * The fractional part of the multiplier is assumed to be 16 bits. The\r
177  * low-level driver will make sure to shift this value to match the\r
178  * hardware if necessary.\r
179  *\r
180  * \param cfg The DFLL configuration to be modified.\r
181  * \param mul_i Integer part of multiplier.\r
182  * \param mul_f Fractional part of multiplier.\r
183  */\r
184 /**\r
185  * \fn void dfll_config_enable_dithering(struct dfll_config *cfg)\r
186  * \brief Enable dithering for more accurate frequency generation.\r
187  *\r
188  * The fine LSB input to the VCO is dithered to achieve fractional\r
189  * approximation to the correct multiplication ratio.\r
190  *\r
191  * \param cfg The DFLL configuration to be modified.\r
192  */\r
193 /**\r
194  * \fn void dfll_config_disable_dithering(struct dfll_config *cfg)\r
195  * \brief Disable dithering.\r
196  *\r
197  * \see dfll_config_enable_dithering()\r
198  *\r
199  * \param cfg The DFLL configuration to be modified.\r
200  */\r
201 /**\r
202  * \fn void dfll_config_set_initial_tuning(struct dfll_config *cfg,\r
203  *              uint16_t coarse, uint16_t fine)\r
204  * \brief Set initial VCO tuning.\r
205  *\r
206  * In open loop mode, this will determine the frequency of the output.\r
207  *\r
208  * In closed loop mode, this will provide an initial estimate of the VCO\r
209  * tuning. While the DFLL will automatically adjust these values to\r
210  * match the desired output frequency, careful selection of initial\r
211  * values might reduce the time to achieve coarse and fine lock.\r
212  *\r
213  * \param cfg The DFLL configuration to be modified.\r
214  * \param coarse Coarse tuning of the frequency generator.\r
215  * \param fine Fine tuning of the frequency generator.\r
216  */\r
217 /**\r
218  * \fn void dfll_config_set_max_step(struct dfll_config *cfg,\r
219  *              uint16_t coarse, uint16_t fine)\r
220  * \brief Set the maximum VCO tuning step size.\r
221  *\r
222  * This function has no effect in open-loop mode.\r
223  *\r
224  * By default, both of these values are set to 50% of their respective\r
225  * maximums.  It is not recommended to set the values any higher than\r
226  * this, but setting them lower might reduce the frequency overshoot at\r
227  * the expense of longer time to achieve coarse and/or fine lock.\r
228  *\r
229  * \param cfg The DFLL configuration to be modified\r
230  * \param coarse The maximum step size of the coarse VCO tuning.\r
231  * \param fine The maximum step size of the fine VCO tuning.\r
232  */\r
233 /**\r
234  * \fn void dfll_config_enable_ssg(struct dfll_config *cfg,\r
235  *              uint16_t amplitude, uint16_t step_size)\r
236  * \brief Enable Spread Spectrum Generator.\r
237  *\r
238  * \param cfg The DFLL configuration to be modified.\r
239  * \param amplitude The amplitude of the spread spectrum.\r
240  * \param step_size The step size of the spread spectrum.\r
241  */\r
242 /**\r
243  * \fn void dfll_config_disable_ssg(struct dfll_config *cfg)\r
244  * \brief Disable Spread Spectrum Generator.\r
245  *\r
246  * \param cfg The DFLL configuration to be modified.\r
247  */\r
248 //@}\r
249 \r
250 //! \name Interaction with the DFLL hardware\r
251 //@{\r
252 /**\r
253  * \fn void dfll_enable_open_loop(const struct dfll_config *cfg,\r
254  *              unsigned int dfll_id)\r
255  * \brief Activate the configuration \a cfg and enable DFLL \a dfll_id\r
256  * in open-loop mode.\r
257  *\r
258  * \pre The configuration in \a cfg must represent an open-loop\r
259  * configuration.\r
260  *\r
261  * \param cfg The configuration to be activated.\r
262  * \param dfll_id The ID of the DFLL to be enabled.\r
263  */\r
264 /**\r
265  * \fn void dfll_enable_closed_loop(const struct dfll_config *cfg,\r
266  *              unsigned int dfll_id)\r
267  * \brief Activate the configuration \a cfg and enable DFLL \a dfll_id\r
268  * in closed-loop mode.\r
269  *\r
270  * \pre The configuration in \a cfg must represent a closed-loop\r
271  * configuration.\r
272  *\r
273  * \param cfg The configuration to be activated.\r
274  * \param dfll_id The ID of the DFLL to be enabled.\r
275  */\r
276 /**\r
277  * \fn void dfll_disable_open_loop(unsigned int dfll_id)\r
278  * \brief Disable the DFLL identified by \a dfll_id.\r
279  *\r
280  * \pre The DFLL must have been enabled in open loop mode.\r
281  *\r
282  * \param dfll_id The ID of the DFLL to be disabled.\r
283  */\r
284 /**\r
285  * \fn void dfll_disable_closed_loop(unsigned int dfll_id)\r
286  * \brief Disable the DFLL identified by \a dfll_id.\r
287  *\r
288  * \pre The DFLL must have been enabled in closed loop mode.\r
289  *\r
290  * \param dfll_id The ID of the DFLL to be disabled.\r
291  */\r
292 /**\r
293  * \fn bool dfll_is_coarse_locked(unsigned int dfll_id)\r
294  * \brief Determine whether or not a DFLL has achieved coarse lock.\r
295  *\r
296  * \param dfll_id The ID of the DFLL to check.\r
297  *\r
298  * \retval true The DFLL has determined the final value of the coarse\r
299  * VCO tuning value.\r
300  * \retval false The DFLL has not yet determined the coarse VCO tuning\r
301  * value, or has not been enabled.\r
302  */\r
303 /**\r
304  * \fn bool dfll_is_fine_locked(unsigned int dfll_id)\r
305  * \brief Determine whether or not a DFLL has achieved fine lock.\r
306  *\r
307  * \param dfll_id The ID of the DFLL to check.\r
308  *\r
309  * \retval true The DFLL has determined the final value of the fine VCO\r
310  * tuning value.\r
311  * \retval false The DFLL has not yet determined the fine VCO tuning\r
312  * value, or has not been enabled.\r
313  */\r
314 /**\r
315  * \fn bool dfll_is_accurate_locked(unsigned int dfll_id)\r
316  * \brief Determine whether or not a DFLL has achieved accurate lock.\r
317  *\r
318  * \param dfll_id The ID of the DFLL to check.\r
319  *\r
320  * \retval true The DFLL has determined the final dithering duty cycle.\r
321  * \retval false The DFLL has not yet determined the dithering duty\r
322  * cycle, or has not been enabled with dithering enabled.\r
323  */\r
324 /**\r
325  * \fn void dfll_enable_source(enum dfll_refclk_t src)\r
326  * \brief Enable the source of the dfll.\r
327  * The source is enabled, if the source is not already running.\r
328  *\r
329  * \param dfll_source src The ID of the DFLL source to enable.\r
330  */\r
331 /**\r
332  * \fn void dfll_enable_config_defaults(unsigned int dfll_id)\r
333  * \brief Enable the dfll with the default configuration.\r
334  * DFLL is enabled, if the DFLL is not already locked.\r
335  *\r
336  * \param dfll_id The ID of the DFLL to enable.\r
337  */\r
338 \r
339 /**\r
340  * \brief Wait for the DFLL identified by \a dfll_id to achieve coarse\r
341  * lock.\r
342  *\r
343  * \param dfll_id The ID of the DFLL to wait for.\r
344  *\r
345  * \retval STATUS_OK The DFLL has achieved coarse lock.\r
346  * \retval ERR_TIMEOUT Timed out waiting for lock.\r
347  */\r
348 static inline int dfll_wait_for_coarse_lock(unsigned int dfll_id)\r
349 {\r
350         /* TODO: Add timeout mechanism */\r
351         while (!dfll_is_coarse_locked(dfll_id)) {\r
352                 /* Do nothing */\r
353         }\r
354 \r
355         return 0;\r
356 }\r
357 \r
358 /**\r
359  * \brief Wait for the DFLL identified by \a dfll_id to achieve fine\r
360  * lock.\r
361  *\r
362  * \param dfll_id The ID of the DFLL to wait for.\r
363  *\r
364  * \retval STATUS_OK The DFLL has achieved fine lock.\r
365  * \retval ERR_TIMEOUT Timed out waiting for lock.\r
366  */\r
367 static inline int dfll_wait_for_fine_lock(unsigned int dfll_id)\r
368 {\r
369         /* TODO: Add timeout mechanism */\r
370         while (!dfll_is_fine_locked(dfll_id)) {\r
371                 /* Do nothing */\r
372         }\r
373 \r
374         return 0;\r
375 }\r
376 \r
377 /**\r
378  * \brief Wait for the DFLL identified by \a dfll_id to achieve accurate\r
379  * lock.\r
380  *\r
381  * \param dfll_id The ID of the DFLL to wait for.\r
382  *\r
383  * \retval STATUS_OK The DFLL has achieved accurate lock.\r
384  * \retval ERR_TIMEOUT Timed out waiting for lock.\r
385  */\r
386 static inline int dfll_wait_for_accurate_lock(unsigned int dfll_id)\r
387 {\r
388         /* TODO: Add timeout mechanism */\r
389         while (!dfll_is_accurate_locked(dfll_id)) {\r
390                 /* Do nothing */\r
391         }\r
392 \r
393         return 0;\r
394 }\r
395 \r
396 //@}\r
397 //! @}\r
398 \r
399 #endif /* CLK_DFLL_H_INCLUDED */\r