4 * This file is part of BeRTOS.
6 * Bertos is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 * As a special exception, you may use this file as part of a free software
21 * library without restriction. Specifically, if other files instantiate
22 * templates or use macros or inline functions from this file, or you compile
23 * this file and link it with other files to produce an executable, this
24 * file does not by itself cause the resulting executable to be covered by
25 * the GNU General Public License. This exception does not however
26 * invalidate any other reasons why the executable file might be covered by
27 * the GNU General Public License.
29 * Copyright 2010 Develer S.r.l. (http://www.develer.com/)
34 * \author Giovanni Bajo <rasky@develer.com>
36 * \brief AT91SAM7S256 CRT.
40 #include <cfg/macros.h>
43 // Versione completamente unrollata
45 #define CREATE_PLL_STEP(xtal, cpufreq)
47 #define PLL_STEP(xtal, cpufreq, d, k) \
49 uint32_t m = (((cpufreq * (1LL << k) * (d)) + (xtal / 2)) / xtal) - 1; \
52 uint32_t pll = (d != 0) ? (xtal * (m + 1)) / (d) : 0; \
53 if (80000000 <= pll && pll <= 160000000) \
55 uint32_t err = ABS((int32_t)((pll >> k) - cpufreq)); \
58 best_err=err; best_m=m; best_k=k; best_d=d; \
66 // Versione con funzione nestata (GCC only)
67 // Tempo di compilazione piĆ¹ rapido
69 #define CREATE_PLL_STEP(xtal, cpufreq) \
70 void __attribute__((always_inline)) PLL_STEP(int u1, int u2, int32_t d, long long k) \
73 uint32_t m = ((((cpufreq * (1LL << k) * (d)) + (xtal / 2)) / xtal) - 1; \
76 uint32_t pll = (xtal * (m + 1)) / (d); \
77 if (80000000UL <= pll && pll <= 160000000UL) \
79 uint32_t err = ABS((int32_t)((pll >> k) - cpufreq)); \
82 best_err=err; best_m=m; best_k=k; best_d=d; \
90 #define PLL_MACRO_STEP(xtal, cpufreq, d) \
92 if ((d) > 0 && (d) <= 255 && \
93 (d) <= xtal / 1000000 && (d) >= xtal / 32000000) \
95 PLL_STEP(xtal, cpufreq, d, 0); \
96 PLL_STEP(xtal, cpufreq, d, 1); \
97 PLL_STEP(xtal, cpufreq, d, 2); \
98 PLL_STEP(xtal, cpufreq, d, 3); \
99 PLL_STEP(xtal, cpufreq, d, 4); \
100 PLL_STEP(xtal, cpufreq, d, 5); \
101 PLL_STEP(xtal, cpufreq, d, 6); \
105 #define PLL_ITERATION_4(xtal, cpufreq, d) \
106 PLL_MACRO_STEP(xtal, cpufreq, d)
108 #define PLL_ITERATION_3(xtal, cpufreq, d) \
109 PLL_ITERATION_4(xtal, cpufreq, (d)*4+0); \
110 PLL_ITERATION_4(xtal, cpufreq, (d)*4+1); \
111 PLL_ITERATION_4(xtal, cpufreq, (d)*4+2); \
112 PLL_ITERATION_4(xtal, cpufreq, (d)*4+3);
114 #define PLL_ITERATION_2(xtal, cpufreq, d) \
115 PLL_ITERATION_3(xtal, cpufreq, (d)*4+0); \
116 PLL_ITERATION_3(xtal, cpufreq, (d)*4+1); \
117 PLL_ITERATION_3(xtal, cpufreq, (d)*4+2); \
118 PLL_ITERATION_3(xtal, cpufreq, (d)*4+3);
120 #define PLL_ITERATION_1(xtal, cpufreq, d) \
121 PLL_ITERATION_2(xtal, cpufreq, (d)*4+0); \
122 PLL_ITERATION_2(xtal, cpufreq, (d)*4+1); \
123 PLL_ITERATION_2(xtal, cpufreq, (d)*4+2); \
124 PLL_ITERATION_2(xtal, cpufreq, (d)*4+3);
126 #define PLL_ITERATION(xtal, cpufreq) \
127 PLL_ITERATION_1(xtal, cpufreq, 0); \
128 PLL_ITERATION_1(xtal, cpufreq, 1); \
129 PLL_ITERATION_1(xtal, cpufreq, 2); \
130 PLL_ITERATION_1(xtal, cpufreq, 3)
132 #define PLL_CALC(xtal, cpufreq, m, d, k) do \
134 uint32_t best_err=cpufreq, best_m, best_k, best_d; \
135 CREATE_PLL_STEP(xtal, cpufreq) \
136 PLL_ITERATION(xtal, cpufreq); \
137 *(m)=best_m; *(d)=best_d; *(k)=best_k; \
141 int main(int argc, char *argv[])
144 PLL_CALC(18420000, 48023000, &m, &d, &k);
146 if (__builtin_constant_p(m) && __builtin_constant_p(k) && __builtin_constant_p(d))
147 printf("SUCCESS -- compile time evaluation\n");
149 printf("FAILURE -- run time evaluation\n");
151 printf("M:%d D:%d K:%d\n", m, d, k);