4 #include "../comedi/drivers/8253.h"
7 /* this function is meant to replace i8253_cascade_ns_to_timer_2div
8 * (which is completely broken at the moment)
10 static inline void cascade_new(int i8253_osc_base, unsigned int *d1, unsigned int *d2, unsigned int *nanosec, int round_mode)
13 unsigned int div1, div2;
14 unsigned int div1_glb, div2_glb, ns_glb;
15 unsigned int div1_lub, div2_lub, ns_lub;
18 unsigned int ns_low, ns_high;
20 divider = *nanosec / i8253_osc_base;
22 div1_lub = div2_lub = 0;
23 div1_glb = div2_glb = 0;
29 start = divider / div2;
30 if(start < 2) start = 2;
31 for (div1 = start; div1 <= divider / div1 + 1; div1++) {
32 for(div2 = divider / div1; div1 * div2 <= divider + div1 + 1; div2++) {
33 ns = i8253_osc_base * div1 * div2;
34 if (ns <= *nanosec && ns > ns_glb) {
39 if (div2 <= 0x10000) {
40 ns = i8253_osc_base * div1 * div2;
41 if (ns >= *nanosec && ns < ns_lub) {
51 case TRIG_ROUND_NEAREST:
53 ns_high = div1_lub * div2_lub * i8253_osc_base;
54 ns_low = div1_glb * div2_glb * i8253_osc_base;
55 if( ns_high - *nanosec < *nanosec - ns_low) {
73 *nanosec = div1 * div2 * i8253_osc_base;
81 int main(int argc,vhar *argv[])
84 int round_mode = TRIG_ROUND_NEAREST;
86 int div1_old, div2_old, ns_old, err_old;
87 int div1_new, div2_new, ns_new, err_new;
88 int div1_pow, div2_pow, ns_pow, err_pow;
91 /* loop over desired nanosecond timings to test */
92 for(i = 10000; i < 100000; i++)
94 ns_old = ns_new = ns_pow = i;
96 i8253_cascade_ns_to_timer_2div(osc_base, &div1_old, &div2_old, &ns_old, round_mode);
99 i8253_cascade_ns_to_timer_power(osc_base, &div1_pow, &div2_pow, &ns_pow, round_mode);
100 err_pow = ns_pow - i;
102 cascade_new(osc_base, &div1_new, &div2_new, &ns_new, round_mode);
103 err_new = ns_new - i;
105 /* print results on this condition */
106 if(abs(err_new) > abs(err_pow))
107 printf("nanosec %i\terr_new %i\tdiv1_new %i\tdiv2_new %i\n"
108 "\t\terr_pow %i\tdiv1_pow %i\tdiv2_pow %i\n",
109 i, err_new, div1_new, div2_new, err_pow, div1_pow, div2_pow);
111 /* consistency checks */
112 if(div1_old * div2_old * osc_base != ns_old) err = 1;
113 if(div1_pow * div2_pow * osc_base != ns_pow) err = 2;
114 if(div1_new * div2_new * osc_base != ns_new) err = 3;
117 printf("err %i\n", err);
125 int main(int argc,char *argv[])
129 unsigned int div1,div2;
132 for(ns = 4*osc_base; ns<0x80000000;ns++){
133 i8253_cascade_ns_to_timer_2div
134 (osc_base, &div1, &div2, &ns, TRIG_ROUND_UP);
138 printf("ns=%d div1=%d div2=%d\n",ns,div1,div2);
139 if(i==100000)exit(0);