00001
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include <string.h>
00048 #include "compiler.h"
00049 #include "pm.h"
00050
00051 extern void flashc_set_wait_state(unsigned int wait_state);
00052 #if (defined AVR32_FLASHC_210_H_INCLUDED)
00053 extern void flashc_issue_command(unsigned int command, int page_number);
00054 #endif
00055
00056
00057 #define PM_MAX_MUL ((1 << AVR32_PM_PLL0_PLLMUL_SIZE) - 1)
00058
00059
00060 int pm_configure_clocks(pm_freq_param_t *param)
00061 {
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
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
00083 pm_switch_to_osc0(&AVR32_PM, in_osc0_f, param->osc0_startup);
00084
00085
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
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
00113 while (!(div % 2))
00114 {
00115 div /= 2;
00116 div2_cpu++;
00117 }
00118
00119
00120
00121
00122
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
00140 param->cpu_f = pll_freq / (1 << div2_cpu);
00141 mul--;
00142
00143 pm_pll_setup(&AVR32_PM
00144 , 0
00145 , mul
00146 , div
00147 , 0
00148 , 16
00149 );
00150
00151 pm_pll_set_option(&AVR32_PM
00152 , 0
00153
00154 , (pll_freq < AVR32_PM_PLL_VCO_RANGE0_MIN_FREQ) ? 1 : 0
00155 , div2_en
00156 , 0
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
00170 param->pba_f = pll_freq / (1 << div2_pba);
00171
00172
00173 pm_pll_enable(&AVR32_PM, 0);
00174
00175
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
00196 , b_div2_cpu, div2_cpu
00197 , b_div2_cpu, div2_cpu
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 }
00225
00226
00227 void pm_configure_usb_clock(void)
00228 {
00229 #if UC3A3
00230
00231
00232 pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB,
00233 0,
00234 0,
00235 0,
00236 0);
00237
00238
00239 pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB);
00240 #else
00241
00242 pm_pll_setup(&AVR32_PM, 1,
00243 7,
00244 1,
00245 0,
00246 16);
00247
00248 pm_pll_set_option(&AVR32_PM, 1,
00249 1,
00250 1,
00251 0);
00252
00253
00254 pm_pll_enable(&AVR32_PM, 1);
00255
00256
00257 pm_wait_for_pll1_locked(&AVR32_PM);
00258
00259 pm_gc_setup(&AVR32_PM, AVR32_PM_GCLK_USBB,
00260 1,
00261 1,
00262 0,
00263 0);
00264 pm_gc_enable(&AVR32_PM, AVR32_PM_GCLK_USBB);
00265 #endif
00266 }