00001 /***************************************************************************** 00002 * 00003 * File: llprotocol.h 00004 * 00005 * $RCSfile: llprotocol.h,v $ 00006 * 00007 * Copyright (C) 2001 D-TACQ Solutions Ltd 00008 * not to be used without owner's permission 00009 * 00010 * Description: interface to acq32, implements part of mbox protocol 00011 * 00012 * $Id: llprotocol.h,v 1.10.2.16 2006/01/15 11:18:18 pgm Exp $ 00013 * $Log: llprotocol.h,v $ 00014 * Revision 1.10.2.16 2006/01/15 11:18:18 pgm 00015 * SYNC_2V 00016 * 00017 * Revision 1.10.2.15 2005/11/04 17:26:18 pgm 00018 * *** empty log message *** 00019 * 00020 * Revision 1.10.2.14 2005/09/25 20:32:34 pgm 00021 * LLCV2 initial poll corrected 00022 * 00023 * Revision 1.10.2.13 2005/08/12 09:51:25 pgm 00024 * *** empty log message *** 00025 * 00026 * Revision 1.10.2.12 2005/08/11 10:02:24 pgm 00027 * SYNC_ECM - init host side slave memory areas 00028 * 00029 * Revision 1.10.2.11 2005/08/01 11:10:24 pgm 00030 * V2 part 1 running - local status, no hbpoll - ECM 100 acheived 00031 * 00032 * Revision 1.10.2.10 2004/12/09 12:58:34 pgm 00033 * various attempts at repartitioning for speed 00034 * 00035 * Revision 1.10.2.9 2004/11/14 09:50:44 pgm 00036 * Doxygen type docs 00037 * 00038 * Revision 1.10.2.8 2004/11/04 07:13:13 pgm 00039 * merged multicard case 00040 * 00041 * Revision 1.10.2.7.2.2 2004/09/26 11:32:39 pgm 00042 * multiboard tstats pollstats in 00043 * 00044 * Revision 1.10.2.7.2.1 2004/09/25 09:08:31 pgm 00045 * first UI/test split 00046 * 00047 * Revision 1.10.2.7 2004/09/15 12:48:21 pgm 00048 * use internal var for llWaitDmaDone, reformat 00049 * 00050 * Revision 1.10.2.6 2004/08/10 07:35:46 pgm 00051 * works with ACQ196 00052 * 00053 * Revision 1.10.2.5 2004/07/31 21:48:25 pgm 00054 * now with Feedback - but why does it plot backwards\/ 00055 * 00056 * Revision 1.10.2.4 2004/07/27 20:49:06 pgm 00057 * llcontrol 2G with AO - in debug 00058 * 00059 * Revision 1.10.2.3 2004/07/25 20:39:38 pgm 00060 * hbpolling, 96 channels 00061 * 00062 * Revision 1.10.2.2 2003/12/12 14:51:20 pgm 00063 * UPDATE DACS HACK 00064 * 00065 * Revision 1.10.2.1 2003/11/11 10:11:21 pgm 00066 * fudge LLC SET DAC 00067 * 00068 * Revision 1.10 2003/07/03 11:15:21 pgm 00069 * set dacs 00070 * 00071 * Revision 1.9 2002/09/02 11:01:18 pgm 00072 * revised debug levels 00073 * 00074 * Revision 1.8 2002/08/29 13:22:21 pgm 00075 * better docs 00076 * 00077 * Revision 1.7 2002/03/12 15:37:52 pgm 00078 * emacs format rools OK 00079 * 00080 * Revision 1.6 2001/08/23 20:00:50 pgm 00081 * mod protocol avoids races and works 00082 * 00083 * Revision 1.5 2001/08/17 07:25:38 pgm 00084 * ll, aync update, has race 00085 * 00086 * Revision 1.4 2001/05/25 12:05:15 pgm 00087 * its a runner - shippit quick 00088 * 00089 * Revision 1.3 2001/05/21 20:43:29 pgm 00090 * *** empty log message *** 00091 * 00092 * Revision 1.2 2001/05/21 17:50:36 pgm 00093 * reform again 00094 * 00095 * Revision 1.1 2001/05/21 17:42:38 pgm 00096 * reformed 00097 * 00098 * Revision 1.5 2001/05/20 21:24:10 pgm 00099 * first entry to cvs 00100 * 00101 * 00102 \*****************************************************************************/ 00103 00104 00105 /** @file llprotocol.h API for bus level protocol. */ 00106 00107 #ifndef __LLPROTOCOL_H__ 00108 #define __LLPROTOCOL_H__ 00109 00110 /* this is a HACK - need local copy of acq32busprot.h */ 00111 #define BP_MB_LLC_UPDATEDAC 1 00112 #define LLC_CSR_M_UPDATEDACS 'f' 00113 00114 /******************************************************************************* 00115 * Use these functions to enter Low Latency Mode 00116 */ 00117 00118 int enterLLCSoftClock( 00119 struct MU* m, int clkpos, int trpos, 00120 int internal_loopback, 00121 u32 command_mods); 00122 /* 00123 * Enter LowLatency Mode for SOFT CLOCK capture 00124 */ 00125 00126 int enterLLCExtClock( 00127 struct MU* m, int clkpos, int trpos, 00128 unsigned short divisor, 00129 int internal_loopback, 00130 u32 command_mods 00131 ); 00132 /** 00133 * Enter LowLatency Mode for EXTERNAL CLOCK capture 00134 */ 00135 00136 int enterLLC_SYNC_ECM( 00137 struct MU* m, int clkpos, int trpos, 00138 unsigned short divisor, 00139 int internal_loopback, 00140 u32 command_mods, 00141 u32 init_buf_baddr 00142 ); 00143 /******************************************************************************* 00144 * Now use these functions while in Low Latency Mode 00145 */ 00146 00147 00148 00149 00150 int leaveLLC( struct MU* m ); 00151 /* 00152 * Leave LowLatency Mode 00153 */ 00154 00155 #include <setjmp.h> 00156 extern sigjmp_buf G_env; 00157 00158 00159 static inline u32 llPollSack( struct MU* m ) 00160 // return 0 on SACK, exit on SNACK 00161 // private: not used outside this module 00162 { 00163 u32 status = pollMboxBits( 00164 m, BP_MB_LLC_CSR, LLC_CSR_SACK|LLC_CSR_SNACK, LLC_CSR_SACK); 00165 00166 if ((status&LLC_CSR_SNACK) != 0){ 00167 siglongjmp(G_env, status); 00168 } 00169 return status; 00170 } 00171 static inline u32 llGetCsr( struct MU* m ) 00172 // private: not used outside this module 00173 { 00174 return getMbox( m, BP_MB_LLC_CSR ); 00175 } 00176 00177 00178 /* Sending commands to the board - the following command codes apply (copy from acq32busprot.h) 00179 00180 * LLC LLC LLC LLC LLC LLC LLC 00181 * 00182 * Low Latency Control Mode - works like this ... 00183 * 00184 * 00185 * prams for setup command: BP_FC_SET_MODE_LLC 00186 * A1 - prams 00187 * A3 - clock div for extclock mode 00188 00189 #define BP_FC_SET_MODE_LLC FCL // switch into Low Latency Control Mode. 00190 00191 #define BP_FC_SET_MODE_LLC_SOFTCLOCK 0x80 // EXCLUSIVE! 00192 #define BP_FC_SET_MODE_LLC_EXTCLOCK 0x40 00193 00194 #define BP_FC_SET_MODE_LLC_CLKPOL_POS 0x20 // set for rising edge active 00195 #define BP_FC_SET_MODE_LLC_TRPOL_POS 0x10 // set for rising edge active 00196 #define BP_FC_SET_RTCLOCK_TIMING 0x04 00197 00198 #define BP_FC_SET_MODE_LLC_INTSOFT_CLK 0x01 // test mode 00199 #define BP_FC_SET_MODE_LLC_INTDIV_CLK 0x02 // test mode 00200 00201 */ 00202 00203 00204 static inline u32 llSetCmd( struct MU* m, u32 cmd ) 00205 /* Send a command to the llcontrol board */ 00206 { 00207 PRINTF(4)( "llsetCmd( 0x%08x )\n", cmd ); 00208 00209 cmd &= ~( LLC_CSR_SACK|LLC_CSR_SNACK); 00210 00211 setMbox( m, BP_MB_LLC_CSR, cmd ); 00212 return llPollSack( m ); 00213 } 00214 00215 static inline void llSetAddr( struct MU* m, u32 addr, u32 cmd ) 00216 /* Set the target address and send a command to the llcontrol board */ 00217 { 00218 setMbox( m, BP_MB_LLC_DATA_ADDR, addr ); 00219 00220 00221 llSetCmd( m, LLC_CSR_M_SETADDR|cmd ); 00222 } 00223 00224 00225 static inline u32 llGetTlatch( struct MU* m ) 00226 /* Get the latch count (time at ADC clock) */ 00227 { 00228 return getMbox( m, BP_MB_LLC_TADC ); 00229 } 00230 00231 static inline int llSetTlatch( struct MU* m, u32 value ) 00232 /* Set (reset) the latch count */ 00233 { 00234 return setMbox( m, BP_MB_LLC_TADC, value ); 00235 } 00236 00237 static inline u32 llGetTinst( struct MU* m ) 00238 /* get the instantaneous count (time now) */ 00239 { 00240 return getMbox( m, BP_MB_LLC_TINST ); 00241 } 00242 00243 static inline u32 llGetTprocess( struct MU* m ) 00244 /* get the time taken by the capture process */ 00245 { 00246 return LLC_GET_TCYCLE( llGetCsr( m ) ); 00247 } 00248 00249 u32 llWaitDmaDone(struct MU* m); 00250 /** polls until DMA has completed. 00251 * Returns tlatch 00252 * guaranteed DMA done when tlatch updated 00253 */ 00254 00255 u32 llv2WaitDmaDone(struct MU *m, volatile u32* hstats); 00256 /** polls until DMA has completed. 00257 * Returns tlatch 00258 * guaranteed DMA done when tlatch updated 00259 * V2 method does NOT poll PCI 00260 */ 00261 00262 u32 llv2WaitDmaDone_2v(struct MU *m, volatile u32* hstats, unsigned tlatch); 00263 /** polls until DMA has completed. 00264 * Returns tlatch 00265 * guaranteed DMA done when tlatch updated 00266 * V2 method does NOT poll PCI 00267 */ 00268 00269 void llv2InitDmaDone(volatile u32* hstats); 00270 /** prepare (poison) target buf for incoming DMA. */ 00271 00272 00273 static inline int llCounterRunning( struct MU* m, u32 csr ) 00274 /** returns TRUE when counters are running the process has started on GATE. 00275 */ 00276 { 00277 return (llSetCmd( m, csr+LLC_CSR_M_READCTR )&LLC_CSR_S_CTR_RUN) != 0; 00278 } 00279 00280 #define DAC_COUNT 16 00281 #define DAC_SAMPLE_SIZE (DAC_COUNT*sizeof(short)) 00282 00283 00284 00285 static inline void llSetDacs( struct MU* mu, void* dacvals, char* bigbuf_base) 00286 /** 00287 * uses i2o buffer Q. 00288 - obtain a descriptor (MFA) from the target Q (1) 00289 - copy from client buffer to slave memory ref by MFA (2) 00290 - post descriptor to target Q (3) 00291 * 00292 * target is notified about the post, and uses the MFA to setup a DMA direct 00293 * from host memory to DACs. 00294 * 00295 * For MINIMUM latency 00296 - a/ split the function to mu_reserveOutbound(mu) ahead of time 00297 * (don't pre-reserve more than one .. 100 this is a limited resource 00298 - b/ eliminate the memcpy (but this is quick, regardless). 00299 */ 00300 { 00301 MFA mfa = mu_reserveOutbound(mu); /* (1) */ 00302 PRINTF(1)("llSetDacs MFA 0x%08x dst %p src %p\n", 00303 mfa, bigbuf_base+mfa, dacvals); 00304 00305 memcpy( bigbuf_base+mfa, dacvals, DAC_SAMPLE_SIZE); /* (2) */ 00306 mu_putOutbound(mu, mfa); /* (3) */ 00307 } 00308 00309 /* 00310 * same function split into parts to enable scheduling 00311 */ 00312 00313 #define DAC_BASE(bigbuf_base, mfa) ((void*)bigbuf_base + (mfa)) 00314 00315 00316 void llPrimePollHB(struct DmaBuffer *buf, int offset, int sample_len); 00317 void llPollHB(struct DmaBuffer *buf, int offset, int sample_len); 00318 00319 00320 /** V2 host buffer segmentation - for full V2, 4K is enough. */ 00321 00322 #define LLCV2_HB_OFFSET 0x00100000 /** 1M offset into 16M, backcompatibility */ 00323 00324 /** but for future, simpler host side drivers, we'd like a single 4K buf, 00325 * no offset. => use a variable and set as appropriate 00326 */ 00327 00328 extern unsigned llcv2_hb_offset; 00329 00330 #define LLCV2_AI_HSBT 0x000 00331 #define LLCV2_AO_HSBS 0x400 00332 #define LLCV2_DO_HSBS 0x800 00333 #define LLCV2_STATUS_HSBT 0xc000 00334 00335 #define LLCV2_OFFSET_AI_HSBT (llcv2_hb_offset+LLCV2_AI_HSBT) 00336 #define LLCV2_OFFSET_AO_HSBS (llcv2_hb_offset+LLCV2_AO_HSBS) 00337 #define LLCV2_OFFSET_DO_HSBS (llcv2_hb_offset+LLCV2_DO_HSBS) 00338 #define LLCV2_OFFSET_STATUS_HSBT (llcv2_hb_offset+LLCV2_STATUS_HSBT) 00339 00340 u32 llv2_extend32(u32 old32, u32 new12); 00341 #endif