lib_e3t3.c

00001 /* #pragma ident "@(#)lib_e3t3.c        1.8 06/02/11 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 "edt_vco.h"
00013 #include "edt_ss_vco.h"
00014 
00015 #include "lib_e3t3.h"
00016 
00017 #include "edt_bitload.h"
00018 
00019 #define E3FREQ  34368000.0
00020 #define T3FREQ  44736000.0
00021 #define XTAL    10368100.0
00022 
00023 /*
00024 * offsets in the 8 bit indirect space 78P2344JAT serial pins
00025 */
00026 #define TDK78P2344_EN_D         0x0101004A
00027 #define TDK78P2344_EN_D_0       0x0101004A
00028 #define TDK78P2344_EN_D_1       0x0101004B      
00029 #define TDK78P2344_CTL  0x0101004C
00030 #define TDK78P2344_LOS  0x01010048
00031 
00032 #define TDK78P2344_LOS_0        0x01010045
00033 #define TDK78P2344_LOS_1        0x01010046
00034 #define TDK78P2344_LOS_2        0x01010047
00035 #define TDK78P2344_LOS_3        0x01010048
00036 
00037 /* bits in the data enable register */
00038 #define TDK78P2344_ENCH 0xff
00039 
00040 /* bits in the control register for c3 board*/
00041 
00042 #define TDK78P2344_C3_EN_TX 0x0f
00043 
00044 /* bits in the control register for 16te3 board*/
00045 #define TDK78P2344_16TE3_SEL_0 0x00
00046 #define TDK78P2344_16TE3_SEL_1 0x01
00047 #define TDK78P2344_16TE3_SEL_2 0x02
00048 #define TDK78P2344_16TE3_SEL_3 0x03
00049 
00050 /* bits common to both */
00051 
00052 #define TDK78P2344_ENABLE 0x10
00053 #define TDK78P2344_SDI  0x20
00054 #define TDK78P2344_SCK  0x40
00055 #define TDK78P2344_CS   0x80
00056 
00057 /* bits in the status register */
00058 #define TDK78P2344_INTR 0x0f
00059 
00060 /* unfortunately SDO bit is not the same on c3/16te3 */
00061 
00062 #define TDK78P2344_16TE3_SDO    0x10
00063 #define TDK78P2344_C3_SDO       0x20
00064 
00065 /* Page bamks in the TDK78P2344 */
00066 #define GLOBAL_BANK     0x0
00067 #define CHAN_BANK_BASE  0x1
00068 
00069 /* sub addresses in the global bank */
00070 #define TDK78P2344_MSCR 0x0
00071 #define TDK78P2344_INTC 0x1
00072 
00073 /* sub addresses in each per port bank */
00074 #define TDK78P2344_MDCR 0x0
00075 #define TDK78P2344_STAT 0x1
00076 #define TDK78P2344_JACR 0x3
00077 
00078 
00079 void
00080 edt_write_78P2344_s_bit(EdtDev * edt_p, u_int bit)
00081 {
00082     /* assume the sck  and sdi are low  */
00083     /* always set serial enable (CS) */
00084     if (bit == 0)
00085     {
00086         edt_reg_or( edt_p, TDK78P2344_CTL, TDK78P2344_CS );
00087     }
00088     else
00089     {
00090         edt_reg_or( edt_p, TDK78P2344_CTL, TDK78P2344_CS | TDK78P2344_SDI );
00091     }
00092     /* set sck */
00093     edt_reg_or( edt_p, TDK78P2344_CTL, TDK78P2344_SCK );
00094     /* clear sdi and sck together (data is latched on the rising edge */
00095     edt_reg_and(edt_p, TDK78P2344_CTL, ~(TDK78P2344_SDI | TDK78P2344_SCK));
00096 
00097     edt_reg_read(edt_p, TDK78P2344_CTL);
00098 
00099 }
00100 
00101 u_int
00102 edt_read_78P2344_s_bit(EdtDev * edt_p, u_int los, u_int sdo)
00103 {
00104     volatile u_int tdk_stat;
00105     /* read the first bit before clocking to the next */
00106     tdk_stat = edt_reg_read(edt_p, los);
00107     /* assume SCK is low to start - always set serial enable high */
00108     edt_reg_or( edt_p, TDK78P2344_CTL, TDK78P2344_CS | TDK78P2344_SCK );
00109     edt_reg_and(edt_p, TDK78P2344_CTL, ~(TDK78P2344_SDI | TDK78P2344_SCK));
00110     if ((tdk_stat & sdo) == 0)
00111     {
00112         return(0);
00113     }
00114     else
00115     {
00116         return(1);
00117     }
00118 }
00119 
00120 void
00121 edt_78p2344_serial_add(EdtDev * edt_p, u_int bank, u_int sub_add)
00122 {
00123     volatile int i;
00124 
00125     /* read write bit is already sent */
00126     for(i=0; i<3; i++)
00127     {
00128         edt_write_78P2344_s_bit(edt_p, (sub_add & 0x1));
00129         sub_add >>= 1;
00130     }
00131     for(i=0; i<4; i++)
00132     {
00133         edt_write_78P2344_s_bit(edt_p, (bank & 0x1));
00134         bank >>= 1;
00135     }
00136 }
00137 
00138 unsigned char
00139 edt_read_78p2344_reg(EdtDev * edt_p, u_int bank, u_int sub_add, u_int los, u_int sdo)
00140 {
00141     int i;
00142     volatile unsigned char data = 0;
00143 
00144     /* output read/write bit as 1 (read) */
00145     edt_write_78P2344_s_bit(edt_p, 1);
00146     /* output address */
00147     edt_78p2344_serial_add(edt_p, bank, sub_add);
00148     for(i=0; i<8; i++)
00149     {
00150         data >>= 1;
00151         if ( (edt_read_78P2344_s_bit(edt_p, los, sdo)) != 0)
00152         {
00153             data |= 0x80;
00154         }
00155     }
00156     /* drop serial enable */
00157     edt_reg_and(edt_p, TDK78P2344_CTL, ~(TDK78P2344_CS));
00158     return(data);
00159 }
00160 
00161 void
00162 edt_write_78p2344_reg(EdtDev * edt_p, u_int bank, u_int sub_add, unsigned char indata)
00163 {
00164     volatile int i;
00165     volatile int data = indata;
00166     /* output read/write bit as 0 (write) */
00167     edt_write_78P2344_s_bit(edt_p, 0);
00168     /* output address */
00169     edt_78p2344_serial_add(edt_p, bank, sub_add);
00170     for(i=0; i<8; i++)
00171     {
00172         edt_write_78P2344_s_bit(edt_p, (data & 0x1));
00173         data >>= 1;
00174     }
00175     /* drop serial enable */
00176     edt_reg_and(edt_p, TDK78P2344_CTL, ~(TDK78P2344_CS));
00177 
00178     {
00179         volatile u_int los;
00180         volatile u_int sdo;
00181         volatile u_int chip = edt_reg_read(edt_p,  TDK78P2344_CTL) & 0x3;
00182         volatile u_int readback;
00183         if (edt_is_combo3(edt_p->mezz.id))
00184         {
00185             los =  TDK78P2344_LOS;
00186             sdo =  TDK78P2344_C3_SDO;
00187         }
00188         else if (edt_p->mezz.id == MEZZ_16TE3)
00189         {
00190             los =  TDK78P2344_LOS_0 + chip;
00191             sdo =  TDK78P2344_16TE3_SDO;        
00192         } else {
00193             edt_msg(EDTLIB_MSG_WARNING, "edt_write_78p2344_reg: ERROR, invalid mezz.id (0x%x)\n",
00194                 edt_p->mezz.id);
00195             return;
00196         }
00197 
00198 
00199         readback = edt_read_78p2344_reg(edt_p, bank, sub_add, los, sdo);
00200 
00201         if (readback != indata)
00202         {
00203             edt_msg(EDTLIB_MSG_WARNING, "data not set correctly %02x != %02x\n", readback, indata);
00204         }
00205 
00206     }
00207 
00208 }
00209 
00210 
00211 
00212 void
00213 edt_tdk78P2344_e3t3_init(EdtDev *edt_p, int loopback, int transmit, u_int mscr)
00214 {
00215     volatile int i;
00216     volatile u_int los;
00217     volatile u_int sdo;
00218     volatile u_int chip = edt_reg_read(edt_p,  TDK78P2344_CTL) & 0x3;
00219     volatile u_int readback;
00220 
00221     if (edt_is_combo3(edt_p->mezz.id))
00222     {
00223         los =  TDK78P2344_LOS;
00224         sdo =  TDK78P2344_C3_SDO;
00225     }
00226     else if (edt_p->mezz.id == MEZZ_16TE3)
00227     {
00228         los =  TDK78P2344_LOS_0 + chip;
00229         sdo =  TDK78P2344_16TE3_SDO;
00230 
00231     } else {
00232         edt_msg(EDTLIB_MSG_WARNING, "edt_tdk78P2344_e3t3_init: ERROR, invalid mezz.id (0x%x)\n",
00233             edt_p->mezz.id);
00234         return;
00235     }
00236 
00237     edt_write_78P2344_s_bit(edt_p, 1);
00238     /* set glogal register 0 for e3, endec on and sense on falling edge */
00239 
00240     edt_write_78p2344_reg(edt_p, 0, TDK78P2344_MSCR, mscr);
00241     readback = edt_read_78p2344_reg(edt_p, 0, TDK78P2344_MSCR, los, sdo);
00242     edt_write_78p2344_reg(edt_p, 0, TDK78P2344_MSCR, mscr);
00243     readback = edt_read_78p2344_reg(edt_p, 0, TDK78P2344_MSCR, los, sdo);
00244 
00245     edt_msg(EDTLIB_MSG_INFO_2, "MSCR set %02x read %02x\n", mscr, readback);
00246 
00247     edt_write_78p2344_reg(edt_p, 0, TDK78P2344_INTC, 0x82); /* intr is los */
00248     /* for each channel */
00249     for(i=0; i<4; i++)
00250     {
00251         if ((loopback & (0x1 << i)) == 0)
00252             if ((transmit & (0x1 << i)) != 0)
00253                 edt_write_78p2344_reg(edt_p, i+1, TDK78P2344_MDCR, 0x21);
00254             else
00255                 edt_write_78p2344_reg(edt_p, i+1, TDK78P2344_MDCR, 0x20);
00256         else
00257             edt_write_78p2344_reg(edt_p, i+1, TDK78P2344_MDCR, 0x29);
00258 
00259         edt_write_78p2344_reg(edt_p, i+1, TDK78P2344_JACR, 0x8c);
00260     }
00261 }
00262 
00263 void
00264 edt_tdk78P2344_dump(EdtDev *edt_p, int chip)
00265 {
00266     volatile int i;
00267     volatile u_int los;
00268     volatile u_int sdo;
00269 
00270     if (edt_is_combo3(edt_p->mezz.id))
00271     {
00272         los =  TDK78P2344_LOS;
00273         sdo =  TDK78P2344_C3_SDO;
00274     }
00275     else if (edt_p->mezz.id == MEZZ_16TE3)
00276     {
00277         los =  TDK78P2344_LOS_0 + chip;
00278         sdo =  TDK78P2344_16TE3_SDO;
00279 
00280     }
00281     else
00282     {
00283         edt_msg(EDTLIB_MSG_WARNING, "edt_tdk78P2344_dump requires setting edt_p->mezz.id\n");
00284         return;
00285     }
00286 
00287     if (edt_p->mezz.id == MEZZ_16TE3)
00288         printf("78P2344 Chip %d, Chan %2d-%2d, ", chip, chip *4, (chip *4) + 3);
00289 
00290     printf("Global registers: MSCR = %02x ", 
00291         edt_read_78p2344_reg(edt_p, 0, TDK78P2344_MSCR, los, sdo));
00292     printf("INTC = %02x\n", edt_read_78p2344_reg(edt_p, 0, TDK78P2344_INTC, los, sdo));
00293     /* for each channel */
00294     for(i=0; i<4; i++)
00295     {
00296         printf("\tChannel %d registers: MDCR = %02x ", i, 
00297             edt_read_78p2344_reg(edt_p, i+1, TDK78P2344_MDCR, los, sdo));
00298         printf("STAT = %02x ", edt_read_78p2344_reg(edt_p, i+1, TDK78P2344_STAT, los, sdo));
00299         printf("JACR = %02x\n", edt_read_78p2344_reg(edt_p, i+1, TDK78P2344_JACR, los, sdo));
00300     }
00301 }
00302 
00303 void
00304 edt_c3_set_direction_switch(EdtDev *edt_p, int transmit)
00305 
00306 {
00307     /* unreset tdk  set relay direction */
00308     volatile u_char ctl;
00309 
00310     ctl = edt_reg_read(edt_p, TDK78P2344_CTL) & ~TDK78P2344_C3_EN_TX;
00311 
00312     edt_reg_write(edt_p, TDK78P2344_CTL, 
00313         ctl | (TDK78P2344_C3_EN_TX & transmit)); 
00314 
00315 }
00316 
00317 void
00318 edt_setup_c3_e3t3(EdtDev *edt_p, int reset, int transmit, int loopback, int t3)
00319 
00320 {
00321     volatile double target = E3FREQ;
00322     volatile u_int mscr = 0xAC;
00323 
00324     if (t3)
00325     {
00326         target = T3FREQ;
00327         mscr   = 0xCC;
00328     }
00329 
00330     /* reset tdk78p2344 and the turn off data */
00331     edt_reg_write(edt_p, TDK78P2344_CTL, 0);
00332 
00333     if (reset == 1)
00334     {
00335         /* hardware reset lxt3108 and the rest of the interface chip */
00336         edt_reg_write(edt_p, PCD_CMD, 0);
00337 
00338         edt_msleep(1); /* reset low for a while */
00339         /* unreset chip and lxt3108 */
00340         edt_reg_write(edt_p, PCD_CMD, 0x8);
00341     }
00342 
00343     /*  set pll 2 for e3 clock times 1 */
00344 
00345     edt_set_frequency_ics307(edt_p, XTAL, target, 2, 0);
00346 
00347     /* unreset tdk  set relay direction */
00348     edt_reg_write(edt_p, TDK78P2344_CTL, 
00349         TDK78P2344_ENABLE | (TDK78P2344_C3_EN_TX & (transmit | loopback))); 
00350     edt_reg_read(edt_p, TDK78P2344_CTL);
00351 
00352 
00353     /* enable the data */
00354     edt_reg_write(edt_p, TDK78P2344_EN_D, TDK78P2344_ENCH); 
00355     edt_reg_read(edt_p, TDK78P2344_EN_D);
00356 
00357 
00358     edt_tdk78P2344_e3t3_init(edt_p, loopback, transmit, mscr);
00359 
00360 }
00361 
00362 void
00363 edt_16te3_set_chip(EdtDev *edt_p, int chip)
00364 
00365 {
00366     edt_reg_write(edt_p, TDK78P2344_CTL, 
00367         TDK78P2344_ENABLE | chip);
00368 }
00369 
00370 void
00371 edt_setup_16te3_e3t3(EdtDev *edt_p, int reset, int transmit, int loopback, int t3)
00372 
00373 {
00374     volatile double target = E3FREQ;
00375     volatile u_int mscr = 0xAC;
00376     volatile int chip;
00377 
00378     if (t3)
00379     {
00380         target = T3FREQ;
00381         mscr   = 0xCC;
00382     }
00383 
00384     /* reset tdk78p2344 and the turn off data */
00385     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_0);
00386     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_1);
00387     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_2);
00388     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_3);
00389 
00390     if (reset == 1)
00391     {
00392         /* hardware reset lxt3108 and the rest of the interface chip */
00393         edt_reg_write(edt_p, PCD_CMD, 0);
00394 
00395         edt_msleep(1); /* reset low for a while */
00396         /* unreset chip and lxt3108 */
00397         edt_reg_write(edt_p, PCD_CMD, 0x8);
00398     }
00399 
00400     /*  set pll 2 for e3 clock times 1 */
00401 
00402     edt_set_frequency_ics307(edt_p, XTAL, target, 2, 0);
00403 
00404     /* unreset tdk  set relay direction */
00405     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_0);
00406     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_ENABLE); 
00407 
00408     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_1);
00409     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_ENABLE); 
00410 
00411     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_2);
00412     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_ENABLE); 
00413 
00414     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_3);
00415     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_ENABLE); 
00416 
00417 
00418     /* enable the data */
00419     edt_msleep(10);
00420     edt_reg_write(edt_p, TDK78P2344_EN_D_0, TDK78P2344_ENCH); 
00421     edt_msleep(10);
00422     edt_reg_write(edt_p, TDK78P2344_EN_D_1, TDK78P2344_ENCH); 
00423     edt_msleep(10);
00424 
00425 
00426     for (chip = 0; chip < 4; chip++)
00427     {
00428         edt_16te3_set_chip(edt_p, chip);
00429         edt_tdk78P2344_e3t3_init(edt_p, loopback, transmit, mscr);
00430     }
00431 }
00432 
00433 
00434 /* Defines for testing 16TE3 boards w/no cpld programming */
00435 #define TDK78P2344_EN_D_0       0x0101004A
00436 #define TDK78P2344_EN_D_1       0x0101004B      
00437 #define TDK78P2344_LOS_0        0x01010045
00438 #define TDK78P2344_CTL          0x0101004C
00439 #define TDK78P2344_ENABLE       0x10
00440 #define TDK78P2344_ENCH         0xff
00441 #define TDK78P2344_16TE3_SEL_3  0x03
00442 #define TDK78P2344_16TE3_SDO    0x10
00443 #define TDK78P2344_MSCR         0x0
00444 #define TDK78P2344_MDCR         0x0
00445 
00446 int
00447 edt_test_16te3(EdtDev *edt_p)
00448 
00449 {
00450     int rc;
00451 
00452     /* If here test for 16te3 mezzanine board with cpld's not programmed. */
00453     u_int los, sdo, mscr, mdcr;
00454 
00455     puts("Testing for 16TE3 with unprogrammed CPLD:  Loading te3_16io_test.bit");
00456     if ((rc = edt_bitload(edt_p, NULL, "te3_16io_test.bit", 0, 0)) != 0)
00457     {
00458         edt_msg(EDTLIB_MSG_WARNING, "Unable to load %s\n", "te3_16io_test.bit");
00459         return -1;
00460     }
00461     edt_intfc_write(edt_p, PCD_CMD, 0x08); /* Enable the UI Xilinx */
00462     edt_intfc_write(edt_p, 2, 0x00);       /* Enable the 16TE3 LIU output ports */
00463 
00464 
00465     /* reset tdk78p2344 and the turn off data */
00466     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_3);
00467 
00468 
00469     /* hardware reset lxt3108 and the rest of the interface chip */
00470     edt_reg_write(edt_p, PCD_CMD, 0);
00471     edt_msleep(1); /* reset low for a while */
00472     /* unreset chip and lxt3108 */
00473     edt_reg_write(edt_p, PCD_CMD, 0x8);
00474 
00475 
00476     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_16TE3_SEL_3);
00477     edt_reg_write(edt_p, TDK78P2344_CTL, TDK78P2344_ENABLE); 
00478 
00479 
00480     /* enable the data */
00481     edt_reg_write(edt_p, TDK78P2344_EN_D_0, TDK78P2344_ENCH); 
00482     edt_reg_write(edt_p, TDK78P2344_EN_D_1, TDK78P2344_ENCH); 
00483 
00484 
00485     los =  TDK78P2344_LOS_0 + 3;
00486     sdo =  TDK78P2344_16TE3_SDO;
00487 
00488     edt_16te3_set_chip(edt_p, 3);
00489 
00490     mscr = edt_read_78p2344_reg(edt_p, 0, TDK78P2344_MSCR, los, sdo);
00491 
00492     mdcr = edt_read_78p2344_reg(edt_p, 3+1, TDK78P2344_MDCR, los, sdo);
00493 
00494     if (mscr = 0x20 && mdcr == 0x21)
00495     {
00496         return 1;
00497     }
00498 
00499     return 0;
00500 
00501 }

Generated on 19 Jun 2015 by  doxygen 1.4.7