pll_5410x.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. /*
  2. * @brief LPC5410X PLL driver
  3. *
  4. * @note
  5. * Copyright(C) NXP Semiconductors, 2014
  6. * All rights reserved.
  7. *
  8. * @par
  9. * Software that is described herein is for illustrative purposes only
  10. * which provides customers with programming information regarding the
  11. * LPC products. This software is supplied "AS IS" without any warranties of
  12. * any kind, and NXP Semiconductors and its licenser disclaim any and
  13. * all warranties, express or implied, including all implied warranties of
  14. * merchantability, fitness for a particular purpose and non-infringement of
  15. * intellectual property rights. NXP Semiconductors assumes no responsibility
  16. * or liability for the use of the software, conveys no license or rights under any
  17. * patent, copyright, mask work right, or any other intellectual property rights in
  18. * or to any products. NXP Semiconductors reserves the right to make changes
  19. * in the software without notification. NXP Semiconductors also makes no
  20. * representation or warranty that such application will be suitable for the
  21. * specified use without further testing or modification.
  22. *
  23. * @par
  24. * Permission to use, copy, modify, and distribute this software and its
  25. * documentation is hereby granted, under NXP Semiconductors' and its
  26. * licensor's relevant copyrights in the software, without fee, provided that it
  27. * is used in conjunction with NXP Semiconductors microcontrollers. This
  28. * copyright, permission, and disclaimer notice must appear in all copies of
  29. * this code.
  30. */
  31. #ifndef __PLL_5410X_H_
  32. #define __PLL_5410X_H_
  33. #ifdef __cplusplus
  34. extern "C" {
  35. #endif
  36. /** @defgroup PLL_5410X CHIP: LPC5410X PLL Driver
  37. * @ingroup CHIP_5410X_DRIVERS
  38. * The PLL in the LPC5410x is flexible, but can be complex to use. This driver
  39. * provides functions to help setup and use the PLL in it's various supported
  40. * modes.<br>
  41. *
  42. * This driver does not alter PLL clock source or system clocks outside the
  43. * PLL (like the main clock source) that may be referenced from the PLL. It
  44. * may optionally setup system voltages, wait for PLL lock, and power cycle
  45. * the PLL during setup based on setup flags.
  46. *
  47. * The driver works by first generating a PLL setup structure from a desired
  48. * PLL configuration structure. The PLL setup structure is then passed to the
  49. * PLL setup function to setup the PLL. In a user spplication, the PLL setup
  50. * structure can be pre-populated with PLL setup data to avoid using the PLL
  51. * configuration structure (or multiple PLL setup structures can be used to
  52. * more dynamically control PLL output rate).
  53. *
  54. * <b>How to use this driver</b><br>
  55. @verbatim
  56. // Setup PLL configuration
  57. PLL_CONFIG_T pllConfig = {
  58. 75000000, // desiredRate = 75MHz
  59. 0, // InputRate = 0Hz (not used)
  60. 0 // No flags, function will determine best setup to get closest rate
  61. };
  62. // Get closest PLL setup to get the desired configuration
  63. PLL_SETUP_T pllSetup;
  64. uint32_t actualPllRate;
  65. PLL_ERROR_T pllError;
  66. pllError = Chip_Clock_SetupPLLData(&pllConfig, &pllSetup, &actualPllRate);
  67. if (pllError != PLL_ERROR_SUCCESS) {
  68. printf("PLL setup error #%x\r\n", (uint32_t) pllError);
  69. while (1);
  70. }
  71. else {
  72. printf("PLL config successful, actual config rate = %uHz\r\n", actualPllRate);
  73. }
  74. // Make sure main system clock is not using PLL, as the PLL setup
  75. // function will power off and optionally power on the PLL
  76. Chip_Clock_SetMainClockSource(SYSCON_MAINCLKSRC_IRC);
  77. // Setup PLL source
  78. Chip_Clock_SetSystemPLLSource(SYSCON_PLLCLKSRC_IRC);
  79. // Now to apply the configuration to the PLL
  80. pllSetup.flags = PLL_SETUPFLAG_WAITLOCK;
  81. Chip_Clock_SetupSystemPLLPrec(&pllSetup);
  82. // Switch main system clock to PLL
  83. Chip_Clock_SetMainClockSource(SYSCON_MAINCLKSRC_PLLOUT);
  84. @endverbatim
  85. *
  86. * @{
  87. */
  88. /**
  89. * Clock sources for system PLLs
  90. */
  91. typedef enum CHIP_SYSCON_PLLCLKSRC {
  92. SYSCON_PLLCLKSRC_IRC = 0, /*!< Internal oscillator */
  93. SYSCON_PLLCLKSRC_CLKIN, /*!< External clock input pin */
  94. SYSCON_PLLCLKSRC_WDTOSC, /*!< WDT oscillator */
  95. SYSCON_PLLCLKSRC_RTC, /*!< RTC 32KHz oscillator */
  96. } CHIP_SYSCON_PLLCLKSRC_T;
  97. /**
  98. * @brief Set System PLL clock source
  99. * @param src : Clock source for system PLL
  100. * @return Nothing
  101. * @note The PLL should be pwoered down prior to changing the source.
  102. */
  103. STATIC INLINE void Chip_Clock_SetSystemPLLSource(CHIP_SYSCON_PLLCLKSRC_T src)
  104. {
  105. LPC_SYSCON->SYSPLLCLKSEL = (uint32_t) src;
  106. }
  107. /**
  108. * @brief Return System PLL input clock rate
  109. * @return System PLL input clock rate
  110. */
  111. uint32_t Chip_Clock_GetSystemPLLInClockRate(void);
  112. /**
  113. * @brief Return System PLL output clock rate
  114. * @param recompute : Forces a PLL rate recomputation if true
  115. * @return System PLL output clock rate
  116. * @note The PLL rate is cached in the driver in a variable as
  117. * the rate computation function can take some time to perform. It
  118. * is recommended to use 'false' with the 'recompute' parameter.
  119. */
  120. uint32_t Chip_Clock_GetSystemPLLOutClockRate(bool recompute);
  121. /**
  122. * @brief Enables and disables PLL bypass mode
  123. * @brief bypass : true to bypass PLL (PLL output = PLL input, false to disable bypass
  124. * @return System PLL output clock rate
  125. */
  126. void Chip_Clock_SetBypassPLL(bool bypass);
  127. /**
  128. * @brief Check if PLL is locked or not
  129. * @return true if the PLL is locked, false if not locked
  130. */
  131. STATIC INLINE bool Chip_Clock_IsSystemPLLLocked(void)
  132. {
  133. return (bool) ((LPC_SYSCON->SYSPLLSTAT & 1) != 0);
  134. }
  135. /** @brief PLL configuration structure flags for 'flags' field
  136. * These flags control how the PLL configuration function sets up the PLL setup structure.<br>
  137. *
  138. * When the PLL_CONFIGFLAG_USEINRATE flag is selected, the 'InputRate' field in the
  139. * configuration structure must be assigned with the expected PLL frequency. If the
  140. * PLL_CONFIGFLAG_USEINRATE is not used, 'InputRate' is ignored in the configuration
  141. * function and the driver will determine the PLL rate from the currently selected
  142. * PLL source. This flag might be used to configure the PLL input clock more accurately
  143. * when using the WDT oscillator or a more dyanmic CLKIN source.<br>
  144. *
  145. * When the PLL_CONFIGFLAG_FORCENOFRACT flag is selected, the PLL hardware for the
  146. * automatic bandwidth selection, Spread Spectrum (SS) support, and fractional M-divider
  147. * are not used.<br>
  148. */
  149. #define PLL_CONFIGFLAG_USEINRATE (1 << 0) /*!< Flag to use InputRate in PLL configuration structure for setup */
  150. #define PLL_CONFIGFLAG_FORCENOFRACT (1 << 2) /*!< Force non-fractional output mode, PLL output will not use the fractional, automatic bandwidth, or SS hardware */
  151. /** @brief PLL Spread Spectrum (SS) Programmable modulation frequency
  152. * See (MF) field in the SYSPLLSSCTRL1 register in the UM.
  153. */
  154. typedef enum {
  155. SS_MF_512 = (0 << 20), /*!< Nss = 512 (fm ˜ 3.9 - 7.8 kHz) */
  156. SS_MF_384 = (1 << 20), /*!< Nss ˜= 384 (fm ˜ 5.2 - 10.4 kHz) */
  157. SS_MF_256 = (2 << 20), /*!< Nss = 256 (fm ˜ 7.8 - 15.6 kHz) */
  158. SS_MF_128 = (3 << 20), /*!< Nss = 128 (fm ˜ 15.6 - 31.3 kHz) */
  159. SS_MF_64 = (4 << 20), /*!< Nss = 64 (fm ˜ 32.3 - 64.5 kHz) */
  160. SS_MF_32 = (5 << 20), /*!< Nss = 32 (fm ˜ 62.5- 125 kHz) */
  161. SS_MF_24 = (6 << 20), /*!< Nss ˜= 24 (fm ˜ 83.3- 166.6 kHz) */
  162. SS_MF_16 = (7 << 20) /*!< Nss = 16 (fm ˜ 125- 250 kHz) */
  163. } SS_PROGMODFM_T;
  164. /** @brief PLL Spread Spectrum (SS) Programmable frequency modulation depth
  165. * See (MR) field in the SYSPLLSSCTRL1 register in the UM.
  166. */
  167. typedef enum {
  168. SS_MR_K0 = (0 << 23), /*!< k = 0 (no spread spectrum) */
  169. SS_MR_K1 = (1 << 23), /*!< k = 1 */
  170. SS_MR_K1_5 = (2 << 23), /*!< k = 1.5 */
  171. SS_MR_K2 = (3 << 23), /*!< k = 2 */
  172. SS_MR_K3 = (4 << 23), /*!< k = 3 */
  173. SS_MR_K4 = (5 << 23), /*!< k = 4 */
  174. SS_MR_K6 = (6 << 23), /*!< k = 6 */
  175. SS_MR_K8 = (7 << 23) /*!< k = 8 */
  176. } SS_PROGMODDP_T;
  177. /** @brief PLL Spread Spectrum (SS) Modulation waveform control
  178. * See (MC) field in the SYSPLLSSCTRL1 register in the UM.<br>
  179. * Compensation for low pass filtering of the PLL to get a triangular
  180. * modulation at the output of the PLL, giving a flat frequency spectrum.
  181. */
  182. typedef enum {
  183. SS_MC_NOC = (0 << 26), /*!< no compensation */
  184. SS_MC_RECC = (2 << 26), /*!< recommended setting */
  185. SS_MC_MAXC = (3 << 26), /*!< max. compensation */
  186. } SS_MODWVCTRL_T;
  187. /** @brief PLL configuration structure
  188. * This structure can be used to configure the settings for a PLL
  189. * setup structure. Fill in the desired configuration for the PLL
  190. * and call the PLL setup function to fill in a PLL setup structure.
  191. */
  192. typedef struct {
  193. uint32_t desiredRate; /*!< Desired PLL rate in Hz */
  194. uint32_t InputRate; /*!< PLL input clock in Hz, only used if PLL_CONFIGFLAG_USEINRATE flag is set */
  195. uint32_t flags; /*!< PLL configuration flags, Or'ed value of PLL_CONFIGFLAG_* definitions */
  196. SS_PROGMODFM_T ss_mf; /*!< SS Programmable modulation frequency, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */
  197. SS_PROGMODDP_T ss_mr; /*!< SS Programmable frequency modulation depth, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */
  198. SS_MODWVCTRL_T ss_mc; /*!< SS Modulation waveform control, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */
  199. bool mfDither; /*!< false for fixed modulation frequency or true for dithering, only applicable when not using PLL_CONFIGFLAG_FORCENOFRACT flag */
  200. } PLL_CONFIG_T;
  201. /** @brief PLL setup structure flags for 'flags' field
  202. * These flags control how the PLL setup function sets up the PLL
  203. */
  204. #define PLL_SETUPFLAG_POWERUP (1 << 0) /*!< Setup will power on the PLL after setup */
  205. #define PLL_SETUPFLAG_WAITLOCK (1 << 1) /*!< Setup will wait for PLL lock, implies the PLL will be pwoered on */
  206. #define PLL_SETUPFLAG_ADGVOLT (1 << 2) /*!< Optimize system voltage for the new PLL rate */
  207. /** @brief PLL setup structure
  208. * This structure can be used to pre-build a PLL setup configuration
  209. * at run-time and quickly set the PLL to the configuration. It can be
  210. * populated with the PLL setup function. If powering up or waiting
  211. * for PLL lock, the PLL input clock source should be configured prior
  212. * to PLL setup.
  213. */
  214. typedef struct {
  215. uint32_t flags; /*!< PLL setup flags, Or'ed value of PLL_SETUPFLAG_* definitions */
  216. uint32_t SYSPLLCTRL; /*!< PLL control register */
  217. uint32_t SYSPLLNDEC; /*!< PLL NDEC register */
  218. uint32_t SYSPLLPDEC; /*!< PLL PDEC register */
  219. uint32_t SYSPLLSSCTRL[2]; /*!< PLL SSCTL registers */
  220. } PLL_SETUP_T;
  221. /** @brief PLL status definitions
  222. */
  223. typedef enum {
  224. PLL_ERROR_SUCCESS = 0, /*!< PLL operation was successful */
  225. PLL_ERROR_OUTPUT_TOO_LOW, /*!< PLL output rate request was too low */
  226. PLL_ERROR_OUTPUT_TOO_HIGH, /*!< PLL output rate request was too high */
  227. PLL_ERROR_INPUT_TOO_LOW, /*!< PLL input rate is too low */
  228. PLL_ERROR_INPUT_TOO_HIGH, /*!< PLL input rate is too high */
  229. PLL_ERROR_OUTSIDE_INTLIMIT /*!< Requested output rate isn't possible */
  230. } PLL_ERROR_T;
  231. /**
  232. * @brief Return System PLL output clock rate from setup structure
  233. * @param pSetup : Pointer to a PLL setup structure
  234. * @return System PLL output clock rate the setup structure will generate
  235. */
  236. uint32_t Chip_Clock_GetSystemPLLOutFromSetup(PLL_SETUP_T *pSetup);
  237. /**
  238. * @brief Set PLL output based on the passed PLL setup data
  239. * @param pControl : Pointer to populated PLL control structure to generate setup with
  240. * @param pSetup : Pointer to PLL setup structure to be filled
  241. * @return PLL_ERROR_SUCCESS on success, or PLL setup error code
  242. * @note Actual frequency for setup may vary from the desired frequency based on the
  243. * accuracy of input clocks, rounding, non-fractional PLL mode, etc.
  244. */
  245. PLL_ERROR_T Chip_Clock_SetupPLLData(PLL_CONFIG_T *pControl, PLL_SETUP_T *pSetup);
  246. /**
  247. * @brief Set PLL output from PLL setup structure (precise frequency)
  248. * @param pSetup : Pointer to populated PLL setup structure
  249. * @return PLL_ERROR_SUCCESS on success, or PLL setup error code
  250. * @note This function will power off the PLL, setup the PLL with the
  251. * new setup data, and then optionally powerup the PLL, wait for PLL lock,
  252. * and adjust system voltages to the new PLL rate. The function will not
  253. * alter any source clocks (ie, main systen clock) that may use the PLL,
  254. * so these should be setup prior to and after exiting the function.
  255. */
  256. PLL_ERROR_T Chip_Clock_SetupSystemPLLPrec(PLL_SETUP_T *pSetup);
  257. /**
  258. * @brief Set PLL output based on the multiplier and input frequency
  259. * @param multiply_by : multiplier
  260. * @param input_freq : Clock input frequency of the PLL
  261. * @return Nothing
  262. * @note Unlike the Chip_Clock_SetupSystemPLLPrec() function, this
  263. * function does not disable or enable PLL power, wait for PLL lock,
  264. * or adjust system voltages. These must be done in the application.
  265. * The function will not alter any source clocks (ie, main systen clock)
  266. * that may use the PLL, so these should be setup prior to and after
  267. * exiting the function.
  268. */
  269. void Chip_Clock_SetupSystemPLL(uint32_t multiply_by, uint32_t input_freq);
  270. /**
  271. * @}
  272. */
  273. #ifdef __cplusplus
  274. }
  275. #endif
  276. #endif /* __PLL_5410X_H_ */