lib_srxl.c

00001 #include "edtinc.h"
00002 #include "lib_srxl.h"
00003 
00004 #define SRXLFATAL EDTLIB_MSG_FATAL
00005 #define SRXLINFO  EDTLIB_MSG_INFO_1
00006 
00007 
00017 void srxl_serial_write(EdtDev *edt_p, uint_t desc, uint_t val)
00018 {
00019         /* wait for not busy (that is, wait until XFER_BUSY bit goes low) 
00020             before writes */
00021         while ((edt_reg_read(edt_p, SRXL_SERIAL_CTRL) & SRXL_SERIAL_CTRL_XFER_BUSY) != 0); 
00022         edt_reg_write(edt_p, desc, val);
00023 }
00024         
00025 
00034 void srxl_gc_write(EdtDev *edt_p, int chip, uint_t address, uint_t value)
00035 {
00036         /* The given address needs to be modified if the caller
00037            is trying to access the second chip. */
00038         if (chip) {
00039                 address = 0x80 | address;
00040         }
00041 
00042         srxl_serial_write(edt_p, SRXL_GC_ADDR, address);
00043         srxl_serial_write(edt_p, SRXL_GC_DATA, value);
00044 }
00045         
00046         
00047 
00056 void srxl_gc_set_page(EdtDev *edt_p, int chip, int page) 
00057 {
00058         /* The internal wiring of the graychip is such that 
00059            when specifying the page, its value must be 
00060            left shifted one bit. */
00061         srxl_gc_write(edt_p, chip, 0x02, page << 1);
00062 }
00063 
00064 
00065 
00073 int srxl_set_sample_clk(EdtDev* edt_p, float samp_freq) 
00074 {
00075         unsigned  dds_word, word1, word2, word3, word4;
00076         unsigned  clkregval;
00077         if ((samp_freq < 1.0) | (samp_freq > 65.)) {
00078                 edt_msg(SRXLFATAL, 
00079                                 "Error--requested Sample Clock Frequency %f MHz is out of range: "\
00080                                 "expected 1 <= freq <= 65 MHz\n",
00081                                 samp_freq);
00082                 return -1; /*error, A/D's dont support sample clock < 1mhz or > 65mhz */
00083         }
00084         else    /*sample clock is valid */
00085         {
00086                 /*if sample clock is >40MHz, then set DCS high, otherwise DCS is low */
00087                 clkregval = edt_reg_read(edt_p, SRXL_CLK_CTRL);
00088                 if(samp_freq >= 40)
00089                         edt_reg_write(edt_p, SRXL_CLK_CTRL, clkregval | 0x10);
00090                 else
00091                         edt_reg_write(edt_p, SRXL_CLK_CTRL, clkregval & 0xE0);
00092 
00093                 /*fraction of the 200MHz DDS clock rate (10MHz ref X 20X PLL) */
00094                 dds_word = (int) ((samp_freq * 256. * 256. * 256. * 256.) / 200.);
00095                 edt_reg_write(edt_p, SRXL_DDS_CTRL, 0x02);      /*reset ad9951 */       
00096                 edt_reg_write(edt_p, SRXL_DDS_CTRL, 0x00);      /*clear reset */
00097 
00098                 /*set up proper order for tuning word (MSB first) */
00099                 word1 = dds_word & 0xff;
00100                 dds_word = dds_word >> 8;
00101                 word2 = dds_word & 0xff;
00102                 dds_word = dds_word >> 8;
00103                 word3 = dds_word & 0xff;
00104                 dds_word = dds_word >> 8;
00105                 word4 = dds_word & 0xff;
00106 
00107                 /* write all registers */
00108                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00); /* wait for not busy */
00109                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00110                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00111                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00112                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00113                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x01);
00114                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00115                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00116                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0xA0);
00117                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x02);
00118                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00119                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00120                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x03);
00121                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00122                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x04);
00123                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  word4);
00124                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  word3);
00125                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  word2);
00126                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  word1);
00127                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x05);
00128                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00129                 srxl_serial_write(edt_p,  SRXL_DDS_DATA,  0x00);
00130                 srxl_serial_write(edt_p,  SRXL_DDS_CTRL,  0x01);
00131                 edt_reg_write(edt_p, SRXL_DDS_CTRL, 0x00);
00132         }
00133         return 0; /*normal return */
00134 }
00135 
00136 
00137 
00144 int srxl_set_if_losc(EdtDev *edt_p, unsigned freq) 
00145 {
00146         unsigned prescale;
00147         if ((freq < 63) | (freq > 225)) {
00148                 edt_msg(SRXLFATAL, 
00149                                 "Error--requested IF Frequency %d Mhz is out of range: "\
00150                                 "expected 63 <= freq <= 225 MHz\n",
00151                                 freq);
00152                 return -1; /*error requested frequency too high or low */
00153         }
00154         else if (freq < 118) { /*low frequency range */
00155                 freq *= 2;
00156                 prescale = 0x1a; 
00157         }
00158         else { /*high frequency range */
00159                 prescale = 0x0a;
00160         }
00161         edt_reg_write(edt_p, SRXL_PLL_LOW,((freq<<3) + 1) & 0xff);  /*write bits 0-4 to bits 2-7 (+ 1 for reg 1) */
00162         edt_reg_write(edt_p, SRXL_PLL_LOW+1,(freq>>5) & 0xff);  /*bits 5-12 to bits 8-15 */
00163         edt_reg_write(edt_p, SRXL_PLL_LOW+2,0);  /*write 0's to bits 16-23 */
00164 
00165         edt_reg_write(edt_p, SRXL_PLL_LOW, prescale);  /*write reg 2 with prescale bit for correct freq range */
00166         edt_reg_write(edt_p, SRXL_PLL_LOW+1,0);  
00167         edt_reg_write(edt_p, SRXL_PLL_LOW+2,0);  
00168 
00169         edt_msleep(100); /*give PLL a chance to stabilize for 100ms */
00170         if ((edt_reg_read(edt_p, SRXL_SERIAL_CTRL) & 0x20) == 0) {
00171                 edt_msg(SRXLFATAL, "Warning!!! IF Local Osc PLL did not Lock!!!\n");
00172                 return -1;
00173         }
00174         else edt_msg(SRXLINFO, "IF Local Osc PLL Locked to new frequency\n");
00175         return 0; /*normal return */
00176 }
00177 
00178 
00179 
00186 int srxl_set_lb_losc(EdtDev *edt_p, unsigned freq) 
00187 {
00188         unsigned vco, div2,n, status;
00189         if ((freq < 925) | (freq > 2175)) {
00190                 edt_msg(SRXLFATAL,
00191                                 "Error--requested L-band Frequency %d MHz is out of range: "\
00192                                 "expected 925 <= freq <= 2175\n",
00193                                 freq);
00194                 return -1; /*error requested frequency too hign or low */
00195         }
00196         else if (freq < 932) {
00197                 vco = 4;
00198                 div2 = 0;
00199         }
00200         else if (freq < 1036) {
00201                 vco = 5;
00202                 div2 = 0;
00203         }
00204         else if (freq < 1125) {
00205                 vco = 6;
00206                 div2 = 0;
00207         }
00208         else if (freq < 1216) {
00209                 vco = 0;
00210                 div2 = 1;
00211         }
00212         else if (freq < 1355) {
00213                 vco = 1;
00214                 div2 = 1;
00215         }
00216         else if (freq < 1512) {
00217                 vco = 2;
00218                 div2 = 1;
00219         }
00220         else if (freq < 1670) {
00221                 vco = 3;
00222                 div2 = 1;
00223         }
00224         else if (freq < 1863) {
00225                 vco = 4;
00226                 div2 = 1;
00227         }
00228         else if (freq < 2071) {
00229                 vco = 5;
00230                 div2 = 1;
00231         }
00232         else {
00233                 vco = 6;
00234                 div2 = 1;
00235         }
00236         /*calculate PLL N value for 10 MHz reference.  Round requested freq to a multiple of 5MHz */
00237         n = (int) ((float)((freq / 5) * 5)/ 1.25);
00238         edt_msg(SRXLINFO, "Requested %d MHz has been rounded to %d MHz\n",freq,(int)((float)n * 1.25));
00239         edt_msg(SRXLINFO, "Initial VCO selected = %d\n",vco);
00240         srxl_serial_write(edt_p,  SRXL_SERIAL_CTRL, 0); /*wait for i2c not busy */
00241         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+1,0); /*max2118 reg 0 */
00242         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+2, ((n >> 8) & 0x7f) | (div2 << 7));
00243         srxl_serial_write(edt_p,  SRXL_SERIAL_CTRL+2,  (n & 0xff)); /*wait for i2c not busy */
00244         srxl_serial_write(edt_p,  SRXL_SERIAL_CTRL+2, 0x58 | vco); /*wait for i2c not busy       */
00245         while ((edt_reg_read(edt_p, SRXL_SERIAL_CTRL) & 0x80) == 0x80); /*wait for i2c not busy */
00246         edt_msleep(100); /*wait for PLL to settle */
00247 
00248         /*read the PLL tuning voltage ADC bits */
00249         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+1,4); /* max2118 reg 4 */
00250         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+2,0x2a); /*clear ADC ctl bits */
00251         srxl_serial_write(edt_p,  SRXL_SERIAL_CTRL+1, 4); /*wait for i2c not busy */
00252         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+2,0x6a); /*set ADC enable */
00253         srxl_serial_write(edt_p,  SRXL_SERIAL_CTRL+1, 4); /*wait for i2c not busy */
00254         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+2,0xea); /*set ADC latch enable */
00255         while ((edt_reg_read(edt_p, SRXL_SERIAL_CTRL) & 0x80) == 0x80); /*wait for i2c not busy */
00256         /*read the max2118 status register */
00257         edt_reg_write(edt_p, SRXL_SERIAL_CTRL,1); /*set I2C read mode */
00258         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+1,0); /*dummy write returns status value */
00259         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+2,0);
00260         while ((edt_reg_read(edt_p, SRXL_SERIAL_CTRL) & 0x80) == 0x80); /*wait for i2c not busy */
00261 
00262         status = (edt_reg_read(edt_p, SRXL_SERIAL_CTRL+2) >> 2) & 0x7;
00263         edt_msg(SRXLINFO, "Max2118 Status ADC bits return %d\n",status);
00264 
00265         edt_reg_write(edt_p, SRXL_SERIAL_CTRL,0); /*clear I2C read mode */
00266         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+1,4);
00267         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+2,0x6a); /*clear ADC latch enable */
00268         srxl_serial_write(edt_p,  SRXL_SERIAL_CTRL+1, 4); /*wait for i2c not busy */
00269         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+2,0x2a); /*clear ADC en bit */
00270         while ((edt_reg_read(edt_p, SRXL_SERIAL_CTRL) & 0x80) == 0x80); /*wait for i2c not busy */
00271 
00272         /*adjust choice of vco if tuning voltage is too high or low */
00273         if (status == 0) vco--;
00274         else if (status == 0x7) vco++;
00275         edt_msg(SRXLINFO, "Final VCO selected = %d\n",vco);
00276         /*rewrite the vco selection  */
00277         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+1,2); /*max2118 reg 2 */
00278         edt_reg_write(edt_p, SRXL_SERIAL_CTRL+2,0x58 | vco);
00279         while ((edt_reg_read(edt_p, SRXL_SERIAL_CTRL) & 0x80) == 0x80); /*wait for i2c not busy */
00280         edt_msleep(100); /*wait for PLL to settle */
00281         return 0;
00282 }

Generated on Mon May 12 16:38:54 2008 by  doxygen 1.5.1