edt_si5326.c

00001 /* #pragma ident "@(#)set_ss_vco.c      1.17 01/17/05 EDT" */
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_si5326.h"
00015 
00016 #include "edt_msdv.h"
00017 
00018 #include "edt_ocm.h"
00019 
00020 /* for storing register set */
00021 
00022 
00023 
00024 
00025 /*
00026 */
00027 
00028 /*
00029 * this array initializes a si5226 with a 
00030 * 10.3681MHz reference clock input on clock 1 
00031 * to yield a 148.5MHz clock out on clock 1
00032 * the nominal output is 221 HZ high
00033 */
00034 
00035 
00036 
00037 /* description of all register values */
00038 
00039 
00040 EdtRegisterDescriptor si5326regs_map[] = {
00041     {0, 2, 1, "spim"},
00042     {0, 1, 1, "bypass_reg"},
00043     {0, 0, 1, "fxdly"},
00044     {1, 2, 2, "ck_prior2"},
00045     {1, 0, 2, "ck_prior1"},
00046     {2, 4, 4, "bwsel_reg"},
00047     {3, 6, 2, "cksel_reg"},
00048     {3, 5, 1, "dhold"},
00049     {3, 4, 1, "sq_ical"},
00050     {4, 6, 2, "autosel_reg"},
00051     {4, 0, 5, "hist_del"},
00052     {5, 6, 2, "icmos"},
00053     {6, 6, 1, "sleep"},
00054     {6, 3, 3, "sfout2_reg"},
00055     {6, 0, 3, "sfout1_reg"},
00056     {7, 0, 3, "fosrefsel"},
00057     {8, 6, 2, "hlog_2"},
00058     {8, 4, 2, "hlog_1"},
00059     {9, 3, 5, "hist_avg"},
00060     {10, 3, 1, "dsbl2_reg"},
00061     {10, 2, 1, "dsbl1_reg"},
00062     {11, 1, 1, "pd_ck2"},
00063     {11, 0, 1, "pd_ck1"},
00064     {16, 0, 8, "clat"},
00065     {17, 7, 1, "flat_valid"},
00066     {17, 0, 15, "flat"},
00067     {19, 7, 1, "fos_en"},
00068     {19, 5, 2, "fos_thr"},
00069     {19, 3, 2, "valtime"},
00070     {19, 0, 3, "lockt"},
00071     {20, 3, 1, "ck2_bad_pin"},
00072     {20, 2, 1, "ck1_bad_pin"},
00073     {20, 1, 1, "lol_pin"},
00074     {20, 0, 1, "int_pin"},
00075     {21, 7, 1, "incdec_pin"},
00076     {21, 1, 1, "ck1_actv_pin"},
00077     {21, 0, 1, "cksel_pin"},
00078     {22, 3, 1, "ck_actv_pol"},
00079     {22, 2, 1, "ck_bad_pol"},
00080     {22, 1, 1, "lol_pol"},
00081     {22, 0, 1, "int_pol"},
00082     {23, 2, 1, "los2_msk"},
00083     {23, 1, 1, "los1_msk"},
00084     {23, 0, 1, "losx_msk"},
00085     {24, 2, 1, "fos2_msk"},
00086     {24, 1, 1, "fos1_msk"},
00087     {24, 0, 1, "lol_msk"},
00088     {25, 5, 3, "n1_hs"},
00089     {31, 0, 20, "nc1_ls"},
00090     {34, 0, 20, "nc2_ls"},
00091     {40, 5, 3, "n2_hs"},
00092     {40, 0, 20, "n2_ls"},
00093     {43, 0, 19, "n31"},
00094     {46, 0, 19, "n32"},
00095     {55, 3, 3, "clkin2rate"},
00096     {55, 0, 3, "clkin1rate"},
00097     {128, 1, 1, "ck2_actv_reg"},
00098     {128, 0, 1, "ck1_actv_reg"},
00099     {129, 2, 1, "los2_int"},
00100     {129, 1, 1, "los1_int"},
00101     {129, 0, 1, "losx_int"},
00102     {130, 7, 1, "clatprogress"},
00103     {130, 6, 1, "digholdvalid"},
00104     {130, 2, 1, "fos2_int"},
00105     {130, 1, 1, "fos1_int"},
00106     {130, 0, 1, "lol_int"},
00107     {131, 2, 1, "los2_flg"},
00108     {131, 1, 1, "los1_flg"},
00109     {131, 0, 1, "losx_flg"},
00110     {132, 3, 1, "fos2_flg"},
00111     {132, 2, 1, "fos1_flg"},
00112     {132, 1, 1, "lol_flg"},
00113     {134, 0, 8, "nvm_rev"},
00114     {135, 4, 4, "partnum_ro"},
00115     {135, 0, 4, "revid_ro"},
00116     {136, 7, 1, "rst_reg"},
00117     {136, 6, 1, "ical"},
00118     {136, 0, 2, "grade_ro"},
00119     {142, 0, 8, "independentskew1"},
00120     {142, 0, 8, "independentskew2"},
00121     {0,0,0,NULL,0}
00122 };
00123 
00124 #if 0
00125 int
00126 get_SIReg_value(void *target, int offset, int shift, int mask)
00127 
00128 {
00129     EdtSIRegArray *vector = (EdtSIRegArray *) target;
00130     int shiftmask = (mask << shift);
00131     int vindex = 0;
00132     int v;
00133 
00134     while (vector[vindex].offset < offset && vindex < EDT_SI5326_NREGS)
00135         vindex++;
00136 
00137     if (vector[vindex].offset != offset)
00138     {
00139         printf("Unable to find offset %d in vector\n", offset);
00140         return -1;
00141     }
00142 
00143     if (mask == 0xff)
00144     {
00145         v = vector[vindex].value;
00146     }
00147     else
00148     {
00149         v = (vector[vindex].value & shiftmask) >> shift;
00150     }
00151 
00152     return v;
00153 
00154 }
00155 
00156 int
00157 set_SIReg_value(void *target, int offset, int value, int shift, int mask)
00158 
00159 {
00160     EdtSIRegArray *vector = (EdtSIRegArray *) target;
00161     int invmask = ~(mask << shift);
00162     int vindex = 0;
00163 
00164     while (vector[vindex].offset < offset && vindex < EDT_SI5326_NREGS)
00165         vindex++;
00166 
00167     if (vector[vindex].offset != offset)
00168     {
00169         printf("Unable to find offset %d in vector\n", offset);
00170         return -1;
00171     }
00172 
00173     if (mask == 0xff)
00174     {
00175         vector[vindex].value = value;
00176     }
00177     else
00178     {
00179         vector[vindex].value &= invmask;
00180         vector[vindex].value |= (value << shift);
00181     }
00182 
00183     return 0;
00184 
00185 }
00186 
00187 EdtRegisterDescriptor *
00188 edt_si5326_map_lookup(EdtRegisterDescriptor *map, char *name)
00189 
00190 {
00191     int i;
00192     for (i=0;map[i].name != NULL; i++)
00193         if (!strcmp(name,map[i].name))
00194             return map + i;
00195 
00196     return NULL;
00197 
00198 }
00199 
00200 int
00201 edt_si5326_read_reg_array(EdtRegisterDescriptor *map, char *name, EdtSIRegArray *vector)
00202 
00203 {
00204     /* lookup name in map */
00205     EdtRegisterDescriptor * p;
00206 
00207     p = edt_si5326_map_lookup(map, name);
00208 
00209     if (p)
00210     {
00211         return edt_get_two_wire_value(vector, p, get_SIReg_value);
00212     }
00213     else
00214     {
00215         return -1;
00216     }
00217 
00218 }
00219 
00220 int
00221 edt_si5326_write_reg_array(EdtRegisterDescriptor *map, char *name, EdtSIRegArray *vector, u_int value)
00222 
00223 {
00224     /* lookup name in map */
00225     /* lookup name in map */
00226     EdtRegisterDescriptor * p;
00227 
00228     p = edt_si5326_map_lookup(map, name);
00229 
00230     if (p)
00231     {
00232         return edt_set_two_wire_value(vector, p, value,set_SIReg_value );
00233     }
00234     else
00235     {
00236         return -1;
00237     }
00238 }
00239 
00240 
00241 void
00242 edt_si5326_print_regarray(EdtRegisterDescriptor *map, EdtSIRegArray *vector)
00243 
00244 {
00245     int mapindex;
00246 
00247     for (mapindex = 0; map[mapindex].name != NULL ; mapindex++)
00248     {
00249         u_int v = edt_get_two_wire_value(vector, map + mapindex, get_SIReg_value);
00250 
00251         printf("%-20s: %02x\n", map[mapindex].name, v);
00252 
00253     }
00254 }
00255 
00256 #endif
00257 /*****************************************/
00260 /*****************************************/
00261 
00262 /* explore parameter space for optimal settings */
00263 
00264 
00265 #define N_HS_VALUES 8
00266 
00267 int n1n2_hs_values[N_HS_VALUES] = {
00268     11,10,9,8,7,6,5,4
00269 };
00270 
00271 int n1n2_ls_max = 0x100000;
00272 
00273 int n1n2_min = 4 * 2;
00274 int n1n2_max = 11 * 0x100000;
00275 
00276 int n3_max_possible = 0x80000;
00277 
00278 double fosc_min = 4850000000;
00279 double fosc_max = 5670000000;
00280 
00281 double fbw_min = 60;
00282 double fbw_max = 8400;
00283 
00284 typedef struct n1_possibles {
00285     int n1;
00286     int n1_ls;
00287     int n1_hs;
00288     double fosc;
00289 } N1Possibles;
00290 
00291 typedef struct n2_possibles {
00292     int n2;
00293     int n2_ls;
00294     int n2_hs;
00295     double fosc;
00296     int n3;
00297 } N2Possibles;
00298 
00299 double edt_si5326_compute_fbw(int n2, double fosc, int bwsel)
00300 
00301 {
00302     int i;
00303     double f3;
00304     double fbw;
00305     double a,b,c,d;
00306     int two = 1;
00307 
00308     for (i=0;i<bwsel;i++)
00309         two*= 2;
00310 
00311     f3 = fosc/n2;
00312 
00313     a = (f3/(16.84*two));
00314     b = (1.0/sqrt(1.0-(1.0/(3.35 * two))));
00315     c = (1.0/sqrt(1.0-(4276/(n2 * two))));
00316     d = (6500000000.0 / fosc);
00317 
00318     d = d*d;
00319 
00320     fbw = a* b * c * d;
00321 
00322     return fbw;
00323 
00324 }
00325 
00326 /* return valid bwsel */
00327 /* return 0 if not OK */
00328 
00329 int edt_si5326_bwsel(int n2, double fosc)
00330 
00331 {
00332     int bwsel;
00333     double fbw;
00334 
00335     for (bwsel = 1; bwsel <= 10; bwsel++)
00336     {
00337         fbw = edt_si5326_compute_fbw(n2, fosc, bwsel);
00338 
00339         if (fbw >= fbw_min && fbw <= fbw_max)
00340             return bwsel;
00341     }
00342     return 0;
00343 }
00344 
00345 void 
00346 edt_vco_si5326_print(EdtSI53xx *sip)
00347 {
00348     printf("n1_ls=%6d n1_hs=%2d n2_ls=%6d n2_hs=%2d n3=%6d output=%f\n",
00349         sip->n1_ls,
00350         sip->n1_hs,
00351         sip->n2_ls,
00352         sip->n2_hs,
00353         sip->n3,
00354         sip->output);
00355 
00356     printf("n1_ls=%6x n1_hs=%2x n2_ls=%6x n2_hs=%2x n3=%6x output=%f\n",
00357         sip->n1_ls,
00358         sip->n1_hs,
00359         sip->n2_ls,
00360         sip->n2_hs,
00361         sip->n3,
00362         sip->output);
00363 
00364     printf("n1_ls=%6x n1_hs=%2x n2_ls=%6x n2_hs=%2x n3=%6x bwsel=%2d output=%f\n",
00365         sip->n1_ls-1,
00366         sip->n1_hs-4,
00367         sip->n2_ls-1,
00368         sip->n2_hs-4,
00369         sip->n3-1,
00370         sip->bwsel,
00371         sip->output);
00372 }
00373 
00374 void
00375 edt_vco_si5326_set_speedreg(EdtDev *edt_p,
00376                             u_int base_desc, 
00377                             u_int device, 
00378                             EdtSI53xx *sip,
00379                             int clkin)
00380 
00381 {
00382 
00383     edt_set_two_wire_value(edt_p, si5326regs_map+48, base_desc, device, sip->n1_ls-1);
00384     edt_set_two_wire_value(edt_p, si5326regs_map+47, base_desc, device, sip->n1_hs-4);
00385     edt_set_two_wire_value(edt_p, si5326regs_map+51, base_desc, device, sip->n2_ls-1);
00386     edt_set_two_wire_value(edt_p, si5326regs_map+50, base_desc, device, sip->n2_hs-4);
00387     edt_set_two_wire_value(edt_p, si5326regs_map+52, base_desc, device, sip->n3-1);
00388     edt_set_two_wire_value(edt_p, si5326regs_map+5, base_desc, device, sip->bwsel);
00389 
00390 }
00391 
00392 
00396 double edt_vco_si5326_compute(double xtal, double target, EdtSI53xx *sip)
00397 
00398 {
00399     double ratio;
00400     double actual = 0;
00401     int n1_min, n1_max;
00402     int n2_min, n2_max;
00403     int n1;
00404     int which;
00405     int n1_hs;
00406     int n1_ls;
00407     int pindex = 0;
00408     N1Possibles *possibles;
00409     int psize;
00410     int pgrain = 16;
00411     int visit = 0;
00412     int n3_max;
00413     int n3_min;
00414     double curdelta = 1000000000;
00415 
00416     if (xtal == 0)
00417     {
00418         edt_msg(EDTLIB_MSG_FATAL,"Ref frequency of 0 passed to edt_vco_si5326_compute, returning 0\n");
00419         return 0.0;
00420     }
00421 
00422     ratio = target/xtal;
00423 
00424     n1_min = (int) ceil(fosc_min / target);
00425     n1_max = (int) floor(fosc_max/target);
00426 
00427     psize = pgrain;
00428     possibles = (N1Possibles *) malloc(sizeof(N1Possibles) * psize);
00429     for (n1=n1_min;n1 <= n1_max;n1++)
00430     {
00431         for (which = 0; which < N_HS_VALUES;which++)
00432         {
00433             n1_hs = n1n2_hs_values[which];
00434 
00435             n1_ls = n1/n1_hs;
00436 
00437 
00438             if (((n1 % n1_hs) == 0) && n1_ls && (n1_ls & 1) == 0 && (n1_ls <= n1n2_ls_max))
00439             {
00440                 int already = 0;
00441                 int i;
00442 
00443                 for (i=0;i<pindex;i++)
00444                     if (n1 == possibles[i].n1)
00445                     {
00446                         already = 1;
00447                         break;
00448                     }
00449 
00450                     if (!already)
00451                     {
00452                         possibles[pindex].n1 = n1;
00453                         possibles[pindex].n1_ls = n1_ls;
00454                         possibles[pindex].n1_hs = n1_hs;
00455                         possibles[pindex].fosc = (double) (target * n1_ls * n1_hs);
00456                         pindex++;
00457                         if (pindex >= psize)
00458                         {
00459                             psize += pgrain;
00460                             possibles = (N1Possibles *)realloc(possibles, sizeof(N1Possibles) * psize);
00461                         }
00462                     }
00463 
00464             }
00465         }
00466     }
00467 
00468     psize = pindex;
00469     printf("%d possible n1 values\n", pindex);
00470 
00471     for (pindex = 0; pindex < psize;pindex ++)
00472     {
00473         printf("%3d: %8d %5d %2d: %f\n", pindex,                
00474             possibles[pindex].n1,
00475             possibles[pindex].n1_ls,
00476             possibles[pindex].n1_hs,
00477             possibles[pindex].fosc);
00478     }
00479 
00480     /* scan over all possible n3/n2 combinations */
00481 
00482     n3_max = (int) floor(xtal / 2000.0);
00483     n3_min = (int) ceil(xtal/ 2000000.0);
00484 
00485     for (pindex = 0; pindex < psize;pindex ++)
00486     {
00487 
00488         int n3;
00489         int n2;
00490         n1 = possibles[pindex].n1;
00491 
00492         n2_min = n1n2_min;
00493         n2_max = n1n2_max;
00494 
00495         for (n3 = n3_min;n3 <= n3_max;n3++)
00496         {
00497             int n2_low = (int) floor(n3 * ratio * possibles[pindex].n1);
00498             int n2_high = (int) ceil(n3 * ratio * possibles[pindex].n1);
00499             int n2n3_high = n2_high;
00500             int n2n3_low  = n2_low;
00501 
00502             if (n2n3_high > n2_max)
00503                 n2n3_high = n2_max;
00504 
00505             if (n2n3_low < n2_min)
00506                 n2n3_low = n2_min;
00507 
00508             if (n2n3_low > n2_max)
00509                 break;
00510 
00511             for (n2 = n2n3_low; n2 <= n2n3_high;n2++)
00512             {
00513                 for (which = 0; which < N_HS_VALUES;which++)
00514                 {
00515                     int n2_hs = n1n2_hs_values[which];
00516                     int n2_ls = n2/n2_hs;
00517 
00518                     if (n2_ls >= 2 && n2_ls <= n1n2_ls_max)
00519                     {
00520                         /* compute actual fout */
00521                         double actual_n2, test, delta;
00522 
00523                         n2_ls &= 0xffffffe;
00524 
00525                         actual_n2 = n2_ls * n2_hs;
00526 
00527                         test = ((xtal / (double) n3) * actual_n2) / n1;
00528 
00529                         delta = fabs(test - target);
00530 
00531 
00532                         if (delta < curdelta)
00533                         {
00534                             int bwsel = edt_si5326_bwsel(n2, possibles[pindex].fosc);
00535                             if (bwsel != 0)
00536                             {
00537                                 curdelta = delta;
00538                                 actual = test;
00539                                 sip->n2_ls = n2_ls;
00540                                 sip->n2_hs = n2_hs;
00541                                 sip->n1_ls = possibles[pindex].n1_ls;
00542                                 sip->n1_hs = possibles[pindex].n1_hs;
00543                                 sip->n3 = n3;
00544                                 sip->bwsel = bwsel;
00545                                 sip->output = test;
00546                             }
00547                         }
00548                     }
00549 
00550                     visit++;
00551 
00552                 }
00553             }      
00554         }
00555     }
00556 
00557     printf("loops = %d\n",visit);
00558 
00559     free(possibles);
00560 
00561     return actual;
00562 
00563 }
00564 
00565 
00573 double edt_vco_si5326_compute2(double xtal, 
00574                                double target, 
00575                                double target2, 
00576                                EdtSI53xx *sip, 
00577                                EdtSI53xx *sip2,
00578                                int direction /* -1 below, 0 either, 1 above */)
00579 
00580 {
00581     double ratio;
00582     double ratio2;
00583     double actual = 0;
00584     int n1_min, n1_max;
00585     int n2_min, n2_max;
00586     int n1;
00587     int which;
00588     int pindex = 0;
00589     N1Possibles *possibles;
00590     int psize;
00591     int pgrain = 16;
00592     int visit = 0;
00593     int n3_max;
00594     int n3_min;
00595     double curdelta = 1000000000;
00596     double curdelta2 = 1000000000;
00597 
00598     int max_n_possible;
00599     int i;
00600 
00601     if (xtal == 0)
00602     {
00603         edt_msg(EDTLIB_MSG_FATAL,"Ref frequency of 0 passed to edt_vco_si5326_compute, returning 0\n");
00604         return 0.0;
00605     }
00606 
00607     ratio = target/xtal;
00608     ratio2 = target/target2;
00609 
00610     n1_min = (int) ceil(fosc_min / target);
00611     n1_max = (int) floor(fosc_max/target);
00612 
00613     if (n1_min > 11)
00614         n1_min &= ~1;
00615     if (n1_max > 11)
00616         n1_max &= ~1;
00617 
00618     max_n_possible = (n1_max - n1_min + 1);
00619     if (max_n_possible <= 0)
00620         return 0.0;
00621 
00622     possibles = (N1Possibles *) edt_alloc(max_n_possible * sizeof(N1Possibles));
00623 
00624     for (i=n1_min;i<= n1_max;i++)
00625     {
00626         if (i <= 11 || (i&1) == 0)
00627         {
00628             for (which = 0; which < N_HS_VALUES;which++)
00629             {
00630                 int hs = n1n2_hs_values[which];
00631                 int ls = i / hs;
00632 
00633                 if (i % hs == 0 && ((ls & 1) == 0))
00634                 {
00635                     possibles[pindex].n1_hs = hs;
00636                     possibles[pindex].n1_ls = i / hs;
00637                     possibles[pindex].n1 = i;
00638                     possibles[pindex].fosc = (double) (target * i );
00639                     pindex++;
00640                 }
00641             }
00642         }
00643     }
00644 
00645     /* scan over all possible n3/n2 combinations */
00646 
00647     n3_max = (int) floor(xtal / 2000.0);
00648     n3_min = (int) ceil(xtal/ 2000000.0);
00649 
00650 
00651     psize = pindex;
00652 
00653     for (pindex = 0; pindex < psize;pindex ++)
00654     {
00655 
00656         int n3;
00657         int n2;
00658 
00659         int n1_hs = possibles[pindex].n1_hs;
00660         int n1_ls = possibles[pindex].n1_ls;
00661 
00662         n1 = possibles[pindex].n1;
00663 
00664         n2_min = n1n2_min;
00665         n2_max = n1n2_max;
00666 
00667         for (n3 = n3_min;n3 <= n3_max;n3++)
00668         {
00669             int n2_low = (int) floor(n3 * ratio * possibles[pindex].n1);
00670             int n2_high = (int) ceil(n3 * ratio * possibles[pindex].n1);
00671             int n2n3_high = n2_high;
00672             int n2n3_low  = n2_low;
00673 
00674             if (n2n3_high > n2_max)
00675                 n2n3_high = n2_max;
00676 
00677             if (n2n3_low < n2_min)
00678                 n2n3_low = n2_min;
00679 
00680             if (n2n3_low > n2_max)
00681                 break;
00682 
00683             for (n2 = n2n3_low; n2 <= n2n3_high;n2++)
00684             {
00685                 for (which = 0; which < N_HS_VALUES;which++)
00686                 {
00687                     int n2_hs = n1n2_hs_values[which];
00688                     int n2_ls = n2/n2_hs;
00689                     int n1_ls_target2;
00690                     int n1_ls_target2_2;
00691 
00692 
00693                     if (n2_ls >= 2 && n2_ls <= n1n2_ls_max)
00694                     {
00695                         /* compute actual fout */
00696                         double actual_n2, test, delta;
00697                         double test2 = 0;
00698                         double test3 = 0;
00699                         u_char ok1 = TRUE;
00700                         u_char ok2 = TRUE;
00701                         double delta2;
00702                         double delta3;
00703 
00704                         n2_ls &= 0xffffffe;
00705 
00706                         actual_n2 = n2_ls * n2_hs;
00707 
00708                         test = ((xtal / (double) n3) * actual_n2) / n1;
00709 
00710                         delta = fabs(test - target);
00711 
00712                         // find the closest n1_ls for target 2
00713 
00714                         n1_ls_target2 =  (int) (ratio2 * n1_ls);
00715                         if (n1_ls_target2 > 1)
00716                             n1_ls_target2 &= ~1;
00717 
00718                         if (n1_ls_target2 >= 1 && n1_ls_target2 <n1n2_ls_max)
00719                         {
00720                             test2 = ((xtal / (double) n3) * actual_n2) / (n1_hs * n1_ls_target2);
00721                         }
00722                         else 
00723                             ok1 = FALSE;
00724 
00725                         if (n1_ls_target2 == 1)
00726                             n1_ls_target2_2 = 2;
00727                         else
00728                             n1_ls_target2_2 = n1_ls_target2 + 2;
00729 
00730                         if (n1_ls_target2_2 >= 1 && n1_ls_target2_2 <n1n2_ls_max)
00731                             test3=((xtal / (double) n3) * actual_n2) / (n1_hs * n1_ls_target2_2);
00732                         else
00733                         {
00734                             if (ok1)
00735                                 test3 = test2;
00736                             ok2 = FALSE;
00737                         }
00738                         if (!ok1 && ok2)
00739                             test2 = test3;
00740 
00741                         if (ok1 || ok2)
00742                         {
00743                             delta2 = fabs(test2-target2);
00744                             delta3 = fabs(test3-target2);
00745 
00746                             if (direction < 0) /* constrained to be below target */
00747                             {
00748                                 if (test2 > target2)
00749                                 {
00750                                     ok1 = FALSE;
00751                                 }
00752 
00753                                 if (test3 > target2)
00754                                 {
00755                                     ok2 = FALSE;
00756                                 }
00757 
00758                             }
00759                             else if (direction > 1)/* constrained to be above target */
00760                             {
00761                                 if (test2 < target2)
00762                                 {
00763                                     ok1 = FALSE;
00764                                 }
00765 
00766                                 if (test3 < target2)
00767                                 {
00768                                     ok2 = FALSE;
00769                                 }
00770                             }
00771 
00772                             if (ok1)
00773                             {
00774                                 if (ok2)
00775                                 {
00776                                     if (delta2 > delta3)
00777                                     {
00778                                         delta2 = delta3;
00779                                         n1_ls_target2 = n1_ls_target2_2;
00780                                         test2 = test3;
00781                                     }
00782                                 }
00783                             }
00784                             else if (ok2)
00785                             {
00786                                 delta2 = delta3;
00787                                 n1_ls_target2 = n1_ls_target2_2;
00788                                 test2 = test3;
00789                             }
00790 
00791                             if ((ok1 || ok2) && n1_ls_target2 >= 2 && n1_ls_target2 <= n1n2_ls_max)
00792                             {
00793 
00794 
00795                                 int bwsel = edt_si5326_bwsel(n2, possibles[pindex].fosc);
00796 
00797                                 if (delta <= curdelta && bwsel != 0)
00798                                 {
00799                                     if (delta < curdelta ||
00800                                         (delta == curdelta && delta2 < curdelta2))
00801                                     {
00802                                         curdelta = delta;
00803                                         curdelta2 = delta2;
00804                                         actual = test;
00805                                         sip->n2_ls = n2_ls;
00806                                         sip->n2_hs = n2_hs;
00807                                         sip->n1_ls = possibles[pindex].n1_ls;
00808                                         sip->n1_hs = possibles[pindex].n1_hs;
00809                                         sip->n3 = n3;
00810                                         sip->bwsel = bwsel;
00811                                         sip->output = test;
00812                                         sip2->n2_hs = n2_hs;
00813                                         sip2->n1_ls = n1_ls_target2;
00814                                         sip2->n1_hs = possibles[pindex].n1_hs;
00815                                         sip2->n3 = n3;
00816                                         sip2->bwsel = bwsel;
00817                                         sip2->output = test2;
00818                                         sip2->n2_ls = n2_ls;
00819                                     }
00820                                 }
00821                             }
00822 
00823                         }
00824                         visit++;
00825 
00826                     }
00827                 }
00828             }      
00829         }
00830     }
00831 
00832     edt_free((u_char *) possibles);
00833 
00834     return actual;
00835 
00836 
00837 }

Generated on 19 Jun 2015 by  doxygen 1.4.7