- Main Page
- Related Pages
- Data Structures
- Files

- File List
- Globals

# scif_uc3l.c

Go to the documentation of this file.

    00001 /*This file has been prepared for Doxygen automatic documentation generation.*/
    00016 /* Copyright (c) 2009 Atmel Corporation. All rights reserved.
    00017  *
    00018  * Redistribution and use in source and binary forms, with or without
    00019  * modification, are permitted provided that the following conditions are met:
    00020  *
    00021  * 1. Redistributions of source code must retain the above copyright notice, this
    00022  * list of conditions and the following disclaimer.
    00023  *
    00024  * 2. Redistributions in binary form must reproduce the above copyright notice,
    00025  * this list of conditions and the following disclaimer in the documentation
    00026  * and/or other materials provided with the distribution.
    00027  *
    00028  * 3. The name of Atmel may not be used to endorse or promote products derived
    00029  * from this software without specific prior written permission.
    00030  *
    00031  * 4. This software may only be redistributed and used in connection with an Atmel
    00032  * AVR product.
    00033  *
    00034  * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
    00035  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
    00036  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
    00037  * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
    00038  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    00039  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    00040  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    00041  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    00042  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    00043  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
    00044  *
    00045  */
    00046
    00047 #include "compiler.h"
    00048 #include "scif_uc3l.h"
    00049
    00050
    00053
    00054
    00055 typedef union
    00056 {
    00057   unsigned long                 oscctrl0;
    00058   avr32_scif_oscctrl0_t         OSCCTRL0;
    00059 } u_avr32_scif_oscctrl0_t;
    00060
    00061 typedef union
    00062 {
    00063   unsigned long                 oscctrl32;
    00064   avr32_scif_oscctrl32_t         OSCCTRL32;
    00065 } u_avr32_scif_oscctrl32_t;
    00066
    00067 typedef union
    00068 {
    00069   unsigned long                 dfll0conf;
    00070   avr32_scif_dfll0conf_t        DFLL0CONF;
    00071 } u_avr32_scif_dfll0conf_t;
    00072
    00073 typedef union
    00074 {
    00075   unsigned long                 dfll0ssg;
    00076   avr32_scif_dfll0ssg_t         DFLL0SSG;
    00077 } u_avr32_scif_dfll0ssg_t;
    00078
    00080
    00081
    00085 // Implemented as inline in scif_uc3l.h
    00086
    00087
    00091 // Implemented as inline in scif_uc3l.h
    00092
    00093
    00098 long int scif_start_osc(scif_osc_t osc, const scif_osc_opt_t *opt, bool wait_for_ready)
    00099 {
    00100 //# Implementation note: this code doesn't consider the osc input parameter
    00101 //# because UC3L devices only implement OSC0.
    00102   u_avr32_scif_oscctrl0_t   u_avr32_scif_oscctrl0 = {AVR32_SCIF.oscctrl0};
    00103
    00104
    00105 #ifdef AVR32SFW_INPUT_CHECK
    00106   // Check that the input frequency is in the supported frequency range.
    00107   if( (opt->freq_hz < SCIF_EXT_CRYSTAL_MIN_FREQ_HZ)
    00108       || (opt->freq_hz > SCIF_EXT_CRYSTAL_MAX_FREQ_HZ))
    00109   {
    00110     return -1;
    00111   }
    00112   // Check : for OSC0/OSC1, only 2 modes are supported
    00113   if( (opt->mode != SCIF_OSC_MODE_EXT_CLK)
    00114       && (opt->mode != SCIF_OSC_MODE_2PIN_CRYSTAL))
    00115   {
    00116     return -1;
    00117   }
    00118   // Check that the startup value is in the supported range.
    00119   if(opt->startup > (unsigned char)AVR32_SCIF_OSCCTRL0_STARTUP_16384_RCOSC)
    00120   {
    00121     return -1;
    00122   }
    00123   // Check that the gain value is in the supported range.
    00124   if(opt->gain > AVR32_SCIF_OSCCTRL0_GAIN_G3)
    00125   {
    00126     return -1;
    00127   }
    00128 #endif  // AVR32SFW_INPUT_CHECK
    00129
    00130   // Configure & start OSC0.
    00131   u_avr32_scif_oscctrl0.OSCCTRL0.mode = opt->mode;
    00132   u_avr32_scif_oscctrl0.OSCCTRL0.gain = opt->gain;
    00133   u_avr32_scif_oscctrl0.OSCCTRL0.startup = opt->startup;
    00134   u_avr32_scif_oscctrl0.OSCCTRL0.oscen = ENABLE;
    00135   AVR32_ENTER_CRITICAL_REGION( );
    00136   // Unlock the write-protected OSCCTRL0 register
    00137   SCIF_UNLOCK(AVR32_SCIF_OSCCTRL0);
    00138   // Write
    00139   AVR32_SCIF.oscctrl0 = u_avr32_scif_oscctrl0.oscctrl0;
    00140   AVR32_LEAVE_CRITICAL_REGION( );
    00141
    00142   if(true == wait_for_ready)
    00143   {
    00144     // Wait until OSC0 is stable and ready to be used.
    00145     if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_OSC0RDY_MASK))
    00146       return -1;
    00147   }
    00148
    00149   return PASS;
    00150 }
    00151
    00152
    00153 bool scif_is_osc_ready(scif_osc_t osc)
    00154 {
    00155 //# Implementation note: this code doesn't consider the osc input parameter
    00156 //# because UC3L devices only implement OSC0.
    00157   return((AVR32_SCIF.pclksr & AVR32_SCIF_PCLKSR_OSC0RDY_MASK)>>AVR32_SCIF_PCLKSR_OSC0RDY_OFFSET);
    00158 }
    00159
    00160
    00161 long int scif_stop_osc(scif_osc_t osc)
    00162 {
    00163 //# Implementation note: this code doesn't consider the osc input parameter
    00164 //# because UC3L devices only implement OSC0.
    00165   unsigned long temp = AVR32_SCIF.oscctrl0;
    00166   temp &= ~AVR32_SCIF_OSCCTRL0_OSCEN_MASK;
    00167
    00168   AVR32_ENTER_CRITICAL_REGION( );
    00169   // Unlock the write-protected OSCCTRL0 register
    00170   SCIF_UNLOCK(AVR32_SCIF_OSCCTRL0);
    00171   // Stop OSC0.
    00172   AVR32_SCIF.oscctrl0 = temp;
    00173   AVR32_LEAVE_CRITICAL_REGION( );
    00174
    00175   return PASS;
    00176 }
    00177
    00178
    00179 long int scif_configure_osc_crystalmode(scif_osc_t osc, unsigned int fcrystal)
    00180 {
    00181 //# Implementation note: this code doesn't consider the osc input parameter
    00182 //# because UC3L devices only implement OSC0.
    00183   u_avr32_scif_oscctrl0_t   u_avr32_scif_oscctrl0 = {AVR32_SCIF.oscctrl0};
    00184
    00185   // Configure the oscillator mode to crystal and set the gain according to the
    00186   // cyrstal frequency.
    00187   u_avr32_scif_oscctrl0.OSCCTRL0.mode = SCIF_OSC_MODE_2PIN_CRYSTAL;
    00188   u_avr32_scif_oscctrl0.OSCCTRL0.gain = (fcrystal <  900000) ? AVR32_SCIF_OSCCTRL0_GAIN_G0 :
    00189                                         (fcrystal < 3000000) ? AVR32_SCIF_OSCCTRL0_GAIN_G1 :
    00190                                         (fcrystal < 8000000) ? AVR32_SCIF_OSCCTRL0_GAIN_G2 :
    00191                                                                AVR32_SCIF_OSCCTRL0_GAIN_G3;
    00192   AVR32_ENTER_CRITICAL_REGION( );
    00193   // Unlock the write-protected OSCCTRL0 register
    00194   SCIF_UNLOCK(AVR32_SCIF_OSCCTRL0);
    00195   // Write
    00196   AVR32_SCIF.oscctrl0 = u_avr32_scif_oscctrl0.oscctrl0;
    00197   AVR32_LEAVE_CRITICAL_REGION( );
    00198   // Add here after support for OSC1 for devices that implement OSC1.
    00199
    00200   return PASS;
    00201 }
    00202
    00203
    00204 long int scif_enable_osc(scif_osc_t osc, unsigned int startup, bool wait_for_ready)
    00205 {
    00206 //# Implementation note: this code doesn't consider the osc input parameter
    00207 //# because UC3L devices only implement OSC0.
    00208   u_avr32_scif_oscctrl0_t   u_avr32_scif_oscctrl0 = {AVR32_SCIF.oscctrl0};
    00209
    00210
    00211   // Configure the oscillator startup and enable the osc.
    00212   u_avr32_scif_oscctrl0.OSCCTRL0.startup = startup;
    00213   u_avr32_scif_oscctrl0.OSCCTRL0.oscen = ENABLE;
    00214   AVR32_ENTER_CRITICAL_REGION( );
    00215   // Unlock the write-protected OSCCTRL0 register
    00216   SCIF_UNLOCK(AVR32_SCIF_OSCCTRL0);
    00217   // Write
    00218   AVR32_SCIF.oscctrl0 = u_avr32_scif_oscctrl0.oscctrl0;
    00219   AVR32_LEAVE_CRITICAL_REGION( );
    00220
    00221   if(true == wait_for_ready)
    00222   {
    00223     // Wait until OSC0 is stable and ready to be used.
    00224     if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_OSC0RDY_MASK))
    00225       return -1;
    00226   }
    00227
    00228   return PASS;
    00229 }
    00230
    00231
    00236 long int scif_start_osc32(const scif_osc32_opt_t *opt, bool wait_for_ready)
    00237 {
    00238   u_avr32_scif_oscctrl32_t  u_avr32_scif_oscctrl32 = {AVR32_SCIF.oscctrl32};
    00239
    00240
    00241 #ifdef AVR32SFW_INPUT_CHECK
    00242   // Check that the input frequency is in the supported frequency range.
    00243   if( (opt->freq_hz < SCIF_EXT_CRYSTAL_MIN_FREQ_HZ)
    00244       || (opt->freq_hz > SCIF_EXT_CRYSTAL_MAX_FREQ_HZ))
    00245   {
    00246     return -1;
    00247   }
    00248   // Check : for OSC0/OSC1, only 2 modes are supported
    00249   if( (opt->mode < SCIF_OSC_MODE_EXT_CLK)
    00250       || (opt->mode > SCIF_OSC_MODE_2PIN_CRYSTAL)
    00251       || (opt->mode == SCIF_OSC_MODE_NOT_SUPPORTED_1)
    00252       || (opt->mode == SCIF_OSC_MODE_NOT_SUPPORTED_2) )
    00253   {
    00254     return -1;
    00255   }
    00256   // Check that the startup value is in the supported range.
    00257   if(opt->startup > (unsigned char)AVR32_SCIF_OSCCTRL32_STARTUP_524288_RCOSC)
    00258   {
    00259     return -1;
    00260   }
    00261 #endif  // AVR32SFW_INPUT_CHECK
    00262
    00263   // Configure & start OSC32.
    00264   u_avr32_scif_oscctrl32.OSCCTRL32.mode = opt->mode;
    00265   u_avr32_scif_oscctrl32.OSCCTRL32.pinsel = opt->pinsel;
    00266   u_avr32_scif_oscctrl32.OSCCTRL32.en32k = opt->en32k;
    00267   u_avr32_scif_oscctrl32.OSCCTRL32.en1k = opt->en1k;
    00268   u_avr32_scif_oscctrl32.OSCCTRL32.startup = opt->startup;
    00269   u_avr32_scif_oscctrl32.OSCCTRL32.osc32en = ENABLE;
    00270 #if 0
    00271   AVR32_ENTER_CRITICAL_REGION( );
    00272   // Unlock the write-protected OSCCTRL32 register
    00273   SCIF_UNLOCK(AVR32_SCIF_OSCCTRL32);
    00274 #endif
    00275   // write
    00276   AVR32_SCIF.oscctrl32 = u_avr32_scif_oscctrl32.oscctrl32;
    00277 #if 0
    00278   AVR32_LEAVE_CRITICAL_REGION( );
    00279 #endif
    00280
    00281   if(true == wait_for_ready)
    00282   {
    00283     // Wait until OSC32 is stable and ready to be used.
    00284     if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_OSC32RDY_MASK))
    00285       return -1;
    00286   }
    00287
    00288   return PASS;
    00289 }
    00290
    00291
    00292 long scif_stop_osc32()
    00293 {
    00294   unsigned long temp = AVR32_SCIF.oscctrl32;
    00295   temp &= ~AVR32_SCIF_OSCCTRL32_OSC32EN_MASK;
    00296
    00297 #if 0
    00298   AVR32_ENTER_CRITICAL_REGION( );
    00299   // Unlock the write-protected OSCCTRL32 register
    00300   SCIF_UNLOCK(AVR32_SCIF_OSCCTRL32);
    00301 #endif
    00302   // Stop OSC32.
    00303   AVR32_SCIF.oscctrl32 = temp;
    00304 #if 0
    00305   AVR32_LEAVE_CRITICAL_REGION( );
    00306 #endif
    00307
    00308   return PASS;
    00309 }
    00310
    00311
    00312
    00317
    00318 typedef enum
    00319 {
    00320   SCIF_DFLL0_MODE_OPENLOOP = 0,
    00321   SCIF_DFLL0_MODE_CLOSEDLOOP
    00322 } scif_dfll_mode_t;
    00323
    00324 long int scif_dfll0_openloop_start(const scif_dfll_openloop_conf_t *pdfllconfig)
    00325 {
    00326   u_avr32_scif_dfll0conf_t  u_avr32_scif_dfll0conf = {AVR32_SCIF.dfll0conf};
    00327
    00328
    00329 #ifdef AVR32SFW_INPUT_CHECK
    00330   if((pdfllconfig->fine >> AVR32_SCIF_DFLL0CONF_FINE_SIZE))
    00331     return -1;
    00332   if((pdfllconfig->coarse >> AVR32_SCIF_DFLL0CONF_COARSE_SIZE))
    00333     return -1;
    00334 #endif
    00335
    00336   // Enable the DFLL0: DFLL0CONF.EN=1
    00337   u_avr32_scif_dfll0conf.DFLL0CONF.en = ENABLE;
    00338   AVR32_ENTER_CRITICAL_REGION( );
    00339   SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
    00340   AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
    00341   AVR32_LEAVE_CRITICAL_REGION( );
    00342
    00343   // Wait for PCLKSR.DFLL0RDY is high
    00344   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00345     return -1;
    00346
    00347   // Set the DFLL0 to operate in open mode: DFLL0CONF.MODE=0
    00348   u_avr32_scif_dfll0conf.DFLL0CONF.mode = SCIF_DFLL0_MODE_OPENLOOP;
    00349   AVR32_ENTER_CRITICAL_REGION( );
    00350   SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
    00351   AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
    00352   AVR32_LEAVE_CRITICAL_REGION( );
    00353
    00354   // Wait for PCLKSR.DFLL0RDY is high
    00355   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00356     return -1;
    00357
    00358   // Write DFLL0CONF.COARSE & DFLL0CONF.FINE
    00359   u_avr32_scif_dfll0conf.DFLL0CONF.coarse = pdfllconfig->coarse;
    00360   u_avr32_scif_dfll0conf.DFLL0CONF.fine = pdfllconfig->fine;
    00361   AVR32_ENTER_CRITICAL_REGION( );
    00362   SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
    00363   AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
    00364   AVR32_LEAVE_CRITICAL_REGION( );
    00365
    00366   // Wait for PCLKSR.DFLL0RDY is high
    00367   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00368     return -1;
    00369
    00370   return PASS;
    00371 }
    00372
    00373
    00374 #define SCIF_DFLL_COARSE_MAX  (AVR32_SCIF_COARSE_MASK >> AVR32_SCIF_COARSE_OFFSET)
    00375 #define SCIF_DFLL_FINE_MAX    (AVR32_SCIF_FINE_MASK >> AVR32_SCIF_FINE_OFFSET)
    00376 #define SCIF_DFLL_FINE_HALF   (1 << (AVR32_SCIF_DFLL0CONF_FINE_SIZE-1))
    00377 long int scif_dfll0_openloop_start_auto(unsigned long TargetFreqkHz)
    00378 {
    00379   scif_dfll_openloop_conf_t Dfll0Conf;
    00380   unsigned long             Coarse;
    00381   unsigned long             Fine;
    00382   unsigned long             CoarseFreq;
    00383   unsigned long             DeltaFreq;
    00384
    00385
    00386 #ifdef AVR32SFW_INPUT_CHECK
    00387   if((TargetFreqkHz < SCIF_DFLL_MINFREQ_KHZ) || (TargetFreqkHz > SCIF_DFLL_MAXFREQ_KHZ))
    00388     return -1;
    00389 #endif
    00390
    00391   //**
    00392   //** Dynamically compute the COARSE and FINE values.
    00393   //**
    00394   // Fdfll = (Fmin+(Fmax-Fmin)*(COARSE/0xFF))*(1+X*(FINE-0x100)/0x1FF)=CoarseFreq*(1+X*(FINE-0x100)/0x1FF)
    00395
    00396   // Compute the COARSE value.
    00397   Coarse = ((TargetFreqkHz - SCIF_DFLL_MINFREQ_KHZ)*SCIF_DFLL_COARSE_MAX)/(SCIF_DFLL_MAXFREQ_KHZ - SCIF_DFLL_MINFREQ_KHZ);
    00398   // Compute the COARSE DFLL frequency.
    00399   CoarseFreq = SCIF_DFLL_MINFREQ_KHZ + (((SCIF_DFLL_MAXFREQ_KHZ - SCIF_DFLL_MINFREQ_KHZ)/SCIF_DFLL_COARSE_MAX)*Coarse);
    00400   // Compute the coarse error.
    00401   DeltaFreq = TargetFreqkHz - CoarseFreq;
    00402   // Compute the FINE value.
    00403   // Fine = ((DeltaFreq*SCIF_DFLL_FINE_MAX)*10/CoarseFreq) + SCIF_DFLL_FINE_HALF;
    00404   // Theorical equation don't work on silicon: the best was to use X=5/2 to
    00405   // find FINE, then do FINE/4.
    00406   Fine = ((DeltaFreq*SCIF_DFLL_FINE_MAX)*2/CoarseFreq*5) + SCIF_DFLL_FINE_HALF;
    00407   Fine >>=2;
    00408
    00409   Dfll0Conf.coarse = Coarse;
    00410   Dfll0Conf.fine = Fine;
    00411   return(scif_dfll0_openloop_start(&Dfll0Conf));
    00412 }
    00413
    00414 long int scif_dfll0_openloop_updatefreq(const scif_dfll_openloop_conf_t *pdfllconfig)
    00415 {
    00416   u_avr32_scif_dfll0conf_t  u_avr32_scif_dfll0conf = {AVR32_SCIF.dfll0conf};
    00417
    00418
    00419 #ifdef AVR32SFW_INPUT_CHECK
    00420   if((pdfllconfig->fine >> AVR32_SCIF_DFLL0CONF_FINE_SIZE))
    00421     return -1;
    00422 #endif
    00423
    00424   // It is assumed that the DFLL is enabled and operates in open-loop mode.
    00425
    00426   // Wait for PCLKSR.DFLL0RDY is high
    00427   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00428     return -1;
    00429
    00430   // Write DFLL0CONF.COARSE & DFLL0CONF.FINE
    00431   u_avr32_scif_dfll0conf.DFLL0CONF.coarse = pdfllconfig->coarse;
    00432   u_avr32_scif_dfll0conf.DFLL0CONF.fine = pdfllconfig->fine;
    00433   AVR32_ENTER_CRITICAL_REGION( );
    00434   SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
    00435   AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
    00436   AVR32_LEAVE_CRITICAL_REGION( );
    00437
    00438   // Wait for PCLKSR.DFLL0RDY is high
    00439   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00440     return -1;
    00441
    00442   return PASS;
    00443 }
    00444
    00445
    00446 long int scif_dfll0_openloop_stop(void)
    00447 {
    00448   u_avr32_scif_dfll0conf_t  u_avr32_scif_dfll0conf = {AVR32_SCIF.dfll0conf};
    00449
    00450
    00451   // Before disabling the DFLL, the output freq of the DFLL should be set to a
    00452   // minimum: set COARSE to 0x00.
    00453
    00454   // Wait for PCLKSR.DFLL0RDY is high
    00455   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00456     return -1;
    00457
    00458   // Write DFLL0CONF.COARSE
    00459   u_avr32_scif_dfll0conf.DFLL0CONF.coarse = 0;
    00460   AVR32_ENTER_CRITICAL_REGION( );
    00461   SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
    00462   AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
    00463   AVR32_LEAVE_CRITICAL_REGION( );
    00464
    00465   // Wait for PCLKSR.DFLL0RDY is high
    00466   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00467     return -1;
    00468
    00469   // Disable the DFLL
    00470   u_avr32_scif_dfll0conf.DFLL0CONF.en = 0;
    00471   AVR32_ENTER_CRITICAL_REGION( );
    00472   SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
    00473   AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
    00474   AVR32_LEAVE_CRITICAL_REGION( );
    00475
    00476   // Wait for PCLKSR.DFLL0RDY is high
    00477   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00478     return -1;
    00479
    00480   return PASS;
    00481 }
    00482
    00483
    00484 long int scif_dfll0_ssg_gc_enable(void)
    00485 {
    00486   scif_gclk_opt_t GcConf = {
    00487     SCIF_GCCTRL_SLOWCLOCK,  // use the RCOSC slow clock as source for the gclk
    00488     0,                      // divider = 0
    00489     DISABLE                 // diven disabled
    00490     };
    00491
    00492
    00493   // Configure and start the generic clock used by the dithering and the SSG:
    00494   // use the undivided RCOSC slow clock as source for the generic clock. The
    00495   // generic clock frequency will thus be ~115kHz.
    00496   return(scif_start_gclk(AVR32_SCIF_GCLK_DFLL0_SSG, &GcConf));
    00497 }
    00498
    00499
    00500 long int scif_dfll0_ssg_enable(scif_dfll_ssg_conf_t *pssg_conf)
    00501 {
    00502   u_avr32_scif_dfll0ssg_t  u_avr32_scif_dfll0ssg = {AVR32_SCIF.dfll0ssg};
    00503
    00504
    00505   u_avr32_scif_dfll0ssg.DFLL0SSG.en = ENABLE;
    00506   u_avr32_scif_dfll0ssg.DFLL0SSG.prbs = pssg_conf->use_random;
    00507   u_avr32_scif_dfll0ssg.DFLL0SSG.amplitude = pssg_conf->amplitude;
    00508   u_avr32_scif_dfll0ssg.DFLL0SSG.stepsize = pssg_conf->step_size;
    00509   AVR32_ENTER_CRITICAL_REGION( );
    00510   SCIF_UNLOCK(AVR32_SCIF_DFLL0SSG);
    00511   AVR32_SCIF.dfll0ssg = u_avr32_scif_dfll0ssg.dfll0ssg;
    00512   AVR32_LEAVE_CRITICAL_REGION( );
    00513
    00514   return PASS;
    00515 }
    00516
    00517
    00518 long int scif_dfll0_closedloop_start(const scif_dfll_closedloop_conf_t *pdfllconfig)
    00519 {
    00520   u_avr32_scif_dfll0conf_t  u_avr32_scif_dfll0conf = {AVR32_SCIF.dfll0conf};
    00521
    00522
    00523 #ifdef AVR32SFW_INPUT_CHECK
    00524   if((pdfllconfig->coarse >> AVR32_SCIF_DFLL0CONF_COARSE_SIZE))
    00525     return -1;
    00526   if((pdfllconfig->maxstep >> AVR32_SCIF_DFLL0STEP_MAXSTEP_SIZE))
    00527     return -1;
    00528 #endif
    00529
    00530   // Enable the DFLL0: DFLL0CONF.EN=1
    00531   u_avr32_scif_dfll0conf.DFLL0CONF.en = ENABLE;
    00532   AVR32_ENTER_CRITICAL_REGION( );
    00533   SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
    00534   AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
    00535   AVR32_LEAVE_CRITICAL_REGION( );
    00536
    00537   // Wait for PCLKSR.DFLL0RDY is high
    00538   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00539     return -1;
    00540
    00541   // Set the maxstep
    00542   AVR32_ENTER_CRITICAL_REGION( );
    00543   SCIF_UNLOCK(AVR32_SCIF_MAXSTEP);
    00544   AVR32_SCIF.dfll0step = (pdfllconfig->maxstep << AVR32_SCIF_DFLL0STEP_MAXSTEP_OFFSET)&AVR32_SCIF_DFLL0STEP_MAXSTEP_MASK;
    00545   AVR32_LEAVE_CRITICAL_REGION( );
    00546
    00547   // Wait for PCLKSR.DFLL0RDY is high
    00548   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00549     return -1;
    00550
    00551   // Set the fmul
    00552   AVR32_ENTER_CRITICAL_REGION( );
    00553   SCIF_UNLOCK(AVR32_SCIF_DFLL0FMUL);
    00554   AVR32_SCIF.dfll0fmul = (pdfllconfig->fmul << AVR32_SCIF_DFLL0FMUL_FMUL_OFFSET)&AVR32_SCIF_DFLL0FMUL_FMUL_MASK;
    00555   AVR32_LEAVE_CRITICAL_REGION( );
    00556
    00557   // Wait for PCLKSR.DFLL0RDY is high
    00558   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00559     return -1;
    00560
    00561   // Set the DFLL0 to operate in closed-loop mode: DFLL0CONF.MODE=1
    00562   u_avr32_scif_dfll0conf.DFLL0CONF.mode = SCIF_DFLL0_MODE_CLOSEDLOOP;
    00563   u_avr32_scif_dfll0conf.DFLL0CONF.coarse = pdfllconfig->coarse;
    00564   AVR32_ENTER_CRITICAL_REGION( );
    00565   SCIF_UNLOCK(AVR32_SCIF_DFLL0CONF);
    00566   AVR32_SCIF.dfll0conf = u_avr32_scif_dfll0conf.dfll0conf;
    00567   AVR32_LEAVE_CRITICAL_REGION( );
    00568
    00569   // Wait for PCLKSR.DFLL0RDY is high
    00570   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0RDY_MASK))
    00571     return -1;
    00572
    00573   // Wait until the DFLL is locked on Fine value, and is ready to be selected as
    00574   // clock source with a highly accurate output clock.
    00575   if(scif_pclksr_statushigh_wait(AVR32_SCIF_PCLKSR_DFLL0LOCKF_MASK))
    00576      return -1;
    00577
    00578   return PASS;
    00579 }
    00580
    00581
    00582 long int scif_dfll0_closedloop_configure_and_start( scif_dfll_clkref_t dfll_main_ref_gc,
    00583                                                     unsigned long long target_freq_hz,
    00584                                                     bool enable_ssg)
    00585 {
    00586   scif_dfll_closedloop_conf_t DfllConfig;
    00587   scif_gclk_opt_t             GcConf = { (scif_gcctrl_oscsel_t)dfll_main_ref_gc, 0, OFF };
    00588
    00589
    00590   // Configure and start the DFLL main reference generic clock.
    00591   // Note: this function will start the AVR32_SCIF_GCLK_DFLL0_REF generic clock
    00592   // (i.e. the generic clock dedicated to be the DFLL main reference clock).
    00593   if(scif_dfll0_closedloop_mainref_gc_enable(&GcConf))
    00594     return(-1);
    00595
    00596   // Configure the DFLL.
    00597   // The coarse value (= (dfll_f - SCIF_DFLL_MINFREQ_KHZ)*255/(SCIF_DFLL_MAXFREQ_KHZ - SCIF_DFLL_MINFREQ_KHZ))
    00598   DfllConfig.coarse = ((unsigned long long)(target_freq_hz - SCIF_DFLL_MINFREQ_HZ)*255)/(SCIF_DFLL_MAXFREQ_HZ - SCIF_DFLL_MINFREQ_HZ);
    00599
    00600   // The fmul value (= (fDFLL*2^16)/fref, with fref being the frequency of the
    00601   // DFLL main reference generic clock)
    00602   if(SCIF_DFLL_CLKREF_GC_SRC_115KHZ==dfll_main_ref_gc)
    00603     DfllConfig.fmul = ((unsigned long long)target_freq_hz<<16)/SCIF_SLOWCLOCK_FREQ_HZ;
    00604   else
    00605     DfllConfig.fmul = ((unsigned long long)target_freq_hz<<16)/SCIF_RC32K_FREQ_HZ;
    00606
    00607   // The maxstep value
    00608       //+ Errata UC3L revB: 35.2.7 SCIF.12 DFLLIF indicates coarse lock too early
    00609       //+ The DFLLIF might indicate coarse lock too early, the DFLL will lose
    00610       //+ coarse lock and regain it later.
    00611       //+ Fix/Workaround
    00612       //+ Use max step size (DFLL0MAXSTEP.MAXSTEP) of 4 or higher.
    00613   DfllConfig.maxstep = 0x0040004;
    00614
    00615   // Dithering disabled.
    00616       //+ Errata UC3L revB: 35.2.7 SCIF.13 DFLLIF dithering does not work
    00617       //+ The DFLLIF dithering does not work.
    00618       //+ Fix/Workaround
    00619       //+ None.
    00620
    00621   // Configure and start the DFLL0 in closed loop mode.
    00622   if(scif_dfll0_closedloop_start(&DfllConfig))
    00623     return -1;
    00624
    00625   // TODO: Future implementation note: add use of the generic clock CLK_DFLLIF_DITHER
    00626   // as a reference for the SSG feature.
    00627   if(TRUE == enable_ssg)
    00628   {
    00629   ;
    00630   }
    00631   return PASS;
    00632 }
    00633
    00648 void scif_start_rc120M(void)
    00649 {
    00650   AVR32_ENTER_CRITICAL_REGION( );
    00651   // Unlock the write-protected RC120MCR register
    00652   SCIF_UNLOCK(AVR32_SCIF_RC120MCR);
    00653   AVR32_SCIF.rc120mcr = AVR32_SCIF_RC120MCR_EN_MASK;
    00654   AVR32_LEAVE_CRITICAL_REGION( );
    00655 }
    00656
    00657 void scif_stop_rc120M(void)
    00658 {
    00659   unsigned long temp = AVR32_SCIF.rc120mcr;
    00660
    00661   temp &= ~AVR32_SCIF_RC120MCR_EN_MASK;
    00662   AVR32_ENTER_CRITICAL_REGION( );
    00663   // Unlock the write-protected RC120MCR register
    00664   SCIF_UNLOCK(AVR32_SCIF_RC120MCR);
    00665   AVR32_SCIF.rc120mcr = temp;
    00666   AVR32_LEAVE_CRITICAL_REGION( );
    00667 }
    00668
    00669
    00670
    00674 void scif_start_rc32k(void)
    00675 {
    00676   AVR32_ENTER_CRITICAL_REGION( );
    00677   // Unlock the write-protected RC32KCR register
    00678   SCIF_UNLOCK(AVR32_SCIF_RC32KCR);
    00679   AVR32_SCIF.rc32kcr = AVR32_SCIF_RC32KCR_EN_MASK;
    00680   AVR32_LEAVE_CRITICAL_REGION( );
    00681 }
    00682
    00683 void scif_stop_rc32k(void)
    00684 {
    00685   unsigned long temp = AVR32_SCIF.rc32kcr;
    00686
    00687   temp &= ~AVR32_SCIF_RC32KCR_EN_MASK;
    00688   AVR32_ENTER_CRITICAL_REGION( );
    00689   // Unlock the write-protected RC32KCR register
    00690   SCIF_UNLOCK(AVR32_SCIF_RC32KCR);
    00691   AVR32_SCIF.rc32kcr = temp;
    00692   AVR32_LEAVE_CRITICAL_REGION( );
    00693 }
    00694
    00695
    00696
    00701 long int scif_start_gclk(unsigned int gclk, const scif_gclk_opt_t *opt)
    00702 {
    00703 #ifdef AVR32SFW_INPUT_CHECK
    00704   // Check that the generic clock number is correct
    00705   if( gclk > AVR32_SCIF_GCLK_NUM )
    00706   {
    00707     return -1;
    00708   }
    00709   // Check that the clock source for the generic clock is correct.
    00710   if(( opt->clock_source >= SCIF_GCCTRL_OSCSEL_INVALID ) || ( opt->clock_source < 0 ))
    00711   {
    00712     return -1;
    00713   }
    00714 #endif  // AVR32SFW_INPUT_CHECK
    00715
    00716   // If the generic clock is already enabled, return an error.
    00717   if(AVR32_SCIF.gcctrl[gclk] & AVR32_SCIF_GCCTRL_CEN_MASK)
    00718     return -1;
    00719
    00720   // Configure & start the generic clock.
    00721   AVR32_SCIF.gcctrl[gclk] = ((opt->divider << AVR32_SCIF_GCCTRL_DIV_OFFSET)&AVR32_SCIF_GCCTRL_DIV_MASK)
    00722                             |((opt->diven << AVR32_SCIF_GCCTRL_DIVEN_OFFSET)&AVR32_SCIF_GCCTRL_DIVEN_MASK)
    00723                             |((opt->clock_source << AVR32_SCIF_GCCTRL_OSCSEL_OFFSET)&AVR32_SCIF_GCCTRL_OSCSEL_MASK)
    00724                             |(AVR32_SCIF_GCCTRL_CEN_MASK);
    00725
    00726   return PASS;
    00727 }
    00728
    00729
    00730 long int scif_stop_gclk(unsigned int gclk)
    00731 {
    00732   unsigned int  timeout = SCIF_POLL_TIMEOUT;
    00733
    00734 #ifdef AVR32SFW_INPUT_CHECK
    00735   // Check that the generic clock number is correct
    00736   if( gclk > AVR32_SCIF_GCLK_NUM )
    00737   {
    00738     return -1;
    00739   }
    00740 #endif  // AVR32SFW_INPUT_CHECK
    00741
    00742   // Stop the generic clock.
    00743   AVR32_SCIF.gcctrl[gclk] &= ~AVR32_SCIF_GCCTRL_CEN_MASK;
    00744
    00745   // Wait until the generic clock is actually stopped.
    00746   while(AVR32_SCIF.gcctrl[gclk] & AVR32_SCIF_GCCTRL_CEN_MASK)
    00747   {
    00748     if(--timeout == 0)
    00749       return -1;
    00750   }
    00751
    00752   return PASS;
    00753 }
    00754
    00755
    00756 long int scif_gc_setup(unsigned int gclk, scif_gcctrl_oscsel_t clk_src, unsigned int diven, unsigned int divfactor)
    00757 {
    00758   int restart_gc = false;
    00759
    00760
    00761   // Change the division factor to conform to the equation: fgclk = fsrc/divfactor = fsrc/(2*(div+1))
    00762   divfactor = (divfactor>>1) -1;
    00763
    00764 #ifdef AVR32SFW_INPUT_CHECK
    00765   // Check that the generic clock number is correct
    00766   if( gclk > AVR32_SCIF_GCLK_NUM )
    00767   {
    00768     return -1;
    00769   }
    00770   // Check that the clock source for the generic clock is correct.
    00771   if(( clk_src >= SCIF_GCCTRL_OSCSEL_INVALID ) || ( clk_src < 0 ))
    00772   {
    00773     return -1;
    00774   }
    00775   // Check that the required division factor is correct.
    00776   if(diven)
    00777   {
    00778     if(divfactor >= (1<<AVR32_SCIF_GCCTRL_DIV_SIZE))
    00779       return -1;
    00780   }
    00781 #endif  // AVR32SFW_INPUT_CHECK
    00782
    00783   // If the generic clock is already enabled, disable it before changing its setup.
    00784   if(AVR32_SCIF.gcctrl[gclk] & AVR32_SCIF_GCCTRL_CEN_MASK)
    00785   {
    00786     restart_gc = true;
    00787     if(scif_stop_gclk(gclk) < 0)
    00788       return -1;  // Could not stop the generic clock.
    00789   }
    00790
    00791   // Setup the generic clock.
    00792   AVR32_SCIF.gcctrl[gclk] = ((divfactor << AVR32_SCIF_GCCTRL_DIV_OFFSET)&AVR32_SCIF_GCCTRL_DIV_MASK)
    00793                             |((diven << AVR32_SCIF_GCCTRL_DIVEN_OFFSET)&AVR32_SCIF_GCCTRL_DIVEN_MASK)
    00794                             |((clk_src << AVR32_SCIF_GCCTRL_OSCSEL_OFFSET)&AVR32_SCIF_GCCTRL_OSCSEL_MASK);
    00795
    00796   // Restart the gc if it previously was enabled.
    00797   if(true == restart_gc)
    00798     AVR32_SCIF.gcctrl[gclk] |= (AVR32_SCIF_GCCTRL_CEN_MASK);
    00799
    00800   return PASS;
    00801 }
    00802
    00803
    00804 long int scif_gc_enable(unsigned int gclk)
    00805 {
    00806 #ifdef AVR32SFW_INPUT_CHECK
    00807   // Check that the generic clock number is correct
    00808   if( gclk > AVR32_SCIF_GCLK_NUM )
    00809   {
    00810     return -1;
    00811   }
    00812 #endif  // AVR32SFW_INPUT_CHECK
    00813
    00814   // If the generic clock is already enabled, do nothing.
    00815   if(!(AVR32_SCIF.gcctrl[gclk] & AVR32_SCIF_GCCTRL_CEN_MASK))
    00816     AVR32_SCIF.gcctrl[gclk] |= (AVR32_SCIF_GCCTRL_CEN_MASK);
    00817
    00818   return PASS;
    00819 }
    00820
    00838 long int scif_pclksr_statushigh_wait(unsigned long statusMask)
    00839 {
    00840   unsigned int  timeout = SCIF_POLL_TIMEOUT;
    00841
    00842   while(!(AVR32_SCIF.pclksr & statusMask))
    00843   {
    00844     if(--timeout == 0)
    00845       return -1;
    00846   }
    00847   return PASS;
    00848 }