dfll.h 13 KB

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