00001
00002
00003 #include <stdio.h>
00004 #include <math.h>
00005
00006 #include <string.h>
00007
00008 #include <stdlib.h>
00009
00010 #include "edtinc.h"
00011
00012 #include <stddef.h>
00013
00014 #include "edt_si570.h"
00015
00016
00017 EdtRegisterDescriptor si570regs_map[] = {
00018 {7,5,3,"hs_div"},
00019 {7,6,7,"n1"},
00020 {8,4,10,"rfreq_int"},
00021 {9,0,28,"rfreq_frac"},
00022 {135,7,1,"reset"},
00023 {135,6,1,"newfreq"},
00024 {135,0,1,"recall"},
00025 {137,4,1,"freeze"},
00026 {0,0,0,0}
00027 };
00028
00029 int
00030 edt_set_out_clk_si570(EdtDev *edt_p, EdtSI570 *sip)
00031
00032 {
00033 return 0;
00034 }
00035
00036
00037
00038
00039
00040
00041 void
00042 edt_si570_read_values(EdtDev *edt_p,
00043 u_int base_desc,
00044 u_int device,
00045 EdtSI570 *sip)
00046
00047 {
00048 sip->hs_div = edt_get_two_wire_value(edt_p,
00049 si570regs_map,
00050 base_desc,
00051 device);
00052
00053 sip->n1 = edt_get_two_wire_value(edt_p,
00054 si570regs_map+1,
00055 base_desc,
00056 device);
00057
00058 sip->rfreq_hi = edt_get_two_wire_value(edt_p,
00059 si570regs_map+2,
00060 base_desc,
00061 device);
00062
00063 sip->rfreq_fraction = edt_get_two_wire_value(edt_p,
00064 si570regs_map+3,
00065 base_desc,
00066 device);
00067 }
00068
00069 void
00070 edt_si570_reset(EdtDev *edt_p, u_int base_desc, u_int device)
00071
00072 {
00073 int r;
00074 int t;
00075
00076 edt_set_two_wire_value(edt_p, si570regs_map + 4, base_desc, device, 1);
00077
00078 t = 0;
00079 while (r = edt_get_two_wire_value(edt_p, si570regs_map+4, base_desc, device))
00080 {
00081 edt_msleep(50);
00082 t += 50;
00083 }
00084
00085 edt_msleep(100);
00086 }
00087
00088 void
00089 edt_si570_write_values(EdtDev *edt_p,
00090 u_int base_desc,
00091 u_int device,
00092 EdtSI570 *sip)
00093
00094 {
00095
00096 edt_set_two_wire_value(edt_p, si570regs_map + 7, base_desc, device, 1);
00097
00098 edt_set_two_wire_value(edt_p, si570regs_map, base_desc, device, sip->hs_div);
00099 edt_set_two_wire_value(edt_p, si570regs_map+1, base_desc, device, sip->n1);
00100 edt_set_two_wire_value(edt_p, si570regs_map+2, base_desc, device, sip->rfreq_hi);
00101 edt_set_two_wire_value(edt_p, si570regs_map+3, base_desc, device, sip->rfreq_fraction);
00102
00103
00104 edt_set_two_wire_value(edt_p, si570regs_map + 7, base_desc, device, 0);
00105
00106 edt_set_two_wire_value(edt_p, si570regs_map + 5, base_desc, device, 1);
00107
00108 }
00109
00110 int
00111 edt_si570_dump(EdtDev *edt_p, u_int base_desc, u_int device)
00112
00113 {
00114 edt_two_wire_reg_dump_raw(edt_p, si570regs_map, base_desc, device);
00115 edt_two_wire_reg_dump(edt_p, si570regs_map, base_desc, device);
00116 return 0;
00117 }
00118
00119 double
00120 edt_si570_rfreq(u_int freq_hi, u_int freq_fraction)
00121
00122 {
00123 double scalar = (double) (1 << 28);
00124
00125 return (double) freq_hi + ((double) freq_fraction)/scalar;
00126
00127 }
00128
00129 double edt_si570_fxtal(EdtSI570 *sip, double refclock)
00130
00131 {
00132 double rfreq = edt_si570_rfreq(sip->rfreq_hi,sip->rfreq_fraction);
00133
00134 return ((sip->n1 + 1) * (sip->hs_div + 4) * refclock) / rfreq;
00135
00136 }
00137
00138 double edt_si570_current_freq(EdtSI570 *sip, double fxtal)
00139
00140 {
00141 double rfreq = edt_si570_rfreq(sip->rfreq_hi,sip->rfreq_fraction);
00142 double output;
00143
00144 output = (rfreq * fxtal) / ((sip->hs_div + 4) * (sip->n1 + 1));
00145
00146 return output;
00147 }
00148
00149
00150 void
00151 edt_si570_print(EdtSI570 *sip, double refclock)
00152 {
00153 double rfreq = edt_si570_rfreq(sip->rfreq_hi,sip->rfreq_fraction);
00154
00155 printf("n1 = %d\nhs_div = %d\nrfreq_int = %d\nfraction = %08x\nrfreq = %f\n",
00156 sip->n1,
00157 sip->hs_div,
00158 sip->rfreq_hi,
00159 sip->rfreq_fraction,
00160 rfreq);
00161
00162 printf("\nF1 = %f\n",
00163 ((sip->n1 + 1) * (sip->hs_div + 4) * refclock) / rfreq);
00164
00165
00166 }
00167
00168 #define foscmin 4850000000.0
00169 #define foscmax 5670000000.0
00170
00171 #define N_HS_DIV_VALUES 6
00172
00173 static int hs_divs[N_HS_DIV_VALUES] =
00174 {
00175 4,
00176 5,
00177 6,
00178 7,
00179 9,
00180 11
00181 };
00182
00183 double edt_vco_si570_compute(double xtal, double target, EdtSI570 *parms)
00184
00185 {
00186 double actual = target;
00187 double fxtal = edt_si570_fxtal(parms, xtal);
00188 int best_hdiv = -1;
00189 int best_n1;
00190 double best_fosc;
00191 int i;
00192 int n1;
00193 double fosc;
00194 double rfreq;
00195
00196 for (i=0;i<N_HS_DIV_VALUES;i++)
00197 {
00198 int hs_div = hs_divs[i];
00199
00200 for (n1=0;n1<128;n1++)
00201 {
00202 if (n1==1 || (n1 & 1) == 0)
00203 {
00204 fosc = target * hs_div * n1;
00205
00206 if (fosc >= foscmin && fosc <= foscmax)
00207 {
00208 if (best_hdiv == -1 || (fosc < best_fosc) || (fosc == best_fosc && n1 < best_n1) )
00209 {
00210 best_hdiv = hs_div;
00211 best_n1 = n1;
00212 best_fosc = fosc;
00213 edt_msg(EDTLIB_MSG_INFO_1, "Selected fosc = %10f n1 = %d hdiv = %d\n",
00214 best_fosc,best_n1,best_hdiv);
00215 }
00216 else
00217 edt_msg(EDTLIB_MSG_INFO_1,"Rejected fosc = %10f n1 = %d hdiv = %d\n",
00218 fosc,n1,hs_div);
00219 }
00220 }
00221 }
00222 }
00223
00224 rfreq = best_fosc / fxtal;
00225
00226 edt_msg(EDTLIB_MSG_INFO_1,"new rfreq %f\n", rfreq);
00227
00228 parms->hs_div = best_hdiv - 4;
00229 parms->n1 = best_n1 - 1;
00230 parms->rfreq_fraction = (u_int)((rfreq - floor(rfreq)) * (double) (1 << 28)) ;
00231 parms->rfreq_hi = (u_int) (floor(rfreq));
00232
00233 return actual;
00234
00235 }
00236
00237 int
00238 edt_si570_set_clock(EdtDev *edt_p, u_int base_desc, u_int device,
00239 double nominal, double target, EdtSI570 *parms)
00240
00241 {
00242
00243 EdtSI570 *sip;
00244 EdtSI570 localparms;
00245
00246 if (base_desc < 0x100)
00247 base_desc |= 0x01010000;
00248
00249 if (parms)
00250 sip = parms;
00251 else
00252 sip = &localparms;
00253
00254 edt_si570_reset(edt_p, base_desc, device);
00255
00256 edt_si570_read_values(edt_p, base_desc, device, sip);
00257
00258 edt_vco_si570_compute(nominal, target, sip);
00259
00260 edt_si570_write_values(edt_p, base_desc, device, sip);
00261
00262 return 0;
00263 }
00264
00265
00266
00267
00268 double
00269 edt_si570_get_clock(EdtDev *edt_p, u_int base_desc, u_int device, double nominal,
00270 EdtSI570 *parms)
00271
00272 {
00273 EdtSI570 *sip;
00274 EdtSI570 localparms;
00275 EdtSI570 storeparms;
00276 double fxtal;
00277 double output;
00278
00279 if (parms)
00280 sip = parms;
00281 else
00282 sip = &storeparms;
00283
00284
00285 edt_si570_read_values(edt_p, base_desc, device, sip);
00286
00287
00288
00289
00290 edt_si570_reset(edt_p, base_desc, device);
00291
00292 edt_si570_read_values(edt_p, base_desc, device, &localparms);
00293
00294
00295
00296 fxtal = edt_si570_fxtal(&localparms, nominal);
00297
00298 output = edt_si570_current_freq(sip, fxtal);
00299
00300 edt_si570_write_values(edt_p, base_desc, device, sip);
00301
00302 return output;
00303 }
00304
00305
00306
00307
00308