APCI1710_82x54.c revision 790c55415aa31f4c732729f94d2c3a54f7d3bfc2
1/* 2 * Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module. 3 * 4 * ADDI-DATA GmbH 5 * Dieselstrasse 3 6 * D-77833 Ottersweier 7 * Tel: +19(0)7223/9493-0 8 * Fax: +49(0)7223/9493-92 9 * http://www.addi-data-com 10 * info@addi-data.com 11 * 12 * This program is free software; you can redistribute it and/or modify it 13 * under the terms of the GNU General Public License as published by the Free 14 * Software Foundation; either version 2 of the License, or (at your option) 15 * any later version. 16 */ 17/* 18 | Description : APCI-1710 82X54 timer module | 19*/ 20 21#include "APCI1710_82x54.h" 22 23/* 24+----------------------------------------------------------------------------+ 25| Function Name : _INT_ i_APCI1710_InitTimer | 26| (BYTE_ b_BoardHandle, | 27| BYTE_ b_ModulNbr, | 28| BYTE_ b_TimerNbr, | 29| BYTE_ b_TimerMode, | 30| ULONG_ ul_ReloadValue, | 31| BYTE_ b_InputClockSelection, | 32| BYTE_ b_InputClockLevel, | 33| BYTE_ b_OutputLevel, | 34| BYTE_ b_HardwareGateLevel) 35INT i_InsnConfig_InitTimer(comedi_device *dev,comedi_subdevice *s, 36 comedi_insn *insn,unsigned int *data) 37| 38+----------------------------------------------------------------------------+ 39| Task : Configure the Timer (b_TimerNbr) operating mode | 40| (b_TimerMode) from selected module (b_ModulNbr). | 41| You must calling this function be for you call any | 42| other function witch access of the timer. | 43| | 44| | 45| Timer mode description table | 46| | 47|+--------+-----------------------------+--------------+--------------------+| 48||Selected+ Mode description +u_ReloadValue | Hardware gate input|| 49|| mode | | description | action || 50|+--------+-----------------------------+--------------+--------------------+| 51|| |Mode 0 is typically used | | || 52|| |for event counting. After | | || 53|| |the initialisation, OUT | | || 54|| |is initially low, and | | || 55|| 0 |will remain low until the |Start counting| Hardware gate || 56|| |counter reaches zero. | value | || 57|| |OUT then goes high and | | || 58|| |remains high until a new | | || 59|| |count is written. See | | || 60|| |"i_APCI1710_WriteTimerValue" | | || 61|| |function. | | || 62|+--------+-----------------------------+--------------+--------------------+| 63|| |Mode 1 is similar to mode 0 | | || 64|| |except for the gate input | | || 65|| 1 |action. The gate input is not|Start counting| Hardware trigger || 66|| |used for enabled or disabled | value | || 67|| |the timer. | | || 68|| |The gate input is used for | | || 69|| |triggered the timer. | | || 70|+--------+-----------------------------+--------------+--------------------+| 71|| |This mode functions like a | | || 72|| |divide-by-ul_ReloadValue | | || 73|| |counter. It is typically used| | || 74|| |to generate a real time clock| | || 75|| |interrupt. OUT will initially| | || 76|| 2 |be high after the | Division | Hardware gate || 77|| |initialisation. When the | factor | || 78|| |initial count has decremented| | || 79|| |to 1, OUT goes low for one | | || 80|| |CLK pule. OUT then goes high | | || 81|| |again, the counter reloads | | || 82|| |the initial count | | || 83|| |(ul_ReloadValue) and the | | || 84|| |process is repeated. | | || 85|| |This action can generated a | | || 86|| |interrupt. See function | | || 87|| |"i_APCI1710_SetBoardInt- | | || 88|| |RoutineX" | | || 89|| |and "i_APCI1710_EnableTimer" | | || 90|+--------+-----------------------------+--------------+--------------------+| 91|| |Mode 3 is typically used for | | || 92|| |baud rate generation. This | | || 93|| |mode is similar to mode 2 | | || 94|| |except for the duty cycle of | | || 95|| 3 |OUT. OUT will initially be | Division | Hardware gate || 96|| |high after the initialisation| factor | || 97|| |When half the initial count | | || 98|| |(ul_ReloadValue) has expired,| | || 99|| |OUT goes low for the | | || 100|| |remainder of the count. The | | || 101|| |mode is periodic; the | | || 102|| |sequence above is repeated | | || 103|| |indefinitely. | | || 104|+--------+-----------------------------+--------------+--------------------+| 105|| |OUT will be initially high | | || 106|| |after the initialisation. | | || 107|| |When the initial count | | || 108|| 4 |expires OUT will go low for |Start counting| Hardware gate || 109|| |one CLK pulse and then go | value | || 110|| |high again. | | || 111|| |The counting sequences is | | || 112|| |triggered by writing a new | | || 113|| |value. See | | || 114|| |"i_APCI1710_WriteTimerValue" | | || 115|| |function. If a new count is | | || 116|| |written during counting, | | || 117|| |it will be loaded on the | | || 118|| |next CLK pulse | | || 119|+--------+-----------------------------+--------------+--------------------+| 120|| |Mode 5 is similar to mode 4 | | || 121|| |except for the gate input | | || 122|| |action. The gate input is not| | || 123|| 5 |used for enabled or disabled |Start counting| Hardware trigger || 124|| |the timer. The gate input is | value | || 125|| |used for triggered the timer.| | || 126|+--------+-----------------------------+--------------+--------------------+| 127| | 128| | 129| | 130| Input clock selection table | 131| | 132| +--------------------------------+------------------------------------+ | 133| | b_InputClockSelection | Description | | 134| | parameter | | | 135| +--------------------------------+------------------------------------+ | 136| | APCI1710_PCI_BUS_CLOCK | For the timer input clock, the PCI | | 137| | | bus clock / 4 is used. This PCI bus| | 138| | | clock can be 30MHz or 33MHz. For | | 139| | | Timer 0 only this selection are | | 140| | | available. | | 141| +--------------------------------+------------------------------------+ | 142| | APCI1710_ FRONT_CONNECTOR_INPUT| Of the front connector you have the| | 143| | | possibility to inject a input clock| | 144| | | for Timer 1 or Timer 2. The source | | 145| | | from this clock can eat the output | | 146| | | clock from Timer 0 or any other | | 147| | | clock source. | | 148| +--------------------------------+------------------------------------+ | 149| | 150+----------------------------------------------------------------------------+ 151| Input Parameters : BYTE_ b_BoardHandle : Handle of board | 152| APCI-1710 | 153| BYTE_ b_ModulNbr : Module number to | 154| configure (0 to 3) | 155| BYTE_ b_TimerNbr : Timer number to | 156| configure (0 to 2) | 157| BYTE_ b_TimerMode : Timer mode selection | 158| (0 to 5) | 159| 0: Interrupt on terminal| 160| count | 161| 1: Hardware | 162| retriggerable one- | 163| shot | 164| 2: Rate generator | 165| 3: Square wave mode | 166| 4: Software triggered | 167| strobe | 168| 5: Hardware triggered | 169| strobe | 170| See timer mode | 171| description table. | 172| ULONG_ ul_ReloadValue : Start counting value | 173| or division factor | 174| See timer mode | 175| description table. | 176| BYTE_ b_InputClockSelection : Selection from input | 177| timer clock. | 178| See input clock | 179| selection table. | 180| BYTE_ b_InputClockLevel : Selection from input | 181| clock level. | 182| 0 : Low active | 183| (Input inverted) | 184| 1 : High active | 185| BYTE_ b_OutputLevel, : Selection from output | 186| clock level. | 187| 0 : Low active | 188| 1 : High active | 189| (Output inverted) | 190| BYTE_ b_HardwareGateLevel : Selection from | 191| hardware gate level. | 192| 0 : Low active | 193| (Input inverted) | 194| 1 : High active | 195| If you will not used | 196| the hardware gate set | 197| this value to 0. 198|b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); 199 b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec); 200 b_TimerMode = (BYTE) data[0]; 201 ul_ReloadValue = (ULONG) data[1]; 202 b_InputClockSelection =(BYTE) data[2]; 203 b_InputClockLevel =(BYTE) data[3]; 204 b_OutputLevel =(BYTE) data[4]; 205 b_HardwareGateLevel =(BYTE) data[5]; 206+----------------------------------------------------------------------------+ 207| Output Parameters : - | 208+----------------------------------------------------------------------------+ 209| Return Value : 0: No error | 210| -1: The handle parameter of the board is wrong | 211| -2: Module selection wrong | 212| -3: Timer selection wrong | 213| -4: The module is not a TIMER module | 214| -5: Timer mode selection is wrong | 215| -6: Input timer clock selection is wrong | 216| -7: Selection from input clock level is wrong | 217| -8: Selection from output clock level is wrong | 218| -9: Selection from hardware gate level is wrong | 219+----------------------------------------------------------------------------+ 220*/ 221 222INT i_APCI1710_InsnConfigInitTimer(comedi_device * dev, comedi_subdevice * s, 223 comedi_insn * insn, unsigned int * data) 224{ 225 226 INT i_ReturnValue = 0; 227 BYTE b_ModulNbr; 228 BYTE b_TimerNbr; 229 BYTE b_TimerMode; 230 ULONG ul_ReloadValue; 231 BYTE b_InputClockSelection; 232 BYTE b_InputClockLevel; 233 BYTE b_OutputLevel; 234 BYTE b_HardwareGateLevel; 235 236 //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz 237 DWORD dw_Test = 0; 238 //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz 239 240 i_ReturnValue = insn->n; 241 b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); 242 b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec); 243 b_TimerMode = (BYTE) data[0]; 244 ul_ReloadValue = (ULONG) data[1]; 245 b_InputClockSelection = (BYTE) data[2]; 246 b_InputClockLevel = (BYTE) data[3]; 247 b_OutputLevel = (BYTE) data[4]; 248 b_HardwareGateLevel = (BYTE) data[5]; 249 250 /* Test the module number */ 251 if (b_ModulNbr < 4) { 252 /* Test if 82X54 timer */ 253 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { 254 /* Test the timer number */ 255 256 if (b_TimerNbr <= 2) { 257 /* Test the timer mode */ 258 if (b_TimerMode <= 5) { 259 //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz 260 /* Test te imput clock selection */ 261 /* 262 if (((b_TimerNbr == 0) && (b_InputClockSelection == 0)) || 263 ((b_TimerNbr != 0) && ((b_InputClockSelection == 0) || (b_InputClockSelection == 1)))) 264 */ 265 266 if (((b_TimerNbr == 0) && 267 (b_InputClockSelection == APCI1710_PCI_BUS_CLOCK)) || 268 ((b_TimerNbr == 0) && 269 (b_InputClockSelection == APCI1710_10MHZ)) || 270 ((b_TimerNbr != 0) && 271 ((b_InputClockSelection == APCI1710_PCI_BUS_CLOCK) || 272 (b_InputClockSelection == APCI1710_FRONT_CONNECTOR_INPUT) || 273 (b_InputClockSelection == APCI1710_10MHZ)))) { 274 //BEGIN JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz 275 if (((b_InputClockSelection == APCI1710_10MHZ) && 276 ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) >= 0x3131)) || 277 (b_InputClockSelection != APCI1710_10MHZ)) { 278 //END JK 27.10.2003 : Add the possibility to use a 40 Mhz quartz 279 /* Test the input clock level selection */ 280 281 if ((b_InputClockLevel == 0) || 282 (b_InputClockLevel == 1)) { 283 /* Test the output clock level selection */ 284 if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) { 285 /* Test the hardware gate level selection */ 286 if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) { 287 //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz 288 /* Test if version > 1.1 and clock selection = 10MHz */ 289 if ((b_InputClockSelection == APCI1710_10MHZ) && ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0x0000FFFFUL) > 0x3131)) { 290 /* Test if 40MHz quartz on board */ 291 dw_Test = inl(devpriv->s_BoardInfos.ui_Address + (16 + (b_TimerNbr * 4) + (64 * b_ModulNbr))); 292 293 dw_Test = (dw_Test >> 16) & 1; 294 } else { 295 dw_Test = 1; 296 } 297 298 /* Test if detection OK */ 299 if (dw_Test == 1) { 300 //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz 301 /* Initialisation OK */ 302 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init = 1; 303 304 /* Save the input clock selection */ 305 devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockSelection = b_InputClockSelection; 306 307 /* Save the input clock level */ 308 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_InputClockLevel = ~b_InputClockLevel & 1; 309 310 /* Save the output level */ 311 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel = ~b_OutputLevel & 1; 312 313 /* Save the gate level */ 314 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_HardwareGateLevel = b_HardwareGateLevel; 315 316 /* Set the configuration word and disable the timer */ 317 //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz 318 /* 319 devpriv->s_ModuleInfo [b_ModulNbr]. 320 s_82X54ModuleInfo. 321 s_82X54TimerInfo [b_TimerNbr]. 322 dw_ConfigurationWord = (DWORD) (((b_HardwareGateLevel << 0) & 0x1) | 323 ((b_InputClockLevel << 1) & 0x2) | 324 (((~b_OutputLevel & 1) << 2) & 0x4) | 325 ((b_InputClockSelection << 4) & 0x10)); 326 */ 327 /* Test if 10MHz selected */ 328 if (b_InputClockSelection == APCI1710_10MHZ) { 329 b_InputClockSelection = 2; 330 } 331 332 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = (DWORD)(((b_HardwareGateLevel << 0) & 0x1) | ((b_InputClockLevel << 1) & 0x2) | (((~b_OutputLevel & 1) << 2) & 0x4) | ((b_InputClockSelection << 4) & 0x30)); 333 //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz 334 outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 335 336 /* Initialise the 82X54 Timer */ 337 outl((DWORD) b_TimerMode, devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 338 339 /* Write the reload value */ 340 outl(ul_ReloadValue, devpriv->s_BoardInfos.ui_Address + 0 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 341 //BEGIN JK 27.10.03 : Add the possibility to use a 40 Mhz quartz 342 } // if (dw_Test == 1) 343 else { 344 /* Input timer clock selection is wrong */ 345 i_ReturnValue = -6; 346 } // if (dw_Test == 1) 347 //END JK 27.10.03 : Add the possibility to use a 40 Mhz quartz 348 } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) 349 else { 350 /* Selection from hardware gate level is wrong */ 351 DPRINTK("Selection from hardware gate level is wrong\n"); 352 i_ReturnValue = -9; 353 } // if ((b_HardwareGateLevel == 0) || (b_HardwareGateLevel == 1)) 354 } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) 355 else { 356 /* Selection from output clock level is wrong */ 357 DPRINTK("Selection from output clock level is wrong\n"); 358 i_ReturnValue = -8; 359 } // if ((b_OutputLevel == 0) || (b_OutputLevel == 1)) 360 } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1)) 361 else { 362 /* Selection from input clock level is wrong */ 363 DPRINTK("Selection from input clock level is wrong\n"); 364 i_ReturnValue = -7; 365 } // if ((b_InputClockLevel == 0) || (b_InputClockLevel == 1)) 366 } else { 367 /* Input timer clock selection is wrong */ 368 DPRINTK("Input timer clock selection is wrong\n"); 369 i_ReturnValue = -6; 370 } 371 } else { 372 /* Input timer clock selection is wrong */ 373 DPRINTK("Input timer clock selection is wrong\n"); 374 i_ReturnValue = -6; 375 } 376 } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5)) 377 else { 378 /* Timer mode selection is wrong */ 379 DPRINTK("Timer mode selection is wrong\n"); 380 i_ReturnValue = -5; 381 } // if ((b_TimerMode >= 0) && (b_TimerMode <= 5)) 382 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) 383 else { 384 /* Timer selection wrong */ 385 DPRINTK("Timer selection wrong\n"); 386 i_ReturnValue = -3; 387 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) 388 } else { 389 /* The module is not a TIMER module */ 390 DPRINTK("The module is not a TIMER module\n"); 391 i_ReturnValue = -4; 392 } 393 } else { 394 /* Module number error */ 395 DPRINTK("Module number error\n"); 396 i_ReturnValue = -2; 397 } 398 399 return (i_ReturnValue); 400} 401 402/* 403+----------------------------------------------------------------------------+ 404| Function Name : _INT_ i_APCI1710_EnableTimer | 405| (BYTE_ b_BoardHandle, | 406| BYTE_ b_ModulNbr, | 407| BYTE_ b_TimerNbr, | 408| BYTE_ b_InterruptEnable) 409INT i_APCI1710_InsnWriteEnableDisableTimer(comedi_device *dev,comedi_subdevice *s, 410 comedi_insn *insn,unsigned int *data) | 411+----------------------------------------------------------------------------+ 412| Task : Enable OR Disable the Timer (b_TimerNbr) from selected module | 413| (b_ModulNbr). You must calling the | 414| "i_APCI1710_InitTimer" function be for you call this | 415| function. If you enable the timer interrupt, the timer | 416| generate a interrupt after the timer value reach | 417| the zero. See function "i_APCI1710_SetBoardIntRoutineX"| 418+----------------------------------------------------------------------------+ 419| Input Parameters : BYTE_ b_BoardHandle : Handle of board | 420| APCI-1710 | 421| BYTE_ b_ModulNbr : Selected module number | 422| (0 to 3) | 423| BYTE_ b_TimerNbr : Timer number to enable | 424| (0 to 2) | 425| BYTE_ b_InterruptEnable : Enable or disable the | 426| timer interrupt. | 427| APCI1710_ENABLE : | 428| Enable the timer interrupt | 429| APCI1710_DISABLE : | 430| Disable the timer interrupt| 431i_ReturnValue=insn->n; 432 b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); 433 b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec); 434 b_ActionType = (BYTE) data[0]; // enable disable 435+----------------------------------------------------------------------------+ 436| Output Parameters : - | 437+----------------------------------------------------------------------------+ 438| Return Value : 0: No error | 439| -1: The handle parameter of the board is wrong | 440| -2: Module selection wrong | 441| -3: Timer selection wrong | 442| -4: The module is not a TIMER module | 443| -5: Timer not initialised see function | 444| "i_APCI1710_InitTimer" | 445| -6: Interrupt parameter is wrong | 446| -7: Interrupt function not initialised. | 447| See function "i_APCI1710_SetBoardIntRoutineX" | 448+----------------------------------------------------------------------------+ 449*/ 450 451INT i_APCI1710_InsnWriteEnableDisableTimer(comedi_device * dev, 452 comedi_subdevice * s, 453 comedi_insn * insn, unsigned int * data) 454{ 455 INT i_ReturnValue = 0; 456 DWORD dw_DummyRead; 457 BYTE b_ModulNbr; 458 BYTE b_TimerNbr; 459 BYTE b_ActionType; 460 BYTE b_InterruptEnable; 461 462 i_ReturnValue = insn->n; 463 b_ModulNbr = (BYTE) CR_AREF(insn->chanspec); 464 b_TimerNbr = (BYTE) CR_CHAN(insn->chanspec); 465 b_ActionType = (BYTE) data[0]; // enable disable 466 467 /* Test the module number */ 468 if (b_ModulNbr < 4) { 469 /* Test if 82X54 timer */ 470 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { 471 /* Test the timer number */ 472 if (b_TimerNbr <= 2) { 473 /* Test if timer initialised */ 474 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) { 475 476 switch (b_ActionType) { 477 case APCI1710_ENABLE: 478 b_InterruptEnable = (BYTE) data[1]; 479 /* Test the interrupt selection */ 480 if ((b_InterruptEnable == APCI1710_ENABLE) || 481 (b_InterruptEnable == APCI1710_DISABLE)) { 482 if (b_InterruptEnable == APCI1710_ENABLE) { 483 484 dw_DummyRead = inl(devpriv->s_BoardInfos.ui_Address + 12 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 485 486 /* Enable the interrupt */ 487 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord | 0x8; 488 489 outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 490 devpriv->tsk_Current = current; // Save the current process task structure 491 492 } // if (b_InterruptEnable == APCI1710_ENABLE) 493 else { 494 /* Disable the interrupt */ 495 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7; 496 497 outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 498 499 /* Save the interrupt flag */ 500 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr)); 501 } // if (b_InterruptEnable == APCI1710_ENABLE) 502 503 /* Test if error occur */ 504 if (i_ReturnValue >= 0) { 505 /* Save the interrupt flag */ 506 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask | ((1 & b_InterruptEnable) << b_TimerNbr); 507 508 /* Enable the timer */ 509 outl(1, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 510 } 511 } else { 512 /* Interrupt parameter is wrong */ 513 DPRINTK("\n"); 514 i_ReturnValue = -6; 515 } 516 break; 517 case APCI1710_DISABLE: 518 /* Test the interrupt flag */ 519 if (((devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask >> b_TimerNbr) & 1) == 1) { 520 /* Disable the interrupt */ 521 522 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr]. dw_ConfigurationWord = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord & 0xF7; 523 524 outl(devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].dw_ConfigurationWord, devpriv->s_BoardInfos.ui_Address + 32 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 525 526 /* Save the interrupt flag */ 527 devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask = devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.b_InterruptMask & (0xFF - (1 << b_TimerNbr)); 528 } 529 530 /* Disable the timer */ 531 outl(0, devpriv->s_BoardInfos.ui_Address + 44 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 532 break; 533 } // Switch end 534 } else { 535 /* Timer not initialised see function */ 536 DPRINTK ("Timer not initialised see function\n"); 537 i_ReturnValue = -5; 538 } 539 } else { 540 /* Timer selection wrong */ 541 DPRINTK("Timer selection wrong\n"); 542 i_ReturnValue = -3; 543 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) 544 } else { 545 /* The module is not a TIMER module */ 546 DPRINTK("The module is not a TIMER module\n"); 547 i_ReturnValue = -4; 548 } 549 } else { 550 /* Module number error */ 551 DPRINTK("Module number error\n"); 552 i_ReturnValue = -2; 553 } 554 555 return (i_ReturnValue); 556} 557 558/* 559+----------------------------------------------------------------------------+ 560| Function Name : _INT_ i_APCI1710_ReadAllTimerValue | 561| (BYTE_ b_BoardHandle, | 562| BYTE_ b_ModulNbr, | 563| PULONG_ pul_TimerValueArray) 564INT i_APCI1710_InsnReadAllTimerValue(comedi_device *dev,comedi_subdevice *s, 565 comedi_insn *insn,unsigned int *data) | 566+----------------------------------------------------------------------------+ 567| Task : Return the all timer values from selected timer | 568| module (b_ModulNbr). | 569+----------------------------------------------------------------------------+ 570| Input Parameters : BYTE_ b_BoardHandle : Handle of board | 571| APCI-1710 | 572| BYTE_ b_ModulNbr : Selected module number | 573| (0 to 3) | 574+----------------------------------------------------------------------------+ 575| Output Parameters : PULONG_ pul_TimerValueArray : Timer value array. | 576| Element 0 contain the timer 0 value. | 577| Element 1 contain the timer 1 value. | 578| Element 2 contain the timer 2 value. | 579+----------------------------------------------------------------------------+ 580| Return Value : 0: No error | 581| -1: The handle parameter of the board is wrong | 582| -2: Module selection wrong | 583| -3: The module is not a TIMER module | 584| -4: Timer 0 not initialised see function | 585| "i_APCI1710_InitTimer" | 586| -5: Timer 1 not initialised see function | 587| "i_APCI1710_InitTimer" | 588| -6: Timer 2 not initialised see function | 589| "i_APCI1710_InitTimer" | 590+----------------------------------------------------------------------------+ 591*/ 592 593INT i_APCI1710_InsnReadAllTimerValue(comedi_device *dev, comedi_subdevice *s, 594 comedi_insn *insn, unsigned int *data) 595{ 596 INT i_ReturnValue = 0; 597 BYTE b_ModulNbr, b_ReadType; 598 PULONG pul_TimerValueArray; 599 600 b_ModulNbr = CR_AREF(insn->chanspec); 601 b_ReadType = CR_CHAN(insn->chanspec); 602 pul_TimerValueArray = (PULONG) data; 603 i_ReturnValue = insn->n; 604 605 switch (b_ReadType) { 606 case APCI1710_TIMER_READINTERRUPT: 607 608 data[0] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].b_OldModuleMask; 609 data[1] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldInterruptMask; 610 data[2] = devpriv->s_InterruptParameters.s_FIFOInterruptParameters[devpriv->s_InterruptParameters.ui_Read].ul_OldCounterLatchValue; 611 612 /* Increment the read FIFO */ 613 devpriv->s_InterruptParameters.ui_Read = (devpriv->s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT; 614 615 break; 616 617 case APCI1710_TIMER_READALLTIMER: 618 /* Test the module number */ 619 if (b_ModulNbr < 4) { 620 /* Test if 82X54 timer */ 621 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { 622 /* Test if timer 0 iniutialised */ 623 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[0].b_82X54Init == 1) { 624 /* Test if timer 1 iniutialised */ 625 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[1].b_82X54Init == 1) { 626 /* Test if timer 2 iniutialised */ 627 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[2].b_82X54Init == 1) { 628 /* Latch all counter */ 629 outl(0x17, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr)); 630 631 /* Read the timer 0 value */ 632 pul_TimerValueArray[0] = inl(devpriv->s_BoardInfos.ui_Address + 0 + (64 * b_ModulNbr)); 633 634 /* Read the timer 1 value */ 635 pul_TimerValueArray[1] = inl(devpriv->s_BoardInfos.ui_Address + 4 + (64 * b_ModulNbr)); 636 637 /* Read the timer 2 value */ 638 pul_TimerValueArray[2] = inl(devpriv->s_BoardInfos.ui_Address + 8 + (64 * b_ModulNbr)); 639 } else { 640 /* Timer 2 not initialised see function */ 641 DPRINTK("Timer 2 not initialised see function\n"); 642 i_ReturnValue = -6; 643 } 644 } else { 645 /* Timer 1 not initialised see function */ 646 DPRINTK("Timer 1 not initialised see function\n"); 647 i_ReturnValue = -5; 648 } 649 } else { 650 /* Timer 0 not initialised see function */ 651 DPRINTK("Timer 0 not initialised see function\n"); 652 i_ReturnValue = -4; 653 } 654 } else { 655 /* The module is not a TIMER module */ 656 DPRINTK("The module is not a TIMER module\n"); 657 i_ReturnValue = -3; 658 } 659 } else { 660 /* Module number error */ 661 DPRINTK("Module number error\n"); 662 i_ReturnValue = -2; 663 } 664 665 } // End of Switch 666 return (i_ReturnValue); 667} 668 669/* 670+----------------------------------------------------------------------------+ 671| Function Name :INT i_APCI1710_InsnBitsTimer(comedi_device *dev, 672comedi_subdevice *s,comedi_insn *insn,unsigned int *data) | 673+----------------------------------------------------------------------------+ 674| Task : Read write functions for Timer | 675+----------------------------------------------------------------------------+ 676| Input Parameters : 677+----------------------------------------------------------------------------+ 678| Output Parameters : - | 679+----------------------------------------------------------------------------+ 680| Return Value : 681+----------------------------------------------------------------------------+ 682*/ 683 684INT i_APCI1710_InsnBitsTimer(comedi_device * dev, comedi_subdevice * s, 685 comedi_insn * insn, unsigned int * data) 686{ 687 BYTE b_BitsType; 688 INT i_ReturnValue = 0; 689 b_BitsType = data[0]; 690 691 printk("\n82X54"); 692 693 switch (b_BitsType) { 694 case APCI1710_TIMER_READVALUE: 695 i_ReturnValue = i_APCI1710_ReadTimerValue(dev, 696 (BYTE)CR_AREF(insn->chanspec), 697 (BYTE)CR_CHAN(insn->chanspec), 698 (PULONG) & data[0]); 699 break; 700 701 case APCI1710_TIMER_GETOUTPUTLEVEL: 702 i_ReturnValue = i_APCI1710_GetTimerOutputLevel(dev, 703 (BYTE)CR_AREF(insn->chanspec), 704 (BYTE)CR_CHAN(insn->chanspec), 705 (PBYTE) &data[0]); 706 break; 707 708 case APCI1710_TIMER_GETPROGRESSSTATUS: 709 i_ReturnValue = i_APCI1710_GetTimerProgressStatus(dev, 710 (BYTE)CR_AREF(insn->chanspec), 711 (BYTE)CR_CHAN(insn->chanspec), 712 (PBYTE)&data[0]); 713 break; 714 715 case APCI1710_TIMER_WRITEVALUE: 716 i_ReturnValue = i_APCI1710_WriteTimerValue(dev, 717 (BYTE)CR_AREF(insn->chanspec), 718 (BYTE)CR_CHAN(insn->chanspec), 719 (ULONG)data[1]); 720 721 break; 722 723 default: 724 printk("Bits Config Parameter Wrong\n"); 725 i_ReturnValue = -1; 726 } 727 728 if (i_ReturnValue >= 0) 729 i_ReturnValue = insn->n; 730 return (i_ReturnValue); 731} 732 733/* 734+----------------------------------------------------------------------------+ 735| Function Name : _INT_ i_APCI1710_ReadTimerValue | 736| (BYTE_ b_BoardHandle, | 737| BYTE_ b_ModulNbr, | 738| BYTE_ b_TimerNbr, | 739| PULONG_ pul_TimerValue) | 740+----------------------------------------------------------------------------+ 741| Task : Return the timer value from selected digital timer | 742| (b_TimerNbr) from selected timer module (b_ModulNbr). | 743+----------------------------------------------------------------------------+ 744| Input Parameters : BYTE_ b_BoardHandle : Handle of board | 745| APCI-1710 | 746| BYTE_ b_ModulNbr : Selected module number | 747| (0 to 3) | 748| BYTE_ b_TimerNbr : Timer number to read | 749| (0 to 2) | 750+----------------------------------------------------------------------------+ 751| Output Parameters : PULONG_ pul_TimerValue : Timer value | 752+----------------------------------------------------------------------------+ 753| Return Value : 0: No error | 754| -1: The handle parameter of the board is wrong | 755| -2: Module selection wrong | 756| -3: Timer selection wrong | 757| -4: The module is not a TIMER module | 758| -5: Timer not initialised see function | 759| "i_APCI1710_InitTimer" | 760+----------------------------------------------------------------------------+ 761*/ 762 763INT i_APCI1710_ReadTimerValue(comedi_device * dev, 764 BYTE b_ModulNbr, BYTE b_TimerNbr, 765 PULONG pul_TimerValue) 766{ 767 INT i_ReturnValue = 0; 768 769 /* Test the module number */ 770 if (b_ModulNbr < 4) { 771 /* Test if 82X54 timer */ 772 if ((devpriv->s_BoardInfos. 773 dw_MolduleConfiguration[b_ModulNbr] & 774 0xFFFF0000UL) == APCI1710_82X54_TIMER) { 775 /* Test the timer number */ 776 if (b_TimerNbr <= 2) { 777 /* Test if timer initialised */ 778 if (devpriv-> 779 s_ModuleInfo[b_ModulNbr]. 780 s_82X54ModuleInfo. 781 s_82X54TimerInfo[b_TimerNbr]. 782 b_82X54Init == 1) { 783 /* Latch the timer value */ 784 outl((2 << b_TimerNbr) | 0xD0, 785 devpriv->s_BoardInfos. 786 ui_Address + 12 + 787 (64 * b_ModulNbr)); 788 789 /* Read the counter value */ 790 *pul_TimerValue = 791 inl(devpriv->s_BoardInfos. 792 ui_Address + (b_TimerNbr * 4) + 793 (64 * b_ModulNbr)); 794 } else { 795 /* Timer not initialised see function */ 796 DPRINTK("Timer not initialised see function\n"); 797 i_ReturnValue = -5; 798 } 799 } else { 800 /* Timer selection wrong */ 801 DPRINTK("Timer selection wrong\n"); 802 i_ReturnValue = -3; 803 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) 804 } else { 805 /* The module is not a TIMER module */ 806 DPRINTK("The module is not a TIMER module\n"); 807 i_ReturnValue = -4; 808 } 809 } else { 810 /* Module number error */ 811 DPRINTK("Module number error\n"); 812 i_ReturnValue = -2; 813 } 814 815 return (i_ReturnValue); 816} 817 818 /* 819 +----------------------------------------------------------------------------+ 820 | Function Name : _INT_ i_APCI1710_GetTimerOutputLevel | 821 | (BYTE_ b_BoardHandle, | 822 | BYTE_ b_ModulNbr, | 823 | BYTE_ b_TimerNbr, | 824 | PBYTE_ pb_OutputLevel) | 825 +----------------------------------------------------------------------------+ 826 | Task : Return the output signal level (pb_OutputLevel) from | 827 | selected digital timer (b_TimerNbr) from selected timer| 828 | module (b_ModulNbr). | 829 +----------------------------------------------------------------------------+ 830 | Input Parameters : BYTE_ b_BoardHandle : Handle of board | 831 | APCI-1710 | 832 | BYTE_ b_ModulNbr : Selected module number | 833 | (0 to 3) | 834 | BYTE_ b_TimerNbr : Timer number to test | 835 | (0 to 2) | 836 +----------------------------------------------------------------------------+ 837 | Output Parameters : PBYTE_ pb_OutputLevel : Output signal level | 838 | 0 : The output is low | 839 | 1 : The output is high | 840 +----------------------------------------------------------------------------+ 841 | Return Value : 0: No error | 842 | -1: The handle parameter of the board is wrong | 843 | -2: Module selection wrong | 844 | -3: Timer selection wrong | 845 | -4: The module is not a TIMER module | 846 | -5: Timer not initialised see function | 847 | "i_APCI1710_InitTimer" | 848 +----------------------------------------------------------------------------+ 849 */ 850 851INT i_APCI1710_GetTimerOutputLevel(comedi_device * dev, 852 BYTE b_ModulNbr, BYTE b_TimerNbr, 853 PBYTE pb_OutputLevel) 854{ 855 INT i_ReturnValue = 0; 856 DWORD dw_TimerStatus; 857 858 /* Test the module number */ 859 if (b_ModulNbr < 4) { 860 /* Test if 82X54 timer */ 861 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { 862 /* Test the timer number */ 863 if (b_TimerNbr <= 2) { 864 /* Test if timer initialised */ 865 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) { 866 /* Latch the timer value */ 867 outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr)); 868 869 /* Read the timer status */ 870 dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 871 872 *pb_OutputLevel = (BYTE) (((dw_TimerStatus >> 7) & 1) ^ devpriv-> s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_OutputLevel); 873 } else { 874 /* Timer not initialised see function */ 875 DPRINTK("Timer not initialised see function\n"); 876 i_ReturnValue = -5; 877 } 878 } else { 879 /* Timer selection wrong */ 880 DPRINTK("Timer selection wrong\n"); 881 i_ReturnValue = -3; 882 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) 883 } else { 884 /* The module is not a TIMER module */ 885 DPRINTK("The module is not a TIMER module\n"); 886 i_ReturnValue = -4; 887 } 888 } else { 889 /* Module number error */ 890 DPRINTK("Module number error\n"); 891 i_ReturnValue = -2; 892 } 893 894 return (i_ReturnValue); 895} 896 897/* 898+----------------------------------------------------------------------------+ 899| Function Name : _INT_ i_APCI1710_GetTimerProgressStatus | 900| (BYTE_ b_BoardHandle, | 901| BYTE_ b_ModulNbr, | 902| BYTE_ b_TimerNbr, | 903| PBYTE_ pb_TimerStatus) | 904+----------------------------------------------------------------------------+ 905| Task : Return the progress status (pb_TimerStatus) from | 906| selected digital timer (b_TimerNbr) from selected timer| 907| module (b_ModulNbr). | 908+----------------------------------------------------------------------------+ 909| Input Parameters : BYTE_ b_BoardHandle : Handle of board | 910| APCI-1710 | 911| BYTE_ b_ModulNbr : Selected module number | 912| (0 to 3) | 913| BYTE_ b_TimerNbr : Timer number to test | 914| (0 to 2) | 915+----------------------------------------------------------------------------+ 916| Output Parameters : PBYTE_ pb_TimerStatus : Output signal level | 917| 0 : Timer not in progress | 918| 1 : Timer in progress | 919+----------------------------------------------------------------------------+ 920| Return Value : 0: No error | 921| -1: The handle parameter of the board is wrong | 922| -2: Module selection wrong | 923| -3: Timer selection wrong | 924| -4: The module is not a TIMER module | 925| -5: Timer not initialised see function | 926| "i_APCI1710_InitTimer" | 927+----------------------------------------------------------------------------+ 928*/ 929 930INT i_APCI1710_GetTimerProgressStatus(comedi_device *dev, 931 BYTE b_ModulNbr, BYTE b_TimerNbr, 932 PBYTE pb_TimerStatus) 933{ 934 INT i_ReturnValue = 0; 935 DWORD dw_TimerStatus; 936 937 /* Test the module number */ 938 if (b_ModulNbr < 4) { 939 /* Test if 82X54 timer */ 940 941 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { 942 /* Test the timer number */ 943 if (b_TimerNbr <= 2) { 944 /* Test if timer initialised */ 945 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) { 946 /* Latch the timer value */ 947 outl((2 << b_TimerNbr) | 0xE0, devpriv->s_BoardInfos.ui_Address + 12 + (64 * b_ModulNbr)); 948 949 /* Read the timer status */ 950 dw_TimerStatus = inl(devpriv->s_BoardInfos.ui_Address + 16 + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 951 952 *pb_TimerStatus = (BYTE) ((dw_TimerStatus) >> 8) & 1; 953 printk("ProgressStatus : %d", *pb_TimerStatus); 954 } else { 955 /* Timer not initialised see function */ 956 i_ReturnValue = -5; 957 } 958 } else { 959 /* Timer selection wrong */ 960 i_ReturnValue = -3; 961 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) 962 } else { 963 /* The module is not a TIMER module */ 964 965 i_ReturnValue = -4; 966 } 967 } else { 968 /* Module number error */ 969 970 i_ReturnValue = -2; 971 } 972 973 return i_ReturnValue; 974} 975 976/* 977+----------------------------------------------------------------------------+ 978| Function Name : _INT_ i_APCI1710_WriteTimerValue | 979| (BYTE_ b_BoardHandle, | 980| BYTE_ b_ModulNbr, | 981| BYTE_ b_TimerNbr, | 982| ULONG_ ul_WriteValue) | 983+----------------------------------------------------------------------------+ 984| Task : Write the value (ul_WriteValue) into the selected timer| 985| (b_TimerNbr) from selected timer module (b_ModulNbr). | 986| The action in depend of the time mode selection. | 987| See timer mode description table. | 988+----------------------------------------------------------------------------+ 989| Input Parameters : BYTE_ b_BoardHandle : Handle of board | 990| APCI-1710 | 991| BYTE_ b_ModulNbr : Selected module number | 992| (0 to 3) | 993| BYTE_ b_TimerNbr : Timer number to write | 994| (0 to 2) | 995| ULONG_ ul_WriteValue : Value to write | 996+----------------------------------------------------------------------------+ 997| Output Parameters : - | 998+----------------------------------------------------------------------------+ 999| Return Value : 0: No error | 1000| -1: The handle parameter of the board is wrong | 1001| -2: Module selection wrong | 1002| -3: Timer selection wrong | 1003| -4: The module is not a TIMER module | 1004| -5: Timer not initialised see function | 1005| "i_APCI1710_InitTimer" | 1006+----------------------------------------------------------------------------+ 1007*/ 1008 1009INT i_APCI1710_WriteTimerValue(comedi_device * dev, 1010 BYTE b_ModulNbr, BYTE b_TimerNbr, 1011 ULONG ul_WriteValue) 1012{ 1013 INT i_ReturnValue = 0; 1014 1015 /* Test the module number */ 1016 if (b_ModulNbr < 4) { 1017 /* Test if 82X54 timer */ 1018 if ((devpriv->s_BoardInfos.dw_MolduleConfiguration[b_ModulNbr] & 0xFFFF0000UL) == APCI1710_82X54_TIMER) { 1019 /* Test the timer number */ 1020 if (b_TimerNbr <= 2) { 1021 /* Test if timer initialised */ 1022 if (devpriv->s_ModuleInfo[b_ModulNbr].s_82X54ModuleInfo.s_82X54TimerInfo[b_TimerNbr].b_82X54Init == 1) { 1023 /* Write the value */ 1024 outl(ul_WriteValue, devpriv->s_BoardInfos.ui_Address + (b_TimerNbr * 4) + (64 * b_ModulNbr)); 1025 } else { 1026 /* Timer not initialised see function */ 1027 DPRINTK("Timer not initialised see function\n"); 1028 i_ReturnValue = -5; 1029 } 1030 } else { 1031 /* Timer selection wrong */ 1032 DPRINTK("Timer selection wrong\n"); 1033 i_ReturnValue = -3; 1034 } // if ((b_TimerNbr >= 0) && (b_TimerNbr <= 2)) 1035 } else { 1036 /* The module is not a TIMER module */ 1037 DPRINTK("The module is not a TIMER module\n"); 1038 i_ReturnValue = -4; 1039 } 1040 } else { 1041 /* Module number error */ 1042 DPRINTK("Module number error\n"); 1043 i_ReturnValue = -2; 1044 } 1045 1046 return i_ReturnValue; 1047} 1048