00001
00039 #include <io/arm.h>
00040 #include <cfg/macros.h>
00041
00042 #if 1
00043
00044
00045 #define CREATE_PLL_STEP(xtal, cpufreq)
00046
00047 #define PLL_STEP(xtal, cpufreq, d, k) \
00048 do { \
00049 uint32_t m = (((cpufreq * (1LL << k) * (d)) + (xtal / 2)) / xtal) - 1; \
00050 if (m < 2048) \
00051 { \
00052 uint32_t pll = (d != 0) ? (xtal * (m + 1)) / (d) : 0; \
00053 if (80000000 <= pll && pll <= 160000000) \
00054 { \
00055 uint32_t err = ABS((int32_t)((pll >> k) - cpufreq)); \
00056 if (err < best_err) \
00057 { \
00058 best_err=err; best_m=m; best_k=k; best_d=d; \
00059 } \
00060 } \
00061 } \
00062 } while (0)
00063
00064 #else
00065
00066
00067
00068
00069 #define CREATE_PLL_STEP(xtal, cpufreq) \
00070 void __attribute__((always_inline)) PLL_STEP(int u1, int u2, int32_t d, long long k) \
00071 { \
00072 (void)u1; (void)u2; \
00073 uint32_t m = ((((cpufreq * (1LL << k) * (d)) + (xtal / 2)) / xtal) - 1; \
00074 if (m < 2048) \
00075 { \
00076 uint32_t pll = (xtal * (m + 1)) / (d); \
00077 if (80000000UL <= pll && pll <= 160000000UL) \
00078 { \
00079 uint32_t err = ABS((int32_t)((pll >> k) - cpufreq)); \
00080 if (err < best_err) \
00081 { \
00082 best_err=err; best_m=m; best_k=k; best_d=d; \
00083 } \
00084 } \
00085 } \
00086 }
00087
00088 #endif
00089
00090 #define PLL_MACRO_STEP(xtal, cpufreq, d) \
00091 do { \
00092 if ((d) > 0 && (d) <= 255 && \
00093 (d) <= xtal / 1000000 && (d) >= xtal / 32000000) \
00094 { \
00095 PLL_STEP(xtal, cpufreq, d, 0); \
00096 PLL_STEP(xtal, cpufreq, d, 1); \
00097 PLL_STEP(xtal, cpufreq, d, 2); \
00098 PLL_STEP(xtal, cpufreq, d, 3); \
00099 PLL_STEP(xtal, cpufreq, d, 4); \
00100 PLL_STEP(xtal, cpufreq, d, 5); \
00101 PLL_STEP(xtal, cpufreq, d, 6); \
00102 } \
00103 } while (0)
00104
00105 #define PLL_ITERATION_4(xtal, cpufreq, d) \
00106 PLL_MACRO_STEP(xtal, cpufreq, d)
00107
00108 #define PLL_ITERATION_3(xtal, cpufreq, d) \
00109 PLL_ITERATION_4(xtal, cpufreq, (d)*4+0); \
00110 PLL_ITERATION_4(xtal, cpufreq, (d)*4+1); \
00111 PLL_ITERATION_4(xtal, cpufreq, (d)*4+2); \
00112 PLL_ITERATION_4(xtal, cpufreq, (d)*4+3);
00113
00114 #define PLL_ITERATION_2(xtal, cpufreq, d) \
00115 PLL_ITERATION_3(xtal, cpufreq, (d)*4+0); \
00116 PLL_ITERATION_3(xtal, cpufreq, (d)*4+1); \
00117 PLL_ITERATION_3(xtal, cpufreq, (d)*4+2); \
00118 PLL_ITERATION_3(xtal, cpufreq, (d)*4+3);
00119
00120 #define PLL_ITERATION_1(xtal, cpufreq, d) \
00121 PLL_ITERATION_2(xtal, cpufreq, (d)*4+0); \
00122 PLL_ITERATION_2(xtal, cpufreq, (d)*4+1); \
00123 PLL_ITERATION_2(xtal, cpufreq, (d)*4+2); \
00124 PLL_ITERATION_2(xtal, cpufreq, (d)*4+3);
00125
00126 #define PLL_ITERATION(xtal, cpufreq) \
00127 PLL_ITERATION_1(xtal, cpufreq, 0); \
00128 PLL_ITERATION_1(xtal, cpufreq, 1); \
00129 PLL_ITERATION_1(xtal, cpufreq, 2); \
00130 PLL_ITERATION_1(xtal, cpufreq, 3)
00131
00132 #define PLL_CALC(xtal, cpufreq, m, d, k) do \
00133 { \
00134 uint32_t best_err=cpufreq, best_m, best_k, best_d; \
00135 CREATE_PLL_STEP(xtal, cpufreq) \
00136 PLL_ITERATION(xtal, cpufreq); \
00137 *(m)=best_m; *(d)=best_d; *(k)=best_k; \
00138 } while (0)
00139
00140 #if 0
00141 int main(int argc, char *argv[])
00142 {
00143 int32_t m, d, k;
00144 PLL_CALC(18420000, 48023000, &m, &d, &k);
00145
00146 if (__builtin_constant_p(m) && __builtin_constant_p(k) && __builtin_constant_p(d))
00147 printf("SUCCESS -- compile time evaluation\n");
00148 else
00149 printf("FAILURE -- run time evaluation\n");
00150
00151 printf("M:%d D:%d K:%d\n", m, d, k);
00152 }
00153 #endif