![]() |
RTXI 1.3
|
00001 00024 /* 00025 00026 +-----------------------------------------------------------------------+ 00027 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier | 00028 +-----------------------------------------------------------------------+ 00029 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com | 00030 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com | 00031 +-------------------------------+---------------------------------------+ 00032 | Project : APCI-2032 | Compiler : GCC | 00033 | Module name : hwdrv_apci2032.c| Version : 2.96 | 00034 +-------------------------------+---------------------------------------+ 00035 | Project manager: Eric Stolz | Date : 02/12/2002 | 00036 +-------------------------------+---------------------------------------+ 00037 | Description : Hardware Layer Acces For APCI-2032 | 00038 +-----------------------------------------------------------------------+ 00039 | UPDATES | 00040 +----------+-----------+------------------------------------------------+ 00041 | Date | Author | Description of updates | 00042 +----------+-----------+------------------------------------------------+ 00043 | | | | 00044 | | | | 00045 | | | | 00046 +----------+-----------+------------------------------------------------+ 00047 */ 00048 00049 /* 00050 +----------------------------------------------------------------------------+ 00051 | Included files | 00052 +----------------------------------------------------------------------------+ 00053 */ 00054 00055 #include "hwdrv_apci2032.h" 00056 UINT ui_InterruptData, ui_Type; 00057 /* 00058 +----------------------------------------------------------------------------+ 00059 | Function Name : int i_APCI2032_ConfigDigitalOutput | 00060 | (comedi_device *dev,comedi_subdevice *s, | 00061 | comedi_insn *insn,lsampl_t *data) | 00062 +----------------------------------------------------------------------------+ 00063 | Task : Configures The Digital Output Subdevice. | 00064 +----------------------------------------------------------------------------+ 00065 | Input Parameters : comedi_device *dev : Driver handle | 00066 | UINT *data : Data Pointer contains | 00067 | configuration parameters as below | 00068 | | 00069 | data[1] : 1 Enable VCC Interrupt | 00070 | 0 Disable VCC Interrupt | 00071 | data[2] : 1 Enable CC Interrupt | 00072 | 0 Disable CC Interrupt | 00073 | | 00074 +----------------------------------------------------------------------------+ 00075 | Output Parameters : -- | 00076 +----------------------------------------------------------------------------+ 00077 | Return Value : TRUE : No error occur | 00078 | : FALSE : Error occur. Return the error | 00079 | | 00080 +----------------------------------------------------------------------------+ 00081 */ 00082 int i_APCI2032_ConfigDigitalOutput(comedi_device * dev, comedi_subdevice * s, 00083 comedi_insn * insn, lsampl_t * data) 00084 { 00085 ULONG ul_Command = 0; 00086 devpriv->tsk_Current = current; 00087 00088 if ((data[0] != 0) && (data[0] != 1)) { 00089 comedi_error(dev, 00090 "Not a valid Data !!! ,Data should be 1 or 0\n"); 00091 return -EINVAL; 00092 } //if ( (data[0]!=0) && (data[0]!=1) ) 00093 if (data[0]) { 00094 devpriv->b_OutputMemoryStatus = ADDIDATA_ENABLE; 00095 } // if (data[0]) 00096 else { 00097 devpriv->b_OutputMemoryStatus = ADDIDATA_DISABLE; 00098 } //else if (data[0]) 00099 00100 if (data[1] == ADDIDATA_ENABLE) { 00101 ul_Command = ul_Command | 0x1; 00102 } //if (data[1] == ADDIDATA_ENABLE) 00103 else { 00104 ul_Command = ul_Command & 0xFFFFFFFE; 00105 } //elseif (data[1] == ADDIDATA_ENABLE) 00106 if (data[2] == ADDIDATA_ENABLE) { 00107 ul_Command = ul_Command | 0x2; 00108 } //if (data[2] == ADDIDATA_ENABLE) 00109 else { 00110 ul_Command = ul_Command & 0xFFFFFFFD; 00111 } //elseif (data[2] == ADDIDATA_ENABLE) 00112 outl(ul_Command, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); 00113 ui_InterruptData = inl(devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); 00114 return insn->n; 00115 } 00116 00117 /* 00118 +----------------------------------------------------------------------------+ 00119 | Function Name : int i_APCI2032_WriteDigitalOutput | 00120 | (comedi_device *dev,comedi_subdevice *s, | 00121 | comedi_insn *insn,lsampl_t *data) | 00122 +----------------------------------------------------------------------------+ 00123 | Task : Writes port value To the selected port | 00124 +----------------------------------------------------------------------------+ 00125 | Input Parameters : comedi_device *dev : Driver handle | 00126 | UINT ui_NoOfChannels : No Of Channels To Write | 00127 | UINT *data : Data Pointer to read status | 00128 +----------------------------------------------------------------------------+ 00129 | Output Parameters : -- | 00130 +----------------------------------------------------------------------------+ 00131 | Return Value : TRUE : No error occur | 00132 | : FALSE : Error occur. Return the error | 00133 | | 00134 +----------------------------------------------------------------------------+ 00135 */ 00136 00137 INT i_APCI2032_WriteDigitalOutput(comedi_device * dev, comedi_subdevice * s, 00138 comedi_insn * insn, lsampl_t * data) 00139 { 00140 UINT ui_Temp, ui_Temp1; 00141 UINT ui_NoOfChannel = CR_CHAN(insn->chanspec); // get the channel 00142 if (devpriv->b_OutputMemoryStatus) { 00143 ui_Temp = inl(devpriv->iobase + APCI2032_DIGITAL_OP); 00144 00145 } //if(devpriv->b_OutputMemoryStatus ) 00146 else { 00147 ui_Temp = 0; 00148 } //if(devpriv->b_OutputMemoryStatus ) 00149 if (data[3] == 0) { 00150 if (data[1] == 0) { 00151 data[0] = (data[0] << ui_NoOfChannel) | ui_Temp; 00152 outl(data[0], devpriv->iobase + APCI2032_DIGITAL_OP); 00153 } //if(data[1]==0) 00154 else { 00155 if (data[1] == 1) { 00156 switch (ui_NoOfChannel) { 00157 00158 case 2: 00159 data[0] = 00160 (data[0] << (2 * 00161 data[2])) | ui_Temp; 00162 break; 00163 00164 case 4: 00165 data[0] = 00166 (data[0] << (4 * 00167 data[2])) | ui_Temp; 00168 break; 00169 00170 case 8: 00171 data[0] = 00172 (data[0] << (8 * 00173 data[2])) | ui_Temp; 00174 break; 00175 00176 case 16: 00177 data[0] = 00178 (data[0] << (16 * 00179 data[2])) | ui_Temp; 00180 break; 00181 case 31: 00182 data[0] = data[0] | ui_Temp; 00183 break; 00184 00185 default: 00186 comedi_error(dev, " chan spec wrong"); 00187 return -EINVAL; // "sorry channel spec wrong " 00188 00189 } //switch(ui_NoOfChannels) 00190 00191 outl(data[0], 00192 devpriv->iobase + APCI2032_DIGITAL_OP); 00193 } // if(data[1]==1) 00194 else { 00195 printk("\nSpecified channel not supported\n"); 00196 } //else if(data[1]==1) 00197 } //elseif(data[1]==0) 00198 } //if(data[3]==0) 00199 else { 00200 if (data[3] == 1) { 00201 if (data[1] == 0) { 00202 data[0] = ~data[0] & 0x1; 00203 ui_Temp1 = 1; 00204 ui_Temp1 = ui_Temp1 << ui_NoOfChannel; 00205 ui_Temp = ui_Temp | ui_Temp1; 00206 data[0] = 00207 (data[0] << ui_NoOfChannel) ^ 00208 0xffffffff; 00209 data[0] = data[0] & ui_Temp; 00210 outl(data[0], 00211 devpriv->iobase + APCI2032_DIGITAL_OP); 00212 } //if(data[1]==0) 00213 else { 00214 if (data[1] == 1) { 00215 switch (ui_NoOfChannel) { 00216 00217 case 2: 00218 data[0] = ~data[0] & 0x3; 00219 ui_Temp1 = 3; 00220 ui_Temp1 = 00221 ui_Temp1 << 2 * data[2]; 00222 ui_Temp = ui_Temp | ui_Temp1; 00223 data[0] = 00224 ((data[0] << (2 * 00225 data 00226 [2])) ^ 00227 0xffffffff) & ui_Temp; 00228 break; 00229 00230 case 4: 00231 data[0] = ~data[0] & 0xf; 00232 ui_Temp1 = 15; 00233 ui_Temp1 = 00234 ui_Temp1 << 4 * data[2]; 00235 ui_Temp = ui_Temp | ui_Temp1; 00236 data[0] = 00237 ((data[0] << (4 * 00238 data 00239 [2])) ^ 00240 0xffffffff) & ui_Temp; 00241 break; 00242 00243 case 8: 00244 data[0] = ~data[0] & 0xff; 00245 ui_Temp1 = 255; 00246 ui_Temp1 = 00247 ui_Temp1 << 8 * data[2]; 00248 ui_Temp = ui_Temp | ui_Temp1; 00249 data[0] = 00250 ((data[0] << (8 * 00251 data 00252 [2])) ^ 00253 0xffffffff) & ui_Temp; 00254 break; 00255 00256 case 16: 00257 data[0] = ~data[0] & 0xffff; 00258 ui_Temp1 = 65535; 00259 ui_Temp1 = 00260 ui_Temp1 << 16 * 00261 data[2]; 00262 ui_Temp = ui_Temp | ui_Temp1; 00263 data[0] = 00264 ((data[0] << (16 * 00265 data 00266 [2])) ^ 00267 0xffffffff) & ui_Temp; 00268 break; 00269 00270 case 31: 00271 break; 00272 default: 00273 comedi_error(dev, 00274 " chan spec wrong"); 00275 return -EINVAL; // "sorry channel spec wrong " 00276 00277 } //switch(ui_NoOfChannels) 00278 00279 outl(data[0], 00280 devpriv->iobase + 00281 APCI2032_DIGITAL_OP); 00282 } // if(data[1]==1) 00283 else { 00284 printk("\nSpecified channel not supported\n"); 00285 } //else if(data[1]==1) 00286 } //elseif(data[1]==0) 00287 } //if(data[3]==1); 00288 else { 00289 printk("\nSpecified functionality does not exist\n"); 00290 return -EINVAL; 00291 } //if else data[3]==1) 00292 } //if else data[3]==0) 00293 return (insn->n);; 00294 } 00295 00296 /* 00297 +----------------------------------------------------------------------------+ 00298 | Function Name : int i_APCI2032_ReadDigitalOutput | 00299 | (comedi_device *dev,comedi_subdevice *s, | 00300 | comedi_insn *insn,lsampl_t *data) | 00301 +----------------------------------------------------------------------------+ 00302 | Task : Read value of the selected channel or port | 00303 +----------------------------------------------------------------------------+ 00304 | Input Parameters : comedi_device *dev : Driver handle | 00305 | UINT ui_NoOfChannels : No Of Channels To read | 00306 | UINT *data : Data Pointer to read status | 00307 +----------------------------------------------------------------------------+ 00308 | Output Parameters : -- | 00309 +----------------------------------------------------------------------------+ 00310 | Return Value : TRUE : No error occur | 00311 | : FALSE : Error occur. Return the error | 00312 | | 00313 +----------------------------------------------------------------------------+ 00314 */ 00315 00316 INT i_APCI2032_ReadDigitalOutput(comedi_device * dev, comedi_subdevice * s, 00317 comedi_insn * insn, lsampl_t * data) 00318 { 00319 UINT ui_Temp; 00320 UINT ui_NoOfChannel; 00321 ui_NoOfChannel = CR_CHAN(insn->chanspec); 00322 ui_Temp = data[0]; 00323 *data = inl(devpriv->iobase + APCI2032_DIGITAL_OP_RW); 00324 if (ui_Temp == 0) { 00325 *data = (*data >> ui_NoOfChannel) & 0x1; 00326 } //if (ui_Temp==0) 00327 else { 00328 if (ui_Temp == 1) { 00329 switch (ui_NoOfChannel) { 00330 00331 case 2: 00332 *data = (*data >> (2 * data[1])) & 3; 00333 break; 00334 00335 case 4: 00336 *data = (*data >> (4 * data[1])) & 15; 00337 break; 00338 00339 case 8: 00340 *data = (*data >> (8 * data[1])) & 255; 00341 break; 00342 00343 case 16: 00344 *data = (*data >> (16 * data[1])) & 65535; 00345 break; 00346 00347 case 31: 00348 break; 00349 00350 default: 00351 comedi_error(dev, " chan spec wrong"); 00352 return -EINVAL; // "sorry channel spec wrong " 00353 00354 } //switch(ui_NoOfChannels) 00355 } //if (ui_Temp==1) 00356 else { 00357 printk("\nSpecified channel not supported \n"); 00358 } //elseif (ui_Temp==1) 00359 } 00360 return insn->n; 00361 } 00362 00363 /* 00364 +----------------------------------------------------------------------------+ 00365 | Function Name : INT i_APCI2032_ConfigWatchdog(comedi_device 00366 *dev,comedi_subdevice *s,comedi_insn *insn,lsampl_t *data)| 00367 | | 00368 +----------------------------------------------------------------------------+ 00369 | Task : Configures The Watchdog | 00370 +----------------------------------------------------------------------------+ 00371 | Input Parameters : comedi_device *dev : Driver handle | 00372 | comedi_subdevice *s, :pointer to subdevice structure 00373 comedi_insn *insn :pointer to insn structure | 00374 | lsampl_t *data : Data Pointer to read status | 00375 +----------------------------------------------------------------------------+ 00376 | Output Parameters : -- | 00377 +----------------------------------------------------------------------------+ 00378 | Return Value : TRUE : No error occur | 00379 | : FALSE : Error occur. Return the error | 00380 | | 00381 +----------------------------------------------------------------------------+ 00382 */ 00383 INT i_APCI2032_ConfigWatchdog(comedi_device * dev, comedi_subdevice * s, 00384 comedi_insn * insn, lsampl_t * data) 00385 { 00386 if (data[0] == 0) { 00387 //Disable the watchdog 00388 outl(0x0, 00389 devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + 00390 APCI2032_TCW_PROG); 00391 //Loading the Reload value 00392 outl(data[1], 00393 devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + 00394 APCI2032_TCW_RELOAD_VALUE); 00395 } else { 00396 printk("\nThe input parameters are wrong\n"); 00397 return -EINVAL; 00398 } 00399 00400 return insn->n; 00401 } 00402 00403 /* 00404 +----------------------------------------------------------------------------+ 00405 | Function Name : int i_APCI2032_StartStopWriteWatchdog | 00406 | (comedi_device *dev,comedi_subdevice *s, 00407 comedi_insn *insn,lsampl_t *data); | 00408 +----------------------------------------------------------------------------+ 00409 | Task : Start / Stop The Watchdog | 00410 +----------------------------------------------------------------------------+ 00411 | Input Parameters : comedi_device *dev : Driver handle | 00412 | comedi_subdevice *s, :pointer to subdevice structure 00413 comedi_insn *insn :pointer to insn structure | 00414 | lsampl_t *data : Data Pointer to read status | 00415 +----------------------------------------------------------------------------+ 00416 | Output Parameters : -- | 00417 +----------------------------------------------------------------------------+ 00418 | Return Value : TRUE : No error occur | 00419 | : FALSE : Error occur. Return the error | 00420 | | 00421 +----------------------------------------------------------------------------+ 00422 */ 00423 00424 int i_APCI2032_StartStopWriteWatchdog(comedi_device * dev, comedi_subdevice * s, 00425 comedi_insn * insn, lsampl_t * data) 00426 { 00427 switch (data[0]) { 00428 case 0: //stop the watchdog 00429 outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog 00430 break; 00431 case 1: //start the watchdog 00432 outl(0x0001, 00433 devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + 00434 APCI2032_TCW_PROG); 00435 break; 00436 case 2: //Software trigger 00437 outl(0x0201, 00438 devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + 00439 APCI2032_TCW_PROG); 00440 break; 00441 default: 00442 printk("\nSpecified functionality does not exist\n"); 00443 return -EINVAL; 00444 } 00445 return insn->n; 00446 } 00447 00448 /* 00449 +----------------------------------------------------------------------------+ 00450 | Function Name : int i_APCI2032_ReadWatchdog | 00451 | (comedi_device *dev,comedi_subdevice *s,comedi_insn *insn, 00452 lsampl_t *data); | 00453 +----------------------------------------------------------------------------+ 00454 | Task : Read The Watchdog | 00455 +----------------------------------------------------------------------------+ 00456 | Input Parameters : comedi_device *dev : Driver handle | 00457 | comedi_subdevice *s, :pointer to subdevice structure 00458 comedi_insn *insn :pointer to insn structure | 00459 | lsampl_t *data : Data Pointer to read status | 00460 +----------------------------------------------------------------------------+ 00461 | Output Parameters : -- | 00462 +----------------------------------------------------------------------------+ 00463 | Return Value : TRUE : No error occur | 00464 | : FALSE : Error occur. Return the error | 00465 | | 00466 +----------------------------------------------------------------------------+ 00467 */ 00468 00469 int i_APCI2032_ReadWatchdog(comedi_device * dev, comedi_subdevice * s, 00470 comedi_insn * insn, lsampl_t * data) 00471 { 00472 00473 data[0] = 00474 inl(devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + 00475 APCI2032_TCW_TRIG_STATUS) & 0x1; 00476 return insn->n; 00477 } 00478 00479 /* 00480 +----------------------------------------------------------------------------+ 00481 | Function Name : void v_APCI2032_Interrupt | 00482 | (int irq , void *d) | 00483 +----------------------------------------------------------------------------+ 00484 | Task : Writes port value To the selected port | 00485 +----------------------------------------------------------------------------+ 00486 | Input Parameters : int irq : irq number | 00487 | void *d : void pointer | 00488 +----------------------------------------------------------------------------+ 00489 | Output Parameters : -- | 00490 +----------------------------------------------------------------------------+ 00491 | Return Value : TRUE : No error occur | 00492 | : FALSE : Error occur. Return the error | 00493 | | 00494 +----------------------------------------------------------------------------+ 00495 */ 00496 void v_APCI2032_Interrupt(int irq, void *d) 00497 { 00498 comedi_device *dev = d; 00499 unsigned int ui_DO; 00500 00501 ui_DO = inl(devpriv->iobase + APCI2032_DIGITAL_OP_IRQ) & 0x1; //Check if VCC OR CC interrupt has occured. 00502 00503 if (ui_DO == 0) { 00504 printk("\nInterrupt from unKnown source\n"); 00505 } // if(ui_DO==0) 00506 if (ui_DO) { 00507 // Check for Digital Output interrupt Type - 1: Vcc interrupt 2: CC interrupt. 00508 ui_Type = 00509 inl(devpriv->iobase + 00510 APCI2032_DIGITAL_OP_INTERRUPT_STATUS) & 0x3; 00511 outl(0x0, 00512 devpriv->iobase + APCI2032_DIGITAL_OP + 00513 APCI2032_DIGITAL_OP_INTERRUPT); 00514 if (ui_Type == 1) { 00515 //Sends signal to user space 00516 send_sig(SIGIO, devpriv->tsk_Current, 0); 00517 } // if (ui_Type==1) 00518 else { 00519 if (ui_Type == 2) { 00520 // Sends signal to user space 00521 send_sig(SIGIO, devpriv->tsk_Current, 0); 00522 } //if (ui_Type==2) 00523 } //else if (ui_Type==1) 00524 } //if(ui_DO) 00525 00526 return; 00527 00528 } 00529 00530 /* 00531 +----------------------------------------------------------------------------+ 00532 | Function Name : int i_APCI2032_ReadInterruptStatus | 00533 | (comedi_device *dev,comedi_subdevice *s, | 00534 | comedi_insn *insn,lsampl_t *data) | 00535 +----------------------------------------------------------------------------+ 00536 | Task :Reads the interrupt status register | 00537 +----------------------------------------------------------------------------+ 00538 | Input Parameters : | 00539 +----------------------------------------------------------------------------+ 00540 | Output Parameters : -- | 00541 +----------------------------------------------------------------------------+ 00542 | Return Value : | 00543 | | 00544 +----------------------------------------------------------------------------+ 00545 */ 00546 00547 int i_APCI2032_ReadInterruptStatus(comedi_device * dev, comedi_subdevice * s, 00548 comedi_insn * insn, lsampl_t * data) 00549 { 00550 *data = ui_Type; 00551 return insn->n; 00552 } 00553 00554 /* 00555 +----------------------------------------------------------------------------+ 00556 | Function Name : int i_APCI2032_Reset(comedi_device *dev) | 00557 | | 00558 +----------------------------------------------------------------------------+ 00559 | Task :Resets the registers of the card | 00560 +----------------------------------------------------------------------------+ 00561 | Input Parameters : | 00562 +----------------------------------------------------------------------------+ 00563 | Output Parameters : -- | 00564 +----------------------------------------------------------------------------+ 00565 | Return Value : | 00566 | | 00567 +----------------------------------------------------------------------------+ 00568 */ 00569 00570 int i_APCI2032_Reset(comedi_device * dev) 00571 { 00572 devpriv->b_DigitalOutputRegister = 0; 00573 ui_Type = 0; 00574 outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP); //Resets the output channels 00575 outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_INTERRUPT); //Disables the interrupt. 00576 outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_PROG); //disable the watchdog 00577 outl(0x0, devpriv->iobase + APCI2032_DIGITAL_OP_WATCHDOG + APCI2032_TCW_RELOAD_VALUE); //reload=0 00578 return 0; 00579 }