scif_uc3l.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962
  1. /*This file has been prepared for Doxygen automatic documentation generation.*/
  2. /*! \file *********************************************************************
  3. *
  4. * \brief System Control InterFace(SCIF) driver.
  5. *
  6. *
  7. * - Compiler: IAR EWAVR32 and GNU GCC for AVR32
  8. * - Supported devices: All AVR32 UC3L devices.
  9. * - AppNote:
  10. *
  11. * \author Atmel Corporation: http://www.atmel.com \n
  12. * Support and FAQ: http://support.atmel.no/
  13. *
  14. *****************************************************************************/
  15. /* Copyright (C) 2009 - 2011 Atmel Corporation. All rights reserved.
  16. *
  17. * Redistribution and use in source and binary forms, with or without
  18. * modification, are permitted provided that the following conditions are met:
  19. *
  20. * 1. Redistributions of source code must retain the above copyright notice, this
  21. * list of conditions and the following disclaimer.
  22. *
  23. * 2. Redistributions in binary form must reproduce the above copyright notice,
  24. * this list of conditions and the following disclaimer in the documentation
  25. * and/or other materials provided with the distribution.
  26. *
  27. * 3. The name of Atmel may not be used to endorse or promote products derived
  28. * from this software without specific prior written permission.
  29. *
  30. * 4. This software may only be redistributed and used in connection with an Atmel
  31. * AVR product.
  32. *
  33. * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
  34. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  35. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
  36. * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
  37. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  38. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  39. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  40. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  41. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  42. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
  43. *
  44. */
  45. #include "compiler.h"
  46. #include "scif_uc3l.h"
  47. /*! \name SCIF Writable Bit-Field Registers
  48. */
  49. //! @{
  50. typedef union
  51. {
  52. unsigned long oscctrl0;
  53. avr32_scif_oscctrl0_t OSCCTRL0;
  54. } u_avr32_scif_oscctrl0_t;
  55. typedef union
  56. {
  57. unsigned long oscctrl32;
  58. avr32_scif_oscctrl32_t OSCCTRL32;
  59. } u_avr32_scif_oscctrl32_t;
  60. typedef union
  61. {
  62. unsigned long dfll0conf;
  63. avr32_scif_dfll0conf_t DFLL0CONF;
  64. } u_avr32_scif_dfll0conf_t;
  65. typedef union
  66. {
  67. unsigned long dfll0ssg;
  68. avr32_scif_dfll0ssg_t DFLL0SSG;
  69. } u_avr32_scif_dfll0ssg_t;
  70. #if (UC3L0128 || UC3L0256)
  71. typedef union
  72. {
  73. unsigned long pll0;
  74. avr32_scif_pll_t PLL0;
  75. } u_avr32_scif_pll_t;
  76. #endif
  77. //! @}
  78. /**
  79. ** Interrupt Functions
  80. **/
  81. // Implemented as inline in scif_uc3l.h
  82. /**
  83. ** Power and Clocks Status Functions
  84. **/
  85. // Implemented as inline in scif_uc3l.h
  86. /**
  87. ** OSC0/OSC1 Functions
  88. **/
  89. long int scif_start_osc(scif_osc_t osc, const scif_osc_opt_t *opt, bool wait_for_ready)
  90. {
  91. //# Implementation note: this code doesn't consider the osc input parameter
  92. //# because UC3L devices only implement OSC0.
  93. u_avr32_scif_oscctrl0_t u_avr32_scif_oscctrl0 = {AVR32_SCIF.oscctrl0};
  94. #ifdef AVR32SFW_INPUT_CHECK
  95. // Check that the input frequency is in the supported frequency range.
  96. if( (opt->freq_hz < SCIF_EXT_CRYSTAL_MIN_FREQ_HZ)
  97. || (opt->freq_hz > SCIF_EXT_CRYSTAL_MAX_FREQ_HZ))
  98. {
  99. return -1;
  100. }
  101. // Check : for OSC0/OSC1, only 2 modes are supported
  102. if( (opt->mode != SCIF_OSC_MODE_EXT_CLK)
  103. && (opt->mode != SCIF_OSC_MODE_2PIN_CRYSTAL))
  104. {
  105. return -1;
  106. }
  107. // Check that the startup value is in the supported range.
  108. if(opt->startup > (unsigned char)AVR32_SCIF_OSCCTRL0_STARTUP_16384_RCOSC)
  109. {
  110. return -1;
  111. }
  112. // Check that the gain value is in the supported range.
  113. if(opt->gain > AVR32_SCIF_OSCCTRL0_GAIN_G3)
  114. {
  115. return -1;
  116. }
  117. #endif // AVR32SFW_INPUT_CHECK
  118. // Configure & start OSC0.
  119. u_avr32_scif_oscctrl0.OSCCTRL0.mode = opt->mode;
  120. u_avr32_scif_oscctrl0.OSCCTRL0.gain = opt->gain;
  121. u_avr32_scif_oscctrl0.OSCCTRL0.startup = opt->startup;
  122. u_avr32_scif_oscctrl0.OSCCTRL0.oscen = ENABLE;
  123. AVR32_ENTER_CRITICAL_REGION( );
  124. // Unlock the write-protected OSCCTRL0 register
  125. SCIF_UNLOCK(AVR32_SCIF_OSCCTRL0);
  126. // Write
  127. AVR32_SCIF.oscctrl0 = u_avr32_scif_oscctrl0.oscctrl0;
  128. AVR32_LEAVE_CRITICAL_REGION( );
  129. if(true == wait_for_ready)
  130. {
  131. // Wait until OSC0 is stable and ready to be used.
  132. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_OSC0RDY_MASK))
  133. return -1;
  134. }
  135. return PASS;
  136. }
  137. bool scif_is_osc_ready(scif_osc_t osc)
  138. {
  139. //# Implementation note: this code doesn't consider the osc input parameter
  140. //# because UC3L devices only implement OSC0.
  141. return((AVR32_SCIF.pclksr & AVR32_SCIF_PCLKSR_OSC0RDY_MASK)>>AVR32_SCIF_PCLKSR_OSC0RDY_OFFSET);
  142. }
  143. long int scif_stop_osc(scif_osc_t osc)
  144. {
  145. //# Implementation note: this code doesn't consider the osc input parameter
  146. //# because UC3L devices only implement OSC0.
  147. unsigned long temp = AVR32_SCIF.oscctrl0;
  148. temp &= ~AVR32_SCIF_OSCCTRL0_OSCEN_MASK;
  149. AVR32_ENTER_CRITICAL_REGION( );
  150. // Unlock the write-protected OSCCTRL0 register
  151. SCIF_UNLOCK(AVR32_SCIF_OSCCTRL0);
  152. // Stop OSC0.
  153. AVR32_SCIF.oscctrl0 = temp;
  154. AVR32_LEAVE_CRITICAL_REGION( );
  155. return PASS;
  156. }
  157. long int scif_configure_osc_crystalmode(scif_osc_t osc, unsigned int fcrystal)
  158. {
  159. //# Implementation note: this code doesn't consider the osc input parameter
  160. //# because UC3L devices only implement OSC0.
  161. u_avr32_scif_oscctrl0_t u_avr32_scif_oscctrl0 = {AVR32_SCIF.oscctrl0};
  162. // Configure the oscillator mode to crystal and set the gain according to the
  163. // cyrstal frequency.
  164. u_avr32_scif_oscctrl0.OSCCTRL0.mode = SCIF_OSC_MODE_2PIN_CRYSTAL;
  165. u_avr32_scif_oscctrl0.OSCCTRL0.gain = (fcrystal < 900000) ? AVR32_SCIF_OSCCTRL0_GAIN_G0 :
  166. (fcrystal < 3000000) ? AVR32_SCIF_OSCCTRL0_GAIN_G1 :
  167. (fcrystal < 8000000) ? AVR32_SCIF_OSCCTRL0_GAIN_G2 :
  168. AVR32_SCIF_OSCCTRL0_GAIN_G3;
  169. AVR32_ENTER_CRITICAL_REGION( );
  170. // Unlock the write-protected OSCCTRL0 register
  171. SCIF_UNLOCK(AVR32_SCIF_OSCCTRL0);
  172. // Write
  173. AVR32_SCIF.oscctrl0 = u_avr32_scif_oscctrl0.oscctrl0;
  174. AVR32_LEAVE_CRITICAL_REGION( );
  175. // Add here after support for OSC1 for devices that implement OSC1.
  176. return PASS;
  177. }
  178. long int scif_configure_osc_extmode(scif_osc_t osc)
  179. {
  180. u_avr32_scif_oscctrl0_t u_avr32_scif_oscctrl0 = {AVR32_SCIF.oscctrl0};
  181. // Read Register
  182. u_avr32_scif_oscctrl0.OSCCTRL0 = AVR32_SCIF.OSCCTRL0 ;
  183. // Modify : Configure the oscillator mode to crystal and set the gain according to the
  184. // cyrstal frequency.
  185. u_avr32_scif_oscctrl0.OSCCTRL0.mode = SCIF_OSC_MODE_EXT_CLK;
  186. AVR32_ENTER_CRITICAL_REGION( );
  187. // Unlock the write-protected OSCCTRL0 register
  188. SCIF_UNLOCK(AVR32_SCIF_OSCCTRL0);
  189. // Write Back
  190. AVR32_SCIF.OSCCTRL0 = u_avr32_scif_oscctrl0.OSCCTRL0;
  191. AVR32_LEAVE_CRITICAL_REGION( );
  192. return PASS;
  193. }
  194. long int scif_enable_osc(scif_osc_t osc, unsigned int startup, bool wait_for_ready)
  195. {
  196. //# Implementation note: this code doesn't consider the osc input parameter
  197. //# because UC3L devices only implement OSC0.
  198. u_avr32_scif_oscctrl0_t u_avr32_scif_oscctrl0 = {AVR32_SCIF.oscctrl0};
  199. // Configure the oscillator startup and enable the osc.
  200. u_avr32_scif_oscctrl0.OSCCTRL0.startup = startup;
  201. u_avr32_scif_oscctrl0.OSCCTRL0.oscen = ENABLE;
  202. AVR32_ENTER_CRITICAL_REGION( );
  203. // Unlock the write-protected OSCCTRL0 register
  204. SCIF_UNLOCK(AVR32_SCIF_OSCCTRL0);
  205. // Write
  206. AVR32_SCIF.oscctrl0 = u_avr32_scif_oscctrl0.oscctrl0;
  207. AVR32_LEAVE_CRITICAL_REGION( );
  208. if(true == wait_for_ready)
  209. {
  210. // Wait until OSC0 is stable and ready to be used.
  211. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_OSC0RDY_MASK))
  212. return -1;
  213. }
  214. return PASS;
  215. }
  216. /**
  217. ** OSC32 Functions
  218. **/
  219. long int scif_start_osc32(const scif_osc32_opt_t *opt, bool wait_for_ready)
  220. {
  221. u_avr32_scif_oscctrl32_t u_avr32_scif_oscctrl32 = {AVR32_SCIF.oscctrl32};
  222. #ifdef AVR32SFW_INPUT_CHECK
  223. // Check that the input frequency is in the supported frequency range.
  224. if( (opt->freq_hz < SCIF_EXT_CRYSTAL_MIN_FREQ_HZ)
  225. || (opt->freq_hz > SCIF_EXT_CRYSTAL_MAX_FREQ_HZ))
  226. {
  227. return -1;
  228. }
  229. // Check : for OSC32, 3 modes are supported
  230. if( (opt->mode != SCIF_OSC_MODE_EXT_CLK)
  231. && (opt->mode != SCIF_OSC_MODE_2PIN_CRYSTAL)
  232. && (opt->mode != SCIF_OSC_MODE_2PIN_CRYSTAL_HICUR)
  233. )
  234. {
  235. return -1;
  236. }
  237. // Check that the startup value is in the supported range.
  238. if(opt->startup > (unsigned char)AVR32_SCIF_OSCCTRL32_STARTUP_524288_RCOSC)
  239. {
  240. return -1;
  241. }
  242. #endif // AVR32SFW_INPUT_CHECK
  243. // Note: RC32K is automatically output on PA20 upon reset, which is the pin
  244. // for XOUT32_2 => we must disable this output before setting-up the OSC32K
  245. // (in case the OSC32 is connected to XIN32_2/XOUT32_2).
  246. scif_disable_rc32out();
  247. // Configure & start OSC32.
  248. u_avr32_scif_oscctrl32.OSCCTRL32.mode = opt->mode;
  249. u_avr32_scif_oscctrl32.OSCCTRL32.pinsel = opt->pinsel;
  250. u_avr32_scif_oscctrl32.OSCCTRL32.en32k = opt->en32k;
  251. u_avr32_scif_oscctrl32.OSCCTRL32.en1k = opt->en1k;
  252. u_avr32_scif_oscctrl32.OSCCTRL32.startup = opt->startup;
  253. u_avr32_scif_oscctrl32.OSCCTRL32.osc32en = ENABLE;
  254. // Note: the OSCCTRL32 register is protected by a lock. To safely unlock then
  255. // write in the register, perform this operation inside a critical region.
  256. AVR32_ENTER_CRITICAL_REGION( );
  257. // Unlock the write-protected OSCCTRL32 register
  258. SCIF_UNLOCK(AVR32_SCIF_OSCCTRL32);
  259. // write
  260. AVR32_SCIF.oscctrl32 = u_avr32_scif_oscctrl32.oscctrl32;
  261. AVR32_LEAVE_CRITICAL_REGION( );
  262. if(true == wait_for_ready)
  263. {
  264. // Wait until OSC32 is stable and ready to be used.
  265. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_OSC32RDY_MASK))
  266. return -1;
  267. }
  268. return PASS;
  269. }
  270. long scif_stop_osc32()
  271. {
  272. unsigned long temp = AVR32_SCIF.oscctrl32;
  273. temp &= ~AVR32_SCIF_OSCCTRL32_OSC32EN_MASK;
  274. // Note: the OSCCTRL32 register is protected by a lock.
  275. // Unlock the write-protected OSCCTRL32 register
  276. SCIF_UNLOCK(AVR32_SCIF_OSCCTRL32);
  277. // Stop OSC32.
  278. AVR32_SCIF.oscctrl32 = temp;
  279. return PASS;
  280. }
  281. /**
  282. ** DFLL Control Functions
  283. **/
  284. //! The different DFLL0 modes
  285. typedef enum
  286. {
  287. SCIF_DFLL0_MODE_OPENLOOP = 0,
  288. SCIF_DFLL0_MODE_CLOSEDLOOP
  289. } scif_dfll_mode_t;
  290. long int scif_dfll0_openloop_start(const scif_dfll_openloop_conf_t *pdfllconfig)
  291. {
  292. u_avr32_scif_dfll0conf_t u_avr32_scif_dfll0conf = {AVR32_SCIF.dfll0conf};
  293. #ifdef AVR32SFW_INPUT_CHECK
  294. if((pdfllconfig->fine >> AVR32_SCIF_DFLL0CONF_FINE_SIZE))
  295. return -1;
  296. if((pdfllconfig->coarse >> AVR32_SCIF_DFLL0CONF_COARSE_SIZE))
  297. return -1;
  298. #endif
  299. // Enable the DFLL0: DFLL0CONF.EN=1
  300. u_avr32_scif_dfll0conf.DFLL0CONF.en = ENABLE;
  301. AVR32_ENTER_CRITICAL_REGION( );
  302. SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
  303. AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
  304. AVR32_LEAVE_CRITICAL_REGION( );
  305. // Wait for PCLKSR.DFLL0RDY is high
  306. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  307. return -1;
  308. // Set the DFLL0 to operate in open mode: DFLL0CONF.MODE=0
  309. u_avr32_scif_dfll0conf.DFLL0CONF.mode = SCIF_DFLL0_MODE_OPENLOOP;
  310. AVR32_ENTER_CRITICAL_REGION( );
  311. SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
  312. AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
  313. AVR32_LEAVE_CRITICAL_REGION( );
  314. // Wait for PCLKSR.DFLL0RDY is high
  315. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  316. return -1;
  317. // Write DFLL0CONF.COARSE & DFLL0CONF.FINE
  318. u_avr32_scif_dfll0conf.DFLL0CONF.coarse = pdfllconfig->coarse;
  319. u_avr32_scif_dfll0conf.DFLL0CONF.fine = pdfllconfig->fine;
  320. AVR32_ENTER_CRITICAL_REGION( );
  321. SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
  322. AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
  323. AVR32_LEAVE_CRITICAL_REGION( );
  324. // Wait for PCLKSR.DFLL0RDY is high
  325. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  326. return -1;
  327. return PASS;
  328. }
  329. #define SCIF_DFLL_COARSE_MAX (AVR32_SCIF_COARSE_MASK >> AVR32_SCIF_COARSE_OFFSET)
  330. #define SCIF_DFLL_FINE_MAX (AVR32_SCIF_FINE_MASK >> AVR32_SCIF_FINE_OFFSET)
  331. #define SCIF_DFLL_FINE_HALF (1 << (AVR32_SCIF_DFLL0CONF_FINE_SIZE-1))
  332. long int scif_dfll0_openloop_start_auto(unsigned long TargetFreqkHz)
  333. {
  334. scif_dfll_openloop_conf_t Dfll0Conf;
  335. unsigned long Coarse;
  336. unsigned long Fine;
  337. unsigned long CoarseFreq;
  338. unsigned long DeltaFreq;
  339. #ifdef AVR32SFW_INPUT_CHECK
  340. if((TargetFreqkHz < SCIF_DFLL_MINFREQ_KHZ) || (TargetFreqkHz > SCIF_DFLL_MAXFREQ_KHZ))
  341. return -1;
  342. #endif
  343. //**
  344. //** Dynamically compute the COARSE and FINE values.
  345. //**
  346. // Fdfll = (Fmin+(Fmax-Fmin)*(COARSE/0xFF))*(1+X*(FINE-0x100)/0x1FF)=CoarseFreq*(1+X*(FINE-0x100)/0x1FF)
  347. // Compute the COARSE value.
  348. Coarse = ((TargetFreqkHz - SCIF_DFLL_MINFREQ_KHZ)*SCIF_DFLL_COARSE_MAX)/(SCIF_DFLL_MAXFREQ_KHZ - SCIF_DFLL_MINFREQ_KHZ);
  349. // Compute the COARSE DFLL frequency.
  350. CoarseFreq = SCIF_DFLL_MINFREQ_KHZ + (((SCIF_DFLL_MAXFREQ_KHZ - SCIF_DFLL_MINFREQ_KHZ)/SCIF_DFLL_COARSE_MAX)*Coarse);
  351. // Compute the coarse error.
  352. DeltaFreq = TargetFreqkHz - CoarseFreq;
  353. // Compute the FINE value.
  354. // Fine = ((DeltaFreq*SCIF_DFLL_FINE_MAX)*10/CoarseFreq) + SCIF_DFLL_FINE_HALF;
  355. // Theorical equation don't work on silicon: the best was to use X=5/2 to
  356. // find FINE, then do FINE/4.
  357. Fine = ((DeltaFreq*SCIF_DFLL_FINE_MAX)*2/CoarseFreq*5) + SCIF_DFLL_FINE_HALF;
  358. Fine >>=2;
  359. Dfll0Conf.coarse = Coarse;
  360. Dfll0Conf.fine = Fine;
  361. return(scif_dfll0_openloop_start(&Dfll0Conf));
  362. }
  363. long int scif_dfll0_openloop_updatefreq(const scif_dfll_openloop_conf_t *pdfllconfig)
  364. {
  365. u_avr32_scif_dfll0conf_t u_avr32_scif_dfll0conf = {AVR32_SCIF.dfll0conf};
  366. #ifdef AVR32SFW_INPUT_CHECK
  367. if((pdfllconfig->fine >> AVR32_SCIF_DFLL0CONF_FINE_SIZE))
  368. return -1;
  369. #endif
  370. // It is assumed that the DFLL is enabled and operates in open-loop mode.
  371. // Wait for PCLKSR.DFLL0RDY is high
  372. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  373. return -1;
  374. // Write DFLL0CONF.COARSE & DFLL0CONF.FINE
  375. u_avr32_scif_dfll0conf.DFLL0CONF.coarse = pdfllconfig->coarse;
  376. u_avr32_scif_dfll0conf.DFLL0CONF.fine = pdfllconfig->fine;
  377. AVR32_ENTER_CRITICAL_REGION( );
  378. SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
  379. AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
  380. AVR32_LEAVE_CRITICAL_REGION( );
  381. // Wait for PCLKSR.DFLL0RDY is high
  382. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  383. return -1;
  384. return PASS;
  385. }
  386. long int scif_dfll0_openloop_stop(void)
  387. {
  388. u_avr32_scif_dfll0conf_t u_avr32_scif_dfll0conf = {AVR32_SCIF.dfll0conf};
  389. // Before disabling the DFLL, the output freq of the DFLL should be set to a
  390. // minimum: set COARSE to 0x00.
  391. // Wait for PCLKSR.DFLL0RDY is high
  392. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  393. return -1;
  394. // Write DFLL0CONF.COARSE
  395. u_avr32_scif_dfll0conf.DFLL0CONF.coarse = 0;
  396. AVR32_ENTER_CRITICAL_REGION( );
  397. SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
  398. AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
  399. AVR32_LEAVE_CRITICAL_REGION( );
  400. // Wait for PCLKSR.DFLL0RDY is high
  401. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  402. return -1;
  403. // Disable the DFLL
  404. u_avr32_scif_dfll0conf.DFLL0CONF.en = 0;
  405. AVR32_ENTER_CRITICAL_REGION( );
  406. SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
  407. AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
  408. AVR32_LEAVE_CRITICAL_REGION( );
  409. // Wait for PCLKSR.DFLL0RDY is high
  410. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  411. return -1;
  412. return PASS;
  413. }
  414. long int scif_dfll0_ssg_enable(scif_dfll_ssg_conf_t *pssg_conf)
  415. {
  416. u_avr32_scif_dfll0ssg_t u_avr32_scif_dfll0ssg = {AVR32_SCIF.dfll0ssg};
  417. u_avr32_scif_dfll0ssg.DFLL0SSG.en = ENABLE;
  418. u_avr32_scif_dfll0ssg.DFLL0SSG.prbs = pssg_conf->use_random;
  419. u_avr32_scif_dfll0ssg.DFLL0SSG.amplitude = pssg_conf->amplitude;
  420. u_avr32_scif_dfll0ssg.DFLL0SSG.stepsize = pssg_conf->step_size;
  421. AVR32_ENTER_CRITICAL_REGION( );
  422. SCIF_UNLOCK(AVR32_SCIF_DFLL0SSG);
  423. AVR32_SCIF.dfll0ssg = u_avr32_scif_dfll0ssg.dfll0ssg;
  424. AVR32_LEAVE_CRITICAL_REGION( );
  425. return PASS;
  426. }
  427. long int scif_dfll0_closedloop_start(const scif_dfll_closedloop_conf_t *pdfllconfig)
  428. {
  429. u_avr32_scif_dfll0conf_t u_avr32_scif_dfll0conf = {AVR32_SCIF.dfll0conf};
  430. volatile unsigned long tempo;
  431. #ifdef AVR32SFW_INPUT_CHECK
  432. if((pdfllconfig->coarse >> AVR32_SCIF_DFLL0CONF_COARSE_SIZE))
  433. return -1;
  434. if( (pdfllconfig->finemaxstep >> AVR32_SCIF_DFLL0STEP_FSTEP_SIZE)
  435. || (pdfllconfig->coarsemaxstep >> AVR32_SCIF_DFLL0STEP_CSTEP_SIZE) )
  436. return -1;
  437. #endif
  438. // Enable the DFLL0: DFLL0CONF.EN=1
  439. u_avr32_scif_dfll0conf.DFLL0CONF.en = ENABLE;
  440. AVR32_ENTER_CRITICAL_REGION( );
  441. SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
  442. AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
  443. AVR32_LEAVE_CRITICAL_REGION( );
  444. // Wait for PCLKSR.DFLL0RDY is high
  445. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  446. return -1;
  447. // Set the maxstep values
  448. tempo = ((pdfllconfig->coarsemaxstep << AVR32_SCIF_DFLL0STEP_CSTEP_OFFSET)&AVR32_SCIF_DFLL0STEP_CSTEP_MASK)
  449. | ((pdfllconfig->finemaxstep << AVR32_SCIF_DFLL0STEP_FSTEP_OFFSET)&AVR32_SCIF_DFLL0STEP_FSTEP_MASK);
  450. AVR32_ENTER_CRITICAL_REGION( );
  451. SCIF_UNLOCK(AVR32_SCIF_DFLL0STEP);
  452. AVR32_SCIF.dfll0step = tempo;
  453. AVR32_LEAVE_CRITICAL_REGION( );
  454. // Wait for PCLKSR.DFLL0RDY is high
  455. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  456. return -1;
  457. // Set the fmul
  458. AVR32_ENTER_CRITICAL_REGION( );
  459. #if AVR32_SCIF_H_VERSION < 110
  460. SCIF_UNLOCK(AVR32_SCIF_DFLL0FMUL);
  461. AVR32_SCIF.dfll0fmul = (pdfllconfig->imul << AVR32_SCIF_DFLL0FMUL_FMUL_OFFSET)&AVR32_SCIF_DFLL0FMUL_FMUL_MASK;
  462. #else
  463. SCIF_UNLOCK(AVR32_SCIF_DFLL0MUL);
  464. AVR32_SCIF.dfll0mul = ((pdfllconfig->fmul << AVR32_SCIF_DFLL0MUL_FMUL_OFFSET)&AVR32_SCIF_DFLL0MUL_FMUL_MASK)
  465. | ((pdfllconfig->imul << AVR32_SCIF_DFLL0MUL_IMUL_OFFSET)&AVR32_SCIF_DFLL0MUL_IMUL_MASK);
  466. #endif
  467. AVR32_LEAVE_CRITICAL_REGION( );
  468. // Wait for PCLKSR.DFLL0RDY is high
  469. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  470. return -1;
  471. // Set the DFLL0 to operate in closed-loop mode: DFLL0CONF.MODE=1
  472. u_avr32_scif_dfll0conf.DFLL0CONF.mode = SCIF_DFLL0_MODE_CLOSEDLOOP;
  473. u_avr32_scif_dfll0conf.DFLL0CONF.coarse = pdfllconfig->coarse;
  474. AVR32_ENTER_CRITICAL_REGION( );
  475. SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
  476. AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
  477. AVR32_LEAVE_CRITICAL_REGION( );
  478. // Wait for PCLKSR.DFLL0RDY is high
  479. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
  480. return -1;
  481. // Wait until the DFLL is locked on Fine value, and is ready to be selected as
  482. // clock source with a highly accurate output clock.
  483. if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0LOCKF_MASK))
  484. return -1;
  485. return PASS;
  486. }
  487. long int scif_dfll0_closedloop_configure_and_start( const scif_gclk_opt_t *gc_dfllif_ref_opt,
  488. unsigned long long target_freq_hz,
  489. bool enable_ssg)
  490. {
  491. scif_dfll_closedloop_conf_t DfllConfig;
  492. int gc_source_clock_freq_hz;
  493. // This function only supports the following source clocks for the CLK_DFLLIF_REF generic clock:
  494. // SCIF_GCCTRL_SLOWCLOCK (aka RCSYS), SCIF_GCCTRL_OSC32K, SCIF_GCCTRL_RC32K,
  495. // SCIF_GCCTRL_OSC0, SCIF_GCCTRL_RC120M, SCIF_GCCTRL_CLK1K.
  496. if(SCIF_GCCTRL_SLOWCLOCK == gc_dfllif_ref_opt->clock_source)
  497. gc_source_clock_freq_hz = SCIF_SLOWCLOCK_FREQ_HZ;
  498. else if((SCIF_GCCTRL_OSC32K == gc_dfllif_ref_opt->clock_source) || (SCIF_GCCTRL_RC32K == gc_dfllif_ref_opt->clock_source))
  499. gc_source_clock_freq_hz = SCIF_RC32K_FREQ_HZ;
  500. else if(SCIF_GCCTRL_OSC0 == gc_dfllif_ref_opt->clock_source)
  501. gc_source_clock_freq_hz = gc_dfllif_ref_opt->extosc_f;
  502. else if(SCIF_GCCTRL_RC120M == gc_dfllif_ref_opt->clock_source)
  503. gc_source_clock_freq_hz = SCIF_RC120M_FREQ_HZ;
  504. else if(SCIF_GCCTRL_CLK1K == gc_dfllif_ref_opt->clock_source)
  505. gc_source_clock_freq_hz = 1000;
  506. else
  507. return -1;
  508. // Configure and start the DFLL main reference generic clock (CLK_DFLLIF_REF).
  509. if(scif_dfll0_closedloop_mainref_gc_enable(gc_dfllif_ref_opt))
  510. return(-1);
  511. // Configure the DFLL.
  512. // The coarse value (= (dfll_f - SCIF_DFLL_MINFREQ_KHZ)*255/(SCIF_DFLL_MAXFREQ_KHZ - SCIF_DFLL_MINFREQ_KHZ))
  513. DfllConfig.coarse = ((unsigned long long)(target_freq_hz - SCIF_DFLL_MINFREQ_HZ)*255)/(SCIF_DFLL_MAXFREQ_HZ - SCIF_DFLL_MINFREQ_HZ);
  514. // imul = (fDFLL)/fref,
  515. // fmul = (fDFLL*2^16)/fref - imul*2^16,
  516. // with fref being the frequency of the DFLL main reference generic clock
  517. // and fDFLL being the target frequency of the DFLL
  518. DfllConfig.imul = ((unsigned long long)target_freq_hz)/gc_source_clock_freq_hz;
  519. if(0 == gc_dfllif_ref_opt->diven)
  520. {
  521. DfllConfig.fmul = ((unsigned long long)target_freq_hz<<16)/gc_source_clock_freq_hz - ((unsigned long long)(DfllConfig.imul)<<16);
  522. }
  523. else
  524. DfllConfig.fmul = ((((unsigned long long)target_freq_hz<<16)/gc_source_clock_freq_hz - ((unsigned long long)(DfllConfig.imul)<<16))<<1)*(1+gc_dfllif_ref_opt->divider);
  525. // The fine and coarse maxstep values
  526. DfllConfig.finemaxstep = 0x0000004;
  527. DfllConfig.coarsemaxstep = 0x0000004;
  528. // Dithering disabled.
  529. // Configure and start the DFLL0 in closed loop mode.
  530. if(scif_dfll0_closedloop_start(&DfllConfig))
  531. return -1;
  532. // TODO: Future implementation note: add use of the generic clock CLK_DFLLIF_DITHER
  533. // as a reference for the SSG feature.
  534. if(true == enable_ssg)
  535. {
  536. ;
  537. }
  538. return PASS;
  539. }
  540. /**
  541. ** Calibration Functions
  542. **/
  543. /**
  544. ** Critical Path Oscillator Functions
  545. **/
  546. #if ( UC3L0128 || UC3L0256 )
  547. /**
  548. ** PLL0 Functions
  549. **/
  550. long int scif_pll0_setup(const scif_pll_opt_t *opt)
  551. {
  552. u_avr32_scif_pll_t u_avr32_scif_pll;
  553. // Read Register
  554. u_avr32_scif_pll.PLL0 = AVR32_SCIF.PLL[0] ;
  555. // Modify Configuration
  556. u_avr32_scif_pll.PLL0.pllosc = opt->osc;
  557. u_avr32_scif_pll.PLL0.pllopt = opt->pll_freq | (opt->pll_div2 << 1) | (opt->pll_wbwdisable << 2);
  558. u_avr32_scif_pll.PLL0.plldiv = opt->div;
  559. u_avr32_scif_pll.PLL0.pllmul = opt->mul;
  560. u_avr32_scif_pll.PLL0.pllcount= opt->lockcount;
  561. AVR32_ENTER_CRITICAL_REGION( );
  562. // Unlock the write-protected PLL0 register
  563. SCIF_UNLOCK(AVR32_SCIF_PLL0);
  564. // Write Back
  565. AVR32_SCIF.PLL[0] = u_avr32_scif_pll.PLL0;
  566. AVR32_LEAVE_CRITICAL_REGION( );
  567. return 0;
  568. }
  569. long int scif_pll0_enable(void)
  570. {
  571. u_avr32_scif_pll_t u_avr32_scif_pll;
  572. // Read Register
  573. u_avr32_scif_pll.PLL0 = AVR32_SCIF.PLL[0] ;
  574. // Modify Configuration
  575. u_avr32_scif_pll.PLL0.pllen = ENABLE;
  576. AVR32_ENTER_CRITICAL_REGION( );
  577. // Unlock the write-protected PLL0 register
  578. SCIF_UNLOCK(AVR32_SCIF_PLL0);
  579. // Write Back
  580. AVR32_SCIF.PLL[0] = u_avr32_scif_pll.PLL0;
  581. AVR32_LEAVE_CRITICAL_REGION( );
  582. return 0;
  583. }
  584. long int scif_pll0_disable(void)
  585. {
  586. u_avr32_scif_pll_t u_avr32_scif_pll;
  587. // Read Register
  588. u_avr32_scif_pll.PLL0 = AVR32_SCIF.PLL[0] ;
  589. // Modify Configuration
  590. u_avr32_scif_pll.PLL0.pllen = DISABLE;
  591. AVR32_ENTER_CRITICAL_REGION( );
  592. // Unlock the write-protected PLL0 register
  593. SCIF_UNLOCK(AVR32_SCIF_PLL0);
  594. // Write Back
  595. AVR32_SCIF.PLL[0] = u_avr32_scif_pll.PLL0;
  596. AVR32_LEAVE_CRITICAL_REGION( );
  597. return 0;
  598. }
  599. long int scif_wait_for_pll0_locked(void)
  600. {
  601. // Wait until PLL0 is stable and ready to be used.
  602. while(!(AVR32_SCIF.pclksr & AVR32_SCIF_PCLKSR_PLLLOCK0_MASK));
  603. return 0;
  604. }
  605. #endif // #if ( UC3L0128 || UC3L0256 )
  606. /**
  607. ** 120MHz RCosc Functions
  608. **/
  609. void scif_start_rc120M(void)
  610. {
  611. AVR32_ENTER_CRITICAL_REGION( );
  612. // Unlock the write-protected RC120MCR register
  613. SCIF_UNLOCK(AVR32_SCIF_RC120MCR);
  614. AVR32_SCIF.rc120mcr = AVR32_SCIF_RC120MCR_EN_MASK;
  615. AVR32_LEAVE_CRITICAL_REGION( );
  616. }
  617. void scif_stop_rc120M(void)
  618. {
  619. unsigned long temp = AVR32_SCIF.rc120mcr;
  620. temp &= ~AVR32_SCIF_RC120MCR_EN_MASK;
  621. AVR32_ENTER_CRITICAL_REGION( );
  622. // Unlock the write-protected RC120MCR register
  623. SCIF_UNLOCK(AVR32_SCIF_RC120MCR);
  624. AVR32_SCIF.rc120mcr = temp;
  625. AVR32_LEAVE_CRITICAL_REGION( );
  626. }
  627. /**
  628. ** 32kHz internal RCosc (RC32K) Functions
  629. **/
  630. void scif_start_rc32k(void)
  631. {
  632. AVR32_ENTER_CRITICAL_REGION( );
  633. // Unlock the write-protected RC32KCR register
  634. SCIF_UNLOCK(AVR32_SCIF_RC32KCR);
  635. AVR32_SCIF.rc32kcr = AVR32_SCIF_RC32KCR_EN_MASK;
  636. AVR32_LEAVE_CRITICAL_REGION( );
  637. }
  638. void scif_stop_rc32k(void)
  639. {
  640. unsigned long temp = AVR32_SCIF.rc32kcr;
  641. temp &= ~AVR32_SCIF_RC32KCR_EN_MASK;
  642. AVR32_ENTER_CRITICAL_REGION( );
  643. // Unlock the write-protected RC32KCR register
  644. SCIF_UNLOCK(AVR32_SCIF_RC32KCR);
  645. AVR32_SCIF.rc32kcr = temp;
  646. AVR32_LEAVE_CRITICAL_REGION( );
  647. }
  648. void scif_disable_rc32out(void)
  649. {
  650. unsigned long temp;
  651. AVR32_ENTER_CRITICAL_REGION( );
  652. temp = AVR32_PM.ppcr & (~AVR32_PM_PPCR_FRC32_MASK);
  653. // Unforce the RC32 signal from being output on the dedicated pin (PA20).
  654. AVR32_PM.unlock = 0xAA000000 | AVR32_PM_PPCR;
  655. AVR32_PM.ppcr = temp;
  656. AVR32_LEAVE_CRITICAL_REGION( );
  657. }
  658. /**
  659. ** Generic Clock Functions
  660. **/
  661. long int scif_start_gclk(unsigned int gclk, const scif_gclk_opt_t *opt)
  662. {
  663. #ifdef AVR32SFW_INPUT_CHECK
  664. // Check that the generic clock number is correct
  665. if( gclk > AVR32_SCIF_GCLK_NUM )
  666. {
  667. return -1;
  668. }
  669. // Check that the clock source for the generic clock is correct.
  670. if(( opt->clock_source >= SCIF_GCCTRL_OSCSEL_INVALID ) || ( opt->clock_source < 0 ))
  671. {
  672. return -1;
  673. }
  674. #endif // AVR32SFW_INPUT_CHECK
  675. // If the generic clock is already enabled, return an error.
  676. if(AVR32_SCIF.gcctrl[gclk] & AVR32_SCIF_GCCTRL_CEN_MASK)
  677. return -1;
  678. // Configure & start the generic clock.
  679. AVR32_SCIF.gcctrl[gclk] = ((opt->divider << AVR32_SCIF_GCCTRL_DIV_OFFSET)&AVR32_SCIF_GCCTRL_DIV_MASK)
  680. |((opt->diven << AVR32_SCIF_GCCTRL_DIVEN_OFFSET)&AVR32_SCIF_GCCTRL_DIVEN_MASK)
  681. |((opt->clock_source << AVR32_SCIF_GCCTRL_OSCSEL_OFFSET)&AVR32_SCIF_GCCTRL_OSCSEL_MASK)
  682. |(AVR32_SCIF_GCCTRL_CEN_MASK);
  683. return PASS;
  684. }
  685. long int scif_stop_gclk(unsigned int gclk)
  686. {
  687. unsigned int timeout = SCIF_POLL_TIMEOUT;
  688. #ifdef AVR32SFW_INPUT_CHECK
  689. // Check that the generic clock number is correct
  690. if( gclk > AVR32_SCIF_GCLK_NUM )
  691. {
  692. return -1;
  693. }
  694. #endif // AVR32SFW_INPUT_CHECK
  695. // Stop the generic clock.
  696. AVR32_SCIF.gcctrl[gclk] &= ~AVR32_SCIF_GCCTRL_CEN_MASK;
  697. // Wait until the generic clock is actually stopped.
  698. while(AVR32_SCIF.gcctrl[gclk] & AVR32_SCIF_GCCTRL_CEN_MASK)
  699. {
  700. if(--timeout == 0)
  701. return -1;
  702. }
  703. return PASS;
  704. }
  705. long int scif_gc_setup(unsigned int gclk, scif_gcctrl_oscsel_t clk_src, unsigned int diven, unsigned int divfactor)
  706. {
  707. int restart_gc = false;
  708. // Change the division factor to conform to the equation: fgclk = fsrc/divfactor = fsrc/(2*(div+1))
  709. divfactor = (divfactor>>1) -1;
  710. #ifdef AVR32SFW_INPUT_CHECK
  711. // Check that the generic clock number is correct
  712. if( gclk > AVR32_SCIF_GCLK_NUM )
  713. {
  714. return -1;
  715. }
  716. // Check that the clock source for the generic clock is correct.
  717. if(( clk_src >= SCIF_GCCTRL_OSCSEL_INVALID ) || ( clk_src < 0 ))
  718. {
  719. return -1;
  720. }
  721. // Check that the required division factor is correct.
  722. if(diven)
  723. {
  724. if(divfactor >= (1<<AVR32_SCIF_GCCTRL_DIV_SIZE))
  725. return -1;
  726. }
  727. #endif // AVR32SFW_INPUT_CHECK
  728. // If the generic clock is already enabled, disable it before changing its setup.
  729. if(AVR32_SCIF.gcctrl[gclk] & AVR32_SCIF_GCCTRL_CEN_MASK)
  730. {
  731. restart_gc = true;
  732. if(scif_stop_gclk(gclk) < 0)
  733. return -1; // Could not stop the generic clock.
  734. }
  735. // Setup the generic clock.
  736. AVR32_SCIF.gcctrl[gclk] = ((divfactor << AVR32_SCIF_GCCTRL_DIV_OFFSET)&AVR32_SCIF_GCCTRL_DIV_MASK)
  737. |((diven << AVR32_SCIF_GCCTRL_DIVEN_OFFSET)&AVR32_SCIF_GCCTRL_DIVEN_MASK)
  738. |((clk_src << AVR32_SCIF_GCCTRL_OSCSEL_OFFSET)&AVR32_SCIF_GCCTRL_OSCSEL_MASK);
  739. // Restart the gc if it previously was enabled.
  740. if(true == restart_gc)
  741. AVR32_SCIF.gcctrl[gclk] |= (AVR32_SCIF_GCCTRL_CEN_MASK);
  742. return PASS;
  743. }
  744. long int scif_gc_enable(unsigned int gclk)
  745. {
  746. #ifdef AVR32SFW_INPUT_CHECK
  747. // Check that the generic clock number is correct
  748. if( gclk > AVR32_SCIF_GCLK_NUM )
  749. {
  750. return -1;
  751. }
  752. #endif // AVR32SFW_INPUT_CHECK
  753. // If the generic clock is already enabled, do nothing.
  754. if(!(AVR32_SCIF.gcctrl[gclk] & AVR32_SCIF_GCCTRL_CEN_MASK))
  755. AVR32_SCIF.gcctrl[gclk] |= (AVR32_SCIF_GCCTRL_CEN_MASK);
  756. return PASS;
  757. }
  758. /**
  759. ** Backup Registers Functions
  760. **/
  761. /**
  762. ** Misc
  763. **/
  764. /*! \brief Wait for a status high in the Power and Clocks status register.
  765. *
  766. * \param statusMask Mask field of the status to poll [INPUT]
  767. *
  768. * \return Status.
  769. * \retval 0 Status is high.
  770. * \retval <0 SCIF_POLL_TIMEOUT Timeout expired before the status was high.
  771. */
  772. long int scif_pclksr_statushigh_wait(unsigned long statusMask)
  773. {
  774. unsigned int timeout = SCIF_POLL_TIMEOUT;
  775. while(!(AVR32_SCIF.pclksr & statusMask))
  776. {
  777. if(--timeout == 0)
  778. return -1;
  779. }
  780. return PASS;
  781. }