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 60 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().
00061 { 00062 // Supported frequencies: 00063 // Fosc0 mul div PLL div2_en cpu_f pba_f Comment 00064 // 12 15 1 192 1 12 12 00065 // 12 9 3 40 1 20 20 PLL out of spec 00066 // 12 15 1 192 1 24 12 00067 // 12 9 1 120 1 30 15 00068 // 12 9 3 40 0 40 20 PLL out of spec 00069 // 12 15 1 192 1 48 12 00070 // 12 15 1 192 1 48 24 00071 // 12 8 1 108 1 54 27 00072 // 12 9 1 120 1 60 15 00073 // 12 9 1 120 1 60 30 00074 // 12 10 1 132 1 66 16.5 00075 // 00076 unsigned long in_cpu_f = param->cpu_f; 00077 unsigned long in_osc0_f = param->osc0_f; 00078 unsigned long mul, div, div2_en = 0, div2_cpu = 0, div2_pba = 0; 00079 unsigned long pll_freq, rest; 00080 Bool b_div2_pba, b_div2_cpu; 00081 00082 // Switch to external Oscillator 0 00083 pm_switch_to_osc0(&AVR32_PM, in_osc0_f, param->osc0_startup); 00084 00085 // Start with CPU freq config 00086 if (in_cpu_f == in_osc0_f) 00087 { 00088 param->cpu_f = in_osc0_f; 00089 param->pba_f = in_osc0_f; 00090 return PM_FREQ_STATUS_OK; 00091 } 00092 else if (in_cpu_f < in_osc0_f) 00093 { 00094 // TBD 00095 } 00096 00097 rest = in_cpu_f % in_osc0_f; 00098 00099 for (div = 1; div < 32; div++) 00100 { 00101 if ((div * rest) % in_osc0_f == 0) 00102 break; 00103 } 00104 if (div == 32) 00105 return PM_FREQ_STATUS_FAIL; 00106 00107 mul = (in_cpu_f * div) / in_osc0_f; 00108 00109 if (mul > PM_MAX_MUL) 00110 return PM_FREQ_STATUS_FAIL; 00111 00112 // export 2power from PLL div to div2_cpu 00113 while (!(div % 2)) 00114 { 00115 div /= 2; 00116 div2_cpu++; 00117 } 00118 00119 // Here we know the mul and div parameter of the PLL config. 00120 // . Check out if the PLL has a valid in_cpu_f. 00121 // . Try to have for the PLL frequency (VCO output) the highest possible value 00122 // to reduce jitter. 00123 while (in_osc0_f * 2 * mul / div < AVR32_PM_PLL_VCO_RANGE0_MAX_FREQ) 00124 { 00125 if (2 * mul > PM_MAX_MUL) 00126 break; 00127 mul *= 2; 00128 div2_cpu++; 00129 } 00130 00131 if (div2_cpu != 0) 00132 { 00133 div2_cpu--; 00134 div2_en = 1; 00135 } 00136 00137 pll_freq = in_osc0_f * mul / (div * (1 << div2_en)); 00138 00139 // Update real CPU Frequency 00140 param->cpu_f = pll_freq / (1 << div2_cpu); 00141 mul--; 00142 00143 pm_pll_setup(&AVR32_PM 00144 , 0 // pll 00145 , mul // mul 00146 , div // div 00147 , 0 // osc 00148 , 16 // lockcount 00149 ); 00150 00151 pm_pll_set_option(&AVR32_PM 00152 , 0 // pll 00153 // PLL clock is lower than 160MHz: need to set pllopt. 00154 , (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0 // pll_freq 00155 , div2_en // pll_div2 00156 , 0 // pll_wbwdisable 00157 ); 00158 00159 rest = pll_freq; 00160 while (rest > AVR32_PM_PBA_MAX_FREQ || 00161 rest != param->pba_f) 00162 { 00163 div2_pba++; 00164 rest = pll_freq / (1 << div2_pba); 00165 if (rest < param->pba_f) 00166 break; 00167 } 00168 00169 // Update real PBA Frequency 00170 param->pba_f = pll_freq / (1 << div2_pba); 00171 00172 // Enable PLL0 00173 pm_pll_enable(&AVR32_PM, 0); 00174 00175 // Wait for PLL0 locked 00176 pm_wait_for_pll0_locked(&AVR32_PM); 00177 00178 if (div2_cpu) 00179 { 00180 b_div2_cpu = TRUE; 00181 div2_cpu--; 00182 } 00183 else 00184 b_div2_cpu = FALSE; 00185 00186 if (div2_pba) 00187 { 00188 b_div2_pba = TRUE; 00189 div2_pba--; 00190 } 00191 else 00192 b_div2_pba = FALSE; 00193 00194 pm_cksel(&AVR32_PM 00195 , b_div2_pba, div2_pba // PBA 00196 , b_div2_cpu, div2_cpu // PBB 00197 , b_div2_cpu, div2_cpu // HSB 00198 ); 00199 00200 if (param->cpu_f > AVR32_FLASHC_FWS_0_MAX_FREQ) 00201 { 00202 flashc_set_wait_state(1); 00203 #if (defined AVR32_FLASHC_210_H_INCLUDED) 00204 if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_1_MAX_FREQ) 00205 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1); 00206 else 00207 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); 00208 #endif 00209 } 00210 else 00211 { 00212 flashc_set_wait_state(0); 00213 #if (defined AVR32_FLASHC_210_H_INCLUDED) 00214 if (param->cpu_f > AVR32_FLASHC_HSEN_FWS_0_MAX_FREQ) 00215 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSEN, -1); 00216 else 00217 flashc_issue_command(AVR32_FLASHC_FCMD_CMD_HSDIS, -1); 00218 #endif 00219 } 00220 00221 pm_switch_to_clock(&AVR32_PM, AVR32_PM_MCCTRL_MCSEL_PLL0); 00222 00223 return PM_FREQ_STATUS_OK; 00224 }
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 227 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().
00228 { 00229 #if UC3A3 00230 00231 // Setup USB GCLK. 00232 pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB, // gc 00233 0, // osc_or_pll: use Osc (if 0) or PLL (if 1) 00234 0, // pll_osc: select Osc0/PLL0 or Osc1/PLL1 00235 0, // diven 00236 0); // div 00237 00238 // Enable USB GCLK. 00239 pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB); 00240 #else 00241 // Use 12MHz from OSC0 and generate 96 MHz 00242 pm_pll_setup(&AVR32_PM, 1, // pll. 00243 7, // mul. 00244 1, // div. 00245 0, // osc. 00246 16); // lockcount. 00247 00248 pm_pll_set_option(&AVR32_PM, 1, // pll. 00249 1, // pll_freq: choose the range 80-180MHz. 00250 1, // pll_div2. 00251 0); // pll_wbwdisable. 00252 00253 // start PLL1 and wait forl lock 00254 pm_pll_enable(&AVR32_PM, 1); 00255 00256 // Wait for PLL1 locked. 00257 pm_wait_for_pll1_locked(&AVR32_PM); 00258 00259 pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB, // gc. 00260 1, // osc_or_pll: use Osc (if 0) or PLL (if 1). 00261 1, // pll_osc: select Osc0/PLL0 or Osc1/PLL1. 00262 0, // diven. 00263 0); // div. 00264 pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB); 00265 #endif 00266 }