Definition in file pm_conf_clocks.c.
#include <string.h>
#include "compiler.h"
#include "pm.h"
Go to the source code of this file.
Defines | |
#define | PM_MAX_MUL ((1 << AVR32_PM_PLL0_PLLMUL_SIZE) - 1) |
Functions | |
void | flashc_set_wait_state (unsigned int wait_state) |
int | pm_configure_clocks (pm_freq_param_t *param) |
Automatically configure the CPU, PBA, PBB, and HSB clocks according to the user wishes. | |
void | pm_configure_usb_clock (void) |
Automatically configure the USB clock. |
#define PM_MAX_MUL ((1 << AVR32_PM_PLL0_PLLMUL_SIZE) - 1) |
void flashc_set_wait_state | ( | unsigned int | wait_state | ) |
Referenced by local_start_highfreq_clock(), and pm_configure_clocks().
int pm_configure_clocks | ( | pm_freq_param_t * | param | ) |
Automatically configure the CPU, PBA, PBB, and HSB clocks according to the user wishes.
This function needs some parameters stored in a pm_freq_param_t structure:
The function will then configure the clocks using the following rules:
The CPU, HSB and PBA frequencies programmed after configuration are stored back into cpu_f and pba_f.
param | pointer on the configuration structure. |
PM_FREQ_STATUS_OK | Mode successfully initialized. | |
PM_FREQ_STATUS_FAIL | The configuration can not be done. |
Definition at line 61 of file pm_conf_clocks.c.
References pm_freq_param_t::cpu_f, flashc_set_wait_state(), pm_freq_param_t::osc0_f, pm_freq_param_t::osc0_startup, pm_freq_param_t::pba_f, pm_cksel(), PM_FREQ_STATUS_FAIL, PM_FREQ_STATUS_OK, PM_MAX_MUL, pm_pll_enable(), pm_pll_set_option(), pm_pll_setup(), pm_switch_to_clock(), pm_switch_to_osc0(), and pm_wait_for_pll0_locked().
Referenced by pcl_configure_clocks().
00062 { 00063 // Supported frequencies: 00064 // Fosc0 mul div PLL div2_en cpu_f pba_f Comment 00065 // 12 15 1 192 1 12 12 00066 // 12 9 3 40 1 20 20 PLL out of spec 00067 // 12 15 1 192 1 24 12 00068 // 12 9 1 120 1 30 15 00069 // 12 9 3 40 0 40 20 PLL out of spec 00070 // 12 15 1 192 1 48 12 00071 // 12 15 1 192 1 48 24 00072 // 12 8 1 108 1 54 27 00073 // 12 9 1 120 1 60 15 00074 // 12 9 1 120 1 60 30 00075 // 12 10 1 132 1 66 16.5 00076 // 00077 unsigned long in_cpu_f = param->cpu_f; 00078 unsigned long in_osc0_f = param->osc0_f; 00079 unsigned long mul, div, div2_en = 0, div2_cpu = 0, div2_pba = 0; 00080 unsigned long pll_freq, rest; 00081 Bool b_div2_pba, b_div2_cpu; 00082 00083 // Switch to external Oscillator 0 00084 pm_switch_to_osc0(&AVR32_PM, in_osc0_f, param->osc0_startup); 00085 00086 // Start with CPU freq config 00087 if (in_cpu_f == in_osc0_f) 00088 { 00089 param->cpu_f = in_osc0_f; 00090 param->pba_f = in_osc0_f; 00091 return PM_FREQ_STATUS_OK; 00092 } 00093 else if (in_cpu_f < in_osc0_f) 00094 { 00095 // TBD 00096 } 00097 00098 rest = in_cpu_f % in_osc0_f; 00099 00100 for (div = 1; div < 32; div++) 00101 { 00102 if ((div * rest) % in_osc0_f == 0) 00103 break; 00104 } 00105 if (div == 32) 00106 return PM_FREQ_STATUS_FAIL; 00107 00108 mul = (in_cpu_f * div) / in_osc0_f; 00109 00110 if (mul > PM_MAX_MUL) 00111 return PM_FREQ_STATUS_FAIL; 00112 00113 // export 2power from PLL div to div2_cpu 00114 while (!(div % 2)) 00115 { 00116 div /= 2; 00117 div2_cpu++; 00118 } 00119 00120 // Here we know the mul and div parameter of the PLL config. 00121 // . Check out if the PLL has a valid in_cpu_f. 00122 // . Try to have for the PLL frequency (VCO output) the highest possible value 00123 // to reduce jitter. 00124 while (in_osc0_f * 2 * mul / div < AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ) 00125 { 00126 if (2 * mul > PM_MAX_MUL) 00127 break; 00128 mul *= 2; 00129 div2_cpu++; 00130 } 00131 00132 if (div2_cpu != 0) 00133 { 00134 div2_cpu--; 00135 div2_en = 1; 00136 } 00137 00138 pll_freq = in_osc0_f * mul / (div * (1 << div2_en)); 00139 00140 // Update real CPU Frequency 00141 param->cpu_f = pll_freq / (1 << div2_cpu); 00142 mul--; 00143 00144 pm_pll_setup(&AVR32_PM 00145 , 0 // pll 00146 , mul // mul 00147 , div // div 00148 , 0 // osc 00149 , 16 // lockcount 00150 ); 00151 00152 pm_pll_set_option(&AVR32_PM 00153 , 0 // pll 00154 // PLL clock is lower than 160MHz: need to set pllopt. 00155 , (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0 // pll_freq 00156 , div2_en // pll_div2 00157 , 0 // pll_wbwdisable 00158 ); 00159 00160 rest = pll_freq; 00161 while (rest > AVR32_PM_PBA_MAX_FREQ || 00162 rest != param->pba_f) 00163 { 00164 div2_pba++; 00165 rest = pll_freq / (1 << div2_pba); 00166 if (rest < param->pba_f) 00167 break; 00168 } 00169 00170 // Update real PBA Frequency 00171 param->pba_f = pll_freq / (1 << div2_pba); 00172 00173 // Enable PLL0 00174 pm_pll_enable(&AVR32_PM, 0); 00175 00176 // Wait for PLL0 locked 00177 pm_wait_for_pll0_locked(&AVR32_PM); 00178 00179 if (div2_cpu) 00180 { 00181 b_div2_cpu = TRUE; 00182 div2_cpu--; 00183 } 00184 else 00185 b_div2_cpu = FALSE; 00186 00187 if (div2_pba) 00188 { 00189 b_div2_pba = TRUE; 00190 div2_pba--; 00191 } 00192 else 00193 b_div2_pba = FALSE; 00194 00195 pm_cksel(&AVR32_PM 00196 , b_div2_pba, div2_pba // PBA 00197 , b_div2_cpu, div2_cpu // PBB 00198 , b_div2_cpu, div2_cpu // HSB 00199 ); 00200 00201 if (param->cpu_f > AVR32_FLASHC_FWS_0_MAX_FREQ) 00202 { 00203 flashc_set_wait_state(1); 00204 #if (defined AVR32_FLASHC_210_H_INCLUDED) 00205 if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ) 00206 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1); 00207 else 00208 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); 00209 #endif 00210 } 00211 else 00212 { 00213 flashc_set_wait_state(0); 00214 #if (defined AVR32_FLASHC_210_H_INCLUDED) 00215 if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ) 00216 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1); 00217 else 00218 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); 00219 #endif 00220 } 00221 00222 pm_switch_to_clock(&AVR32_PM, AVR32_PM_MCCTRL_MCSEL_PLL0); 00223 00224 return PM_FREQ_STATUS_OK; 00225 }
void pm_configure_usb_clock | ( | void | ) |
Automatically configure the USB clock.
USB clock is configured to 48MHz, using the PLL1 from the Oscillator0, assuming a 12 MHz crystal is connected to it.
Definition at line 228 of file pm_conf_clocks.c.
References pm_gc_enable(), pm_gc_setup(), pm_pll_enable(), pm_pll_set_option(), pm_pll_setup(), and pm_wait_for_pll1_locked().
Referenced by pcl_configure_usb_clock().
00229 { 00230 #if (defined __AVR32_UC3A3256__) || (defined __AVR32_UC3A3128__) || (defined __AVR32_UC3A364__) || \ 00231 (defined __AVR32_UC3A3256S__) || (defined __AVR32_UC3A3128S__) || (defined __AVR32_UC3A364S__) || \ 00232 (defined __AT32UC3A3256__) || (defined __AT32UC3A3128__) || (defined __AT32UC3A364__) || \ 00233 (defined __AT32UC3A3256S__) || (defined __AT32UC3A3128S__) || (defined __AT32UC3A364S__) 00234 00235 // Setup USB GCLK. 00236 pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB, // gc 00237 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) 00238 0, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 00239 0, // diven 00240 0); // div 00241 00242 // Enable USB GCLK. 00243 pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB); 00244 #else 00245 // Use 12MHz from OSC0 and generate 96 MHz 00246 pm_pll_setup(&AVR32_PM, 1, // pll. 00247 7, // mul. 00248 1, // div. 00249 0, // osc. 00250 16); // lockcount. 00251 00252 pm_pll_set_option(&AVR32_PM, 1, // pll. 00253 1, // pll_freq: choose the range 80-180MHz. 00254 1, // pll_div2. 00255 0); // pll_wbwdisable. 00256 00257 // start PLL1 and wait forl lock 00258 pm_pll_enable(&AVR32_PM, 1); 00259 00260 // Wait for PLL1 locked. 00261 pm_wait_for_pll1_locked(&AVR32_PM); 00262 00263 pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB, // gc. 00264 1, // osc_or_pll: use Osc (if 0) or PLL (if 1). 00265 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1. 00266 0, // diven. 00267 0); // div. 00268 pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB); 00269 #endif 00270 }