BeRTOS
|
00001 00039 #include <io/arm.h> 00040 #include <cfg/macros.h> 00041 00042 #if 1 00043 // Versione completamente unrollata 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 // Versione con funzione nestata (GCC only) 00067 // Tempo di compilazione più rapido 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(18432000, 48054857, &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