00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <linux/kernel.h>
00031 #include <math.h>
00032 #include "include/dsp-pci32/spa/spacmd.h"
00033
00034
00035 #define BB_TEST_CNT // Test ChanneltronCounting on startup 0.1-100ms
00036 #define BB_POLLING_MODE // use polling Mode for Gate, else use IRQ
00037
00038
00039
00040 #define BB_MEM_BASE 0xd0000
00041
00042 #define BB_MEM_AUTOPROBE 0
00043 #define BB_MEM_BASE_START 0xc0000
00044 #define BB_MEM_BASE_END 0xe0000
00045 #define BB_MEM_SIZE 0x400
00046 #define BB_IRQLINE 5
00047
00048 #define BB_XY_DEFLECTON_BOARD 3
00049 #define BB_ENERGY_BOARD 1
00050
00051
00052
00053 #define BB_PCI20001C1 (0x1+0x2+0x8+0x10)
00054 #define BB_PCI20001C2 (0x1+0x4+0x8+0x10)
00055 #define BB_IDMSK 0x1f
00056
00057 #define BB_PCI20006M2 0xe2 // Analog Output 16bit single channel DAC
00058 #define BB_PCI20006M3 0xe3 // Analog Output 16bit two channel DAC
00059 #define BB_PCI20007M 0xea // Counter, Timer, Puls
00060
00061 #define BB_BASE_MODULE(N) ( spa[BB_CARD_NO].BB_membase + (((N)&3)<<8) )
00062
00063 #define BB_MODULE_PRESENT(M) (readb( BB_BASE_MODULE(0) ) & (1<<(8-(M))))
00064 #define BB_IRQ_STATUS readb( BB_BASE_MODULE(0) + 0x40 )
00065
00066
00067
00068
00069
00070 #define BB_DAC_X(X,N) writew( (X), BB_BASE_MODULE(N) + 0x0d)
00071 #define BB_DAC_Y(X,N) writew( (X), BB_BASE_MODULE(N) + 0x15)
00072 #define BB_DAC_OUT(N) writeb(0xff, BB_BASE_MODULE(N) + 0x1b)
00073
00074
00075 #define BB_TMR_MODULE_ID 2
00076
00077 #define BB_TMR_BASE ( BB_BASE_MODULE(BB_TMR_MODULE_ID) )
00078 #define BB_TMR_RTGREG ( BB_TMR_BASE + 0x04 ) // BB TimerCounter Module Base Address
00079 #define BB_TMR_RTGREG_LO ( BB_TMR_RTGREG ) // 0x04 Rate Generator count Reg. low 16, (rw)
00080 #define BB_TMR_RTGREG_HI ( BB_TMR_RTGREG + 1) // 0x05 Rate Generator count Reg. hi 16, (rw)
00081
00082 #define BB_TMR_CNT0REG ( BB_TMR_BASE + 0x08 ) // Counter 0 count register (rw)
00083 #define BB_TMR_CNT1REG ( BB_TMR_BASE + 0x09 ) // Counter 1 count register (rw)
00084 #define BB_TMR_CNT2REG ( BB_TMR_BASE + 0x0A ) // Counter 2 count register (rw)
00085 #define BB_TMR_CNT3REG ( BB_TMR_BASE + 0x06 ) // Counter 3 count register (rw)
00086
00087 #define BB_TMR_RTGCNT3CTRL ( BB_TMR_BASE + 0x07 ) // Rate Generator and Counter 3 control register (w)
00088 #define BB_TMR_CNT012CTRL ( BB_TMR_BASE + 0x0B ) // Counter 0,1,2 control register (w)
00089 #define BB_TMR_CNTGATECTRL ( BB_TMR_BASE + 0x0C ) // Counter gate control (w)
00090
00091 #define BB_CRTL_MSK 0x40
00092
00093 typedef struct{
00094 short lb0;
00095 short hb0;
00096 short lb1;
00097 short hb1;
00098 } BB_GATEGEN;
00099
00100 #ifdef BB_TEST_CNT
00101 static int irq_count=0;
00102 static int timeout_count=0;
00103 #endif
00104
00105
00106
00107
00108 #define AD_MAX_VOLT 10.
00109 #define DA_MAX_VOLT 10.
00110 #define DA_MAX_VAL 0x7ffe
00111 #define UDA_MAX_VAL 0xffff
00112
00113
00114
00115 #define U2FLT(X) ((X)*(float)(DA_MAX_VAL)/AD_MAX_VOLT)
00116 #define U2INT(X) (int)((X)*(float)(DA_MAX_VAL)/AD_MAX_VOLT)
00117 #define INT2U(X) ((float)(X)/DA_MAX_VAL*AD_MAX_VOLT)
00118
00119
00120 #define UNI_U2FLT(X) ((X)*(float)(UDA_MAX_VAL)/AD_MAX_VOLT)
00121 #define UNI_U2INT(X) (int)((X)*(float)(UDA_MAX_VAL)/AD_MAX_VOLT)
00122 #define UNI_INT2U(X) ((float)(X)/UDA_MAX_VAL*AD_MAX_VOLT)
00123
00124
00125 #define DPRAMBASE (volatile int*) (spa[BB_CARD_NO].dsp->virtual_dpram)
00126
00127 #define CMD_BUFFER (volatile int*) (DPRAMBASE+0x00)
00128 #define CMD_PARM (volatile int*) (DPRAMBASE+0x01)
00129 #define BUFFER (volatile int*) (DPRAMBASE+DSP_BUFFER_START)
00130 #define BUFFERL (volatile unsigned long*) (DPRAMBASE+DSP_BUFFER_START)
00131 #define DPRAML (volatile unsigned long*) (DPRAMBASE)
00132 #define LCDBUFFER (volatile unsigned long*) (DPRAMBASE+DSP_LCDBUFFER)
00133 #define MAXSCANPOINTS (DSP_DATA_REG_LEN)
00134
00135 #define DSPack spa[BB_CARD_NO].dsp->SrvReqAck=TRUE
00136
00137 #define MD_CMD 0x08
00138 #define MD_SCAN 0x10
00139 #define MD_BLK 0x80
00140
00141 #define LEDPORT(X) *((unsigned long*)(DPRAMBASE+DSP_USR_DIO))=X
00142
00143 void LCDclear(void);
00144 int LCDprintf(const char *format, ...);
00145
00146 void scan2d(void);
00147 void linescan(int n, float y);
00148
00149 unsigned long ChanneltronCounts(float x, float y);
00150
00151 int GetParamI(unsigned int N);
00152 float GetParamF(unsigned int N);
00153
00154 void BB_SetVolt(double x, double y);
00155 void BB_SetEnergy(double En);
00156 unsigned long BB_CntRead(void);
00157 double BB_InitCnt(double gate);
00158 void BB_SetCnt(void);
00159 int BB_ReadyCnt(void);
00160
00161 static void bb_gate_interrupt(int irq, void *dev_id, struct pt_regs *regs);
00162
00163 #define MAX_BB_CARDS 1
00164 #define BB_CARD_NO 0
00165
00166 typedef struct{
00167 float ms;
00168 float X0, Y0;
00169 float len;
00170 int N;
00171 int Nx,Ny;
00172 float lenxy;
00173 float alpha, alphaAlt;
00174 float E;
00175 double rotmxx, rotmyy, rotmxy, rotmyx, rotoffx, rotoffy;
00176 } SCANP;
00177
00178 typedef struct{
00179 struct dspsim_thread_data *dsp;
00180 SCANP scanp;
00181
00182 BB_GATEGEN bb_gate_reg;
00183
00184 char *BB_membase;
00185 unsigned char bbid;
00186 unsigned char bbmodid[3];
00187
00188 int major, minor;
00189 int bb_irq;
00190 wait_queue_head_t waitq;
00191 struct timer_list timeout_tmr;
00192 unsigned long bb_timeout_flg;
00193
00194 int LastSPAMode;
00195 int SPAMode;
00196
00197 double extractor;
00198 double chanhv;
00199 double chanrepeller;
00200 double cryfocus;
00201 double filament, expfilament;
00202 double gunfocus;
00203 double gunanode;
00204 double smpdist;
00205 double smptemp;
00206 double S,d,ctheta,sens;
00207 double growing;
00208 } SPALEED;
00209
00210 static SPALEED spa[MAX_BB_CARDS];
00211
00212
00213 #ifdef BB_TEST_CNT
00214 void bb_test_counting(double E, double ms){
00215 unsigned long n;
00216 BB_SetEnergy(E);
00217 ms=BB_InitCnt(ms);
00218 spa[BB_CARD_NO].scanp.ms = ms;
00219 KDEBUG("BB_SPA: irqcount %d, tmoutcount: %d\n", irq_count, timeout_count);
00220 n=jiffies;
00221 KDEBUG("BB_SPA: Testing, %d/10ms, Cnt(0,0)=%d\n",(int)(ms*10.), (int)ChanneltronCounts(0., 0.));
00222 n=jiffies-n;
00223 KDEBUG("BB_SPA: irqcount %d, tmoutcount: %d jiffies: %d\n", irq_count, timeout_count, (int)n);
00224 }
00225 #endif
00226
00227 int InitEmu(struct dspsim_thread_data *dsp){
00228 int err=0;
00229 int i;
00230
00231
00232 KDEBUG("BurrBrow PCI20001CX module\nBB auto detection: %d\n", BB_MEM_AUTOPROBE );
00233
00234 spa[BB_CARD_NO].dsp = dsp;
00235 spa[BB_CARD_NO].major = PCDSP_MAJOR;
00236 spa[BB_CARD_NO].minor = BB_CARD_NO;
00237
00238 spa[BB_CARD_NO].BB_membase = (unsigned char*)BB_MEM_BASE;
00239
00240 switch( spa[BB_CARD_NO].bbid = (readb( BB_BASE_MODULE(0) ) & BB_IDMSK) ){
00241 case BB_PCI20001C1: KDEBUG("BB carrier PCI20001C1 found\n"); break;
00242 case BB_PCI20001C2: KDEBUG("BB carrier PCI20001C2 found\n"); break;
00243 default: KDEBUG("no BB found at %x, id=%x. Trying to autodetect.\n",
00244 (int)spa[BB_CARD_NO].BB_membase, spa[BB_CARD_NO].bbid); err=1; break;
00245 }
00246
00247 if( err && BB_MEM_AUTOPROBE )
00248 for(spa[BB_CARD_NO].BB_membase = (unsigned char*)BB_MEM_BASE_START;
00249 err && (unsigned long)(spa[BB_CARD_NO].BB_membase) < BB_MEM_BASE_END; spa[BB_CARD_NO].BB_membase += BB_MEM_SIZE)
00250 switch( spa[BB_CARD_NO].bbid = (readb( BB_BASE_MODULE(0) ) & BB_IDMSK) ){
00251 case BB_PCI20001C1: KDEBUG("BB carrier PCI20001C1 found\n"); err=0; break;
00252 case BB_PCI20001C2: KDEBUG("BB carrier PCI20001C2 found\n"); err=0; break;
00253 default: continue;
00254 }
00255
00256 if(err){
00257 spa[BB_CARD_NO].BB_membase = (unsigned char*)BB_MEM_BASE;
00258 KDEBUG("Error: BB SPA-LEED module can't find BB card.\n" );
00259 return 1;
00260 }
00261 else
00262 KDEBUG("BB SPA-LEED module, BB baseaddr: %x\n", (int)spa[BB_CARD_NO].BB_membase );
00263
00264 for(i=0; i<3; ++i){
00265 spa[BB_CARD_NO].bbmodid[i]=0;
00266 if( BB_MODULE_PRESENT(i+1) == 0 )
00267 switch( (spa[BB_CARD_NO].bbmodid[i] = readb( BB_BASE_MODULE(i+1) )) ){
00268 case BB_PCI20006M2: KDEBUG("BB module %d is a PCI20006M, single DAC 16bit\n", i+1); break;
00269 case BB_PCI20006M3: KDEBUG("BB module %d is a PCI20006M, two DAC 16bit\n", i+1); break;
00270 case BB_PCI20007M: KDEBUG("BB module %d is a PCI20007M, Counter, Timer, Puls\n", i+1); break;
00271 default: KDEBUG("unknown BB module with id=%x found\n", spa[BB_CARD_NO].bbmodid[i]); break;
00272 }
00273 else
00274 KDEBUG("BB module is %d not present.\n", i+1);
00275 }
00276
00277 init_waitqueue_head(&spa[BB_CARD_NO].waitq);
00278 spa[BB_CARD_NO].bb_irq = request_irq(BB_IRQLINE,
00279 bb_gate_interrupt,
00280 0,
00281 PCDSP_DEVICE_NAME,
00282 NULL );
00283
00284
00285 KDEBUG("requested irq is %d, id=%d\n", BB_IRQLINE, spa[BB_CARD_NO].bb_irq );
00286 KDEBUG("BB Irq Status is: %x\n", BB_IRQ_STATUS );
00287 KDEBUG("BB detection OK.\n" );
00288
00289
00290 *CMD_BUFFER=0;
00291 spa[BB_CARD_NO].LastSPAMode = spa[BB_CARD_NO].SPAMode = MD_CMD;
00292 LCDclear();
00293 LCDprintf("-* DSP Emu *-");
00294 LEDPORT(spa[BB_CARD_NO].SPAMode);
00295
00296 spa[BB_CARD_NO].scanp.rotmxx = spa[BB_CARD_NO].scanp.rotmyy = 1.;
00297 spa[BB_CARD_NO].scanp.rotmxy = spa[BB_CARD_NO].scanp.rotmyx
00298 = spa[BB_CARD_NO].scanp.rotoffx = spa[BB_CARD_NO].scanp.rotoffy = 0.;
00299
00300 spa[BB_CARD_NO].scanp.ms = 1.;
00301 spa[BB_CARD_NO].scanp.X0 = spa[BB_CARD_NO].scanp.Y0 = 0.;
00302 spa[BB_CARD_NO].scanp.Nx = spa[BB_CARD_NO].scanp.Ny = 40;
00303 spa[BB_CARD_NO].scanp.N = 100;
00304 spa[BB_CARD_NO].scanp.len = 100.;
00305 spa[BB_CARD_NO].scanp.lenxy = 100.;
00306 spa[BB_CARD_NO].scanp.E = 1.;
00307
00308 spa[BB_CARD_NO].scanp.alpha = spa[BB_CARD_NO].scanp.alphaAlt = 0.;
00309
00310 spa[BB_CARD_NO].extractor = 0.5;
00311 spa[BB_CARD_NO].chanhv = 2000.0;
00312 spa[BB_CARD_NO].chanrepeller = 1.0;
00313 spa[BB_CARD_NO].cryfocus = 0.5;
00314 spa[BB_CARD_NO].filament = 2.4;
00315 spa[BB_CARD_NO].gunfocus = 0.5;
00316 spa[BB_CARD_NO].gunanode = 1.1;
00317 spa[BB_CARD_NO].smpdist = 20.;
00318 spa[BB_CARD_NO].smptemp = 300.;
00319 spa[BB_CARD_NO].sens = 100.;
00320 spa[BB_CARD_NO].d = 3.141;
00321 spa[BB_CARD_NO].ctheta = 0.996155128;
00322 spa[BB_CARD_NO].S = 1.;
00323 spa[BB_CARD_NO].growing = 0.;
00324
00325 #ifdef BB_TEST_CNT
00326 bb_test_counting(1., 0.1);
00327 bb_test_counting(1., 0.5);
00328 bb_test_counting(1., 1.0);
00329 bb_test_counting(1., 5.0);
00330 bb_test_counting(1., 10.0);
00331 bb_test_counting(1., 50.0);
00332 bb_test_counting(1., 100.0);
00333 bb_test_counting(1., 500.0);
00334 spa[BB_CARD_NO].scanp.ms = 1.;
00335 #endif
00336
00337 return 0;
00338 }
00339
00340 void ExitEmu(void){
00341 KDEBUG("BB cleanup\n");
00342 #ifdef BB_TEST_CNT
00343 KDEBUG("BB_SPA: irqcount %d, tmoutcount: %d\n", irq_count, timeout_count);
00344 #endif
00345 free_irq(BB_IRQLINE, NULL);
00346 }
00347
00348 int GetParamI(unsigned int N){
00349 float *ptr = (float*)(CMD_PARM + N);
00350 return (int)(*ptr);
00351
00352 }
00353
00354 float GetParamF(unsigned int N){
00355 float *ptr = (float*)(CMD_PARM + N);
00356 return *ptr;
00357 }
00358
00359 void LCDclear(void){
00360 int n;
00361 for(n=0; n < DSP_LCDBUFFERLEN;)
00362 *(LCDBUFFER+n++) = ' ';
00363 }
00364
00365 int LCDprintf(const char *format, ...){
00366 va_list ap;
00367 int nr_of_chars;
00368 va_start (ap, format);
00369 nr_of_chars = vsprintf ((char*)LCDBUFFER, format, ap);
00370 va_end (ap);
00371 return (nr_of_chars);
00372 }
00373
00374 void ServiceRequest(struct dspsim_thread_data *dsp){
00375 switch(*CMD_BUFFER & 0xff){
00376
00377 case DSP_CMD_SCAN_PARAM:
00378 spa[BB_CARD_NO].scanp.X0 = GetParamF(DSP_X0);
00379 spa[BB_CARD_NO].scanp.Y0 = GetParamF(DSP_Y0);
00380 spa[BB_CARD_NO].scanp.len = GetParamF(DSP_len);
00381 spa[BB_CARD_NO].scanp.N = GetParamI(DSP_N);
00382 spa[BB_CARD_NO].scanp.alpha = GetParamF(DSP_alpha);
00383 spa[BB_CARD_NO].scanp.ms = GetParamF(DSP_ms);
00384 spa[BB_CARD_NO].scanp.E = GetParamF(DSP_E);
00385
00386 spa[BB_CARD_NO].scanp.rotmxx = GetParamF(DSP_MXX);
00387 spa[BB_CARD_NO].scanp.rotmxy = GetParamF(DSP_MXY);
00388 spa[BB_CARD_NO].scanp.rotmyx = GetParamF(DSP_MYX);
00389 spa[BB_CARD_NO].scanp.rotmyy = GetParamF(DSP_MYY);
00390
00391 spa[BB_CARD_NO].scanp.rotoffx = spa[BB_CARD_NO].scanp.X0;
00392 spa[BB_CARD_NO].scanp.rotoffy = spa[BB_CARD_NO].scanp.Y0;
00393 BB_SetVolt(0., 0.);
00394 BB_SetEnergy(spa[BB_CARD_NO].scanp.E);
00395 DSPack;
00396 break;
00397
00398 case DSP_CMD_SPACTRL_SET:
00399 spa[BB_CARD_NO].extractor = GetParamF(DSP_SPACTRL_EXTRACTOR);
00400 spa[BB_CARD_NO].chanhv = GetParamF(DSP_SPACTRL_CHANHV);
00401 spa[BB_CARD_NO].chanrepeller = GetParamF(DSP_SPACTRL_CHANREPELLER);
00402 spa[BB_CARD_NO].cryfocus = GetParamF(DSP_SPACTRL_CRYFOCUS);
00403 spa[BB_CARD_NO].filament = GetParamF(DSP_SPACTRL_FILAMENT);
00404 spa[BB_CARD_NO].gunfocus = GetParamF(DSP_SPACTRL_GUNFOCUS);
00405 spa[BB_CARD_NO].gunanode = GetParamF(DSP_SPACTRL_GUNANODE);
00406 spa[BB_CARD_NO].smpdist = GetParamF(DSP_SPACTRL_SMPDIST);
00407 spa[BB_CARD_NO].smptemp = GetParamF(DSP_SPACTRL_SMPTEMP);
00408 spa[BB_CARD_NO].growing = GetParamF(DSP_SPACTRL_GROWING);
00409 DSPack;
00410 break;
00411
00412 case DSP_CMD_SCAN_START:
00413 spa[BB_CARD_NO].scanp.len = GetParamF(DSP_len);
00414 spa[BB_CARD_NO].scanp.E = GetParamF(DSP_E);
00415
00416 spa[BB_CARD_NO].LastSPAMode = spa[BB_CARD_NO].SPAMode;
00417 spa[BB_CARD_NO].SPAMode = (spa[BB_CARD_NO].SPAMode & ~(MD_CMD)) | MD_SCAN;
00418 linescan(0, GetParamF(DSP_Y0));
00419 spa[BB_CARD_NO].SPAMode = spa[BB_CARD_NO].LastSPAMode;
00420 DSPack;
00421 break;
00422
00423 case DSP_CMD_SWAPDPRAM:
00424 DSPack;
00425 break;
00426
00427 case DSP_CMD_SCAN2D:
00428 spa[BB_CARD_NO].scanp.Nx = GetParamI(DSP_NX);
00429 spa[BB_CARD_NO].scanp.Ny = GetParamI(DSP_NY);
00430 spa[BB_CARD_NO].scanp.lenxy = GetParamF(DSP_LXY);
00431 spa[BB_CARD_NO].LastSPAMode = spa[BB_CARD_NO].SPAMode;
00432 spa[BB_CARD_NO].SPAMode = (spa[BB_CARD_NO].SPAMode & ~(MD_CMD)) | MD_SCAN;
00433 scan2d();
00434 spa[BB_CARD_NO].SPAMode = spa[BB_CARD_NO].LastSPAMode;
00435 DSPack;
00436 break;
00437
00438 case DSP_CMD_GETCNT:
00439 spa[BB_CARD_NO].scanp.ms = GetParamF(DSP_ms);
00440 spa[BB_CARD_NO].scanp.E = GetParamF(DSP_E);
00441
00442 spa[BB_CARD_NO].scanp.ms = BB_InitCnt(spa[BB_CARD_NO].scanp.ms);
00443 BB_SetEnergy(spa[BB_CARD_NO].scanp.E);
00444
00445 *(BUFFERL) = ChanneltronCounts(0., 0.);
00446
00447 DSPack;
00448 break;
00449
00450 default: break;
00451 }
00452 REQD_DSP = FALSE;
00453 }
00454
00455 void scan2d(void){
00456 double x,y,Ux, dUx, Uy, dUy;
00457 int i,j,k;
00458 if(spa[BB_CARD_NO].scanp.Nx > 1)
00459 Ux = -spa[BB_CARD_NO].scanp.lenxy/2.;
00460 else
00461 Ux = 0.;
00462 dUx = spa[BB_CARD_NO].scanp.lenxy/spa[BB_CARD_NO].scanp.Nx;
00463
00464 if(spa[BB_CARD_NO].scanp.Ny > 1)
00465 Uy = spa[BB_CARD_NO].scanp.lenxy/2.;
00466 else
00467 Uy = 0.;
00468 dUy = spa[BB_CARD_NO].scanp.lenxy/spa[BB_CARD_NO].scanp.Ny;
00469
00470 spa[BB_CARD_NO].scanp.ms = BB_InitCnt(spa[BB_CARD_NO].scanp.ms);
00471 BB_SetEnergy(spa[BB_CARD_NO].scanp.E);
00472
00473 for(y=Uy, k=j=0; j<spa[BB_CARD_NO].scanp.Ny; j++, y-=dUy){
00474 BB_SetVolt(Ux, y);
00475 mysleep(3);
00476 for(x=Ux, i=0; i<spa[BB_CARD_NO].scanp.Nx; i++, k++, x+=dUx){
00477 if( k >= MAXSCANPOINTS )
00478 return;
00479 *(BUFFERL + k) = ChanneltronCounts(x, y);
00480 }
00481 }
00482 }
00483
00484 void linescan(int n, float y){
00485 float x, dx;
00486 int nmax;
00487 nmax = n + spa[BB_CARD_NO].scanp.N + 4;
00488 if( nmax > MAXSCANPOINTS )
00489 nmax = MAXSCANPOINTS;
00490
00491 dx = spa[BB_CARD_NO].scanp.len/(float)spa[BB_CARD_NO].scanp.N;
00492 x = -spa[BB_CARD_NO].scanp.len/2.;
00493
00494 spa[BB_CARD_NO].scanp.ms = BB_InitCnt(spa[BB_CARD_NO].scanp.ms);
00495 BB_SetEnergy(spa[BB_CARD_NO].scanp.E);
00496 BB_SetVolt(x, y);
00497 mysleep(3);
00498 for(; n<nmax; n++, x+=dx)
00499 *(BUFFERL + n) = ChanneltronCounts(x, y);
00500 }
00501
00502 #ifndef BB_POLLING_MODE
00503 static void bb_irq_timeout(unsigned long data){
00504 SPALEED *thisspa = &spa[data];
00505 ++thisspa->bb_timeout_flg;
00506 wake_up_interruptible( &thisspa->waitq );
00507 #ifdef BB_TEST_CNT
00508 ++timeout_count;
00509 #endif
00510 }
00511 #endif
00512
00513 #define MAKE_MY_TIMEOUT_TMR(tmr) \
00514 struct timer_list tmr; \
00515 init_timer(&tmr); \
00516 tmr.function = timeout; \
00517 tmr.data = 0
00518
00519
00520 unsigned long ChanneltronCounts(float x, float y){
00521
00522 #ifdef BB_POLLING_MODE
00523
00524 MAKE_MY_TIMEOUT_TMR(timeout_tmr);
00525
00526 BB_SetVolt(x, y);
00527 BB_SetCnt();
00528
00529 if(spa[BB_CARD_NO].scanp.ms > 12.)
00530 mysleep( (unsigned long) (spa[BB_CARD_NO].scanp.ms/10.) );
00531 else{
00532 wakeups=1000;
00533 while( BB_ReadyCnt() && --wakeups);
00534 if( ! BB_ReadyCnt() )
00535 return BB_CntRead();
00536 }
00537
00538 wakeups=0;
00539 while( BB_ReadyCnt() && wakeups < 100){
00540 del_timer(&timeout_tmr);
00541 timeout_tmr.expires = jiffies + 1;
00542 add_timer(&timeout_tmr);
00543 interruptible_sleep_on( &waitq );
00544 wakeups++;
00545 }
00546
00547 #else
00548 # ifdef bboldtestversion
00549
00550
00551 BB_SetVolt(x, y);
00552 BB_SetCnt();
00553
00554
00555 init_timer( &spa[BB_CARD_NO].timeout_tmr );
00556 spa[BB_CARD_NO].timeout_tmr.expires = jiffies + 1 + (unsigned long)(spa[BB_CARD_NO].scanp.ms/10.) ;
00557 spa[BB_CARD_NO].timeout_tmr.data = BB_CARD_NO;
00558 spa[BB_CARD_NO].timeout_tmr.function = bb_irq_timeout;
00559 spa[BB_CARD_NO].bb_timeout_flg = 0;
00560 add_timer( &spa[BB_CARD_NO].timeout_tmr );
00561
00562 sti();
00563 interruptible_sleep_on( &spa[BB_CARD_NO].waitq );
00564 cli();
00565
00566 del_timer( &spa[BB_CARD_NO].timeout_tmr );
00567 # else
00568 DECLARE_WAITQUEUE(wait, current);
00569 unsigned long data;
00570 ssize_t retval;
00571
00572 BB_SetVolt(x, y);
00573 BB_SetCnt();
00574
00575 add_wait_queue(&spa[BB_CARD_NO].waitq, &wait);
00576 current->state = TASK_INTERRUPTIBLE;
00577
00578 schedule();
00579 # endif
00580 #endif
00581 if( ! BB_ReadyCnt() )
00582 return BB_CntRead();
00583 else
00584 return 13;
00585 }
00586
00587
00588
00589
00590
00591 void BB_SetVolt(double x, double y){
00592 double xt,yt;
00593 xt = x*spa[BB_CARD_NO].scanp.rotmxx + y*spa[BB_CARD_NO].scanp.rotmxy
00594 + spa[BB_CARD_NO].scanp.rotoffx;
00595 yt = x*spa[BB_CARD_NO].scanp.rotmyx + y*spa[BB_CARD_NO].scanp.rotmyy
00596 + spa[BB_CARD_NO].scanp.rotoffy;
00597
00598 BB_DAC_X( (int)(xt), BB_XY_DEFLECTON_BOARD );
00599 BB_DAC_Y( (int)(yt), BB_XY_DEFLECTON_BOARD );
00600 BB_DAC_OUT( BB_XY_DEFLECTON_BOARD );
00601 }
00602
00603
00604 void BB_SetEnergy(double En){
00605 BB_DAC_X( U2INT(En), BB_ENERGY_BOARD );
00606 BB_DAC_Y( U2INT(En), BB_ENERGY_BOARD );
00607 BB_DAC_OUT( BB_ENERGY_BOARD );
00608 }
00609
00610 unsigned long BB_CntRead(void){
00611 unsigned long lb0, hb0, lb1, hb1, cnt, stat0, stat1;
00612 writeb( 0xc6, BB_TMR_CNT012CTRL );
00613 cnt = 0;
00614
00615 stat0 = readb( BB_TMR_CNT0REG ) & BB_CRTL_MSK;
00616 lb0 = 0xff - readb( BB_TMR_CNT0REG );
00617 hb0 = 0xff - readb( BB_TMR_CNT0REG );
00618 if(stat0 == 0)
00619 cnt = (((hb0<<8) | lb0) + 1) << 16;
00620
00621 stat1 = readb( BB_TMR_CNT1REG ) & BB_CRTL_MSK;
00622 lb1 = 0xff - readb( BB_TMR_CNT1REG );
00623 hb1 = 0xff - readb( BB_TMR_CNT1REG );
00624 if(stat1 == 0){
00625 cnt |= (hb1<<8) | lb1;
00626 ++cnt;
00627 }
00628
00629 return cnt;
00630 }
00631
00632 double BB_InitCnt(double gate){
00633
00634 long n0, n1;
00635 double factor;
00636
00637 if( gate < 0.1 )
00638 factor = 1.;
00639 else
00640 if( gate < 1. )
00641 factor = 10.;
00642 else
00643 if( gate < 10. )
00644 factor = 100.;
00645 else
00646 if( gate < 100. )
00647 factor = 1000.;
00648 else
00649 factor = 10000.;
00650
00651 n1 = (long)(2.*factor);
00652 n0 = (long)(4000.*gate/factor);
00653
00654 if( n0 < 2 ){
00655 n0 = 2;
00656 gate = (double)n0 * (double)n1 / 8000.;
00657 }
00658
00659 spa[BB_CARD_NO].bb_gate_reg.lb0 = (n0&0xff);
00660 spa[BB_CARD_NO].bb_gate_reg.hb0 = ((n0>>8)&0xff);
00661 spa[BB_CARD_NO].bb_gate_reg.lb1 = (n1&0xff);
00662 spa[BB_CARD_NO].bb_gate_reg.hb1 = ((n1>>8)&0xff);
00663
00664 return gate;
00665 }
00666
00667 void BB_SetCnt(void){
00668 writeb( 0x34, BB_TMR_CNT012CTRL );
00669 writeb( 0xff, BB_TMR_CNT0REG );
00670 writeb( 0xff, BB_TMR_CNT0REG );
00671
00672 writeb( 0x74, BB_TMR_CNT012CTRL );
00673 writeb( 0xff, BB_TMR_CNT1REG );
00674 writeb( 0xff, BB_TMR_CNT1REG );
00675
00676 writeb( 0x34, BB_TMR_RTGCNT3CTRL );
00677 writeb( spa[BB_CARD_NO].bb_gate_reg.lb0, BB_TMR_RTGREG_LO );
00678 writeb( spa[BB_CARD_NO].bb_gate_reg.hb0, BB_TMR_RTGREG_LO );
00679
00680 writeb( 0x70, BB_TMR_RTGCNT3CTRL );
00681 writeb( spa[BB_CARD_NO].bb_gate_reg.lb1, BB_TMR_RTGREG_HI );
00682 writeb( spa[BB_CARD_NO].bb_gate_reg.hb1, BB_TMR_RTGREG_HI );
00683
00684 writeb( 0xff, BB_TMR_CNTGATECTRL );
00685
00686
00687 }
00688
00689 int BB_ReadyCnt(void){
00690 writeb( 0xe4, BB_TMR_RTGCNT3CTRL );
00691 return ( (readb(BB_TMR_RTGREG_HI) & 0x80) == 0 );
00692 }
00693
00694
00695 static void bb_gate_interrupt(int irq, void *dev_id, struct pt_regs *regs){
00696
00697 SPALEED *thisspa = &spa[BB_CARD_NO];
00698 wake_up_interruptible( &thisspa->waitq );
00699 #ifdef BB_TEST_CNT
00700 ++irq_count;
00701 #endif
00702
00703 }