4 Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
10 Fax: +49(0)7223/9493-92
11 http://www.addi-data.com
14 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
16 This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 You should also find the complete GPL in the COPYING file accompanying this source code.
26 +-----------------------------------------------------------------------+
27 | (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
28 +-----------------------------------------------------------------------+
29 | Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
30 | Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
31 +-----------------------------------------------------------------------+
32 | Project : API APCI1710 | Compiler : gcc |
33 | Module name : PWM.C | Version : 2.96 |
34 +-------------------------------+---------------------------------------+
35 | Project manager: Eric Stolz | Date : 02/12/2002 |
36 +-----------------------------------------------------------------------+
37 | Description : APCI-1710 Wulse wide modulation module |
40 +-----------------------------------------------------------------------+
42 +-----------------------------------------------------------------------+
43 | Date | Author | Description of updates |
44 +-----------------------------------------------------------------------+
45 | 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
47 +-----------------------------------------------------------------------+
50 #define APCI1710_30MHZ 30
51 #define APCI1710_33MHZ 33
52 #define APCI1710_40MHZ 40
54 #define APCI1710_PWM_INIT 0
55 #define APCI1710_PWM_GETINITDATA 1
57 #define APCI1710_PWM_DISABLE 0
58 #define APCI1710_PWM_ENABLE 1
59 #define APCI1710_PWM_NEWTIMING 2
62 +----------------------------------------------------------------------------+
63 | Function Name : _INT_ i_APCI1710_InitPWM |
64 | (unsigned char_ b_BoardHandle, |
65 | unsigned char_ b_ModulNbr, |
66 | unsigned char_ b_PWM, |
67 | unsigned char_ b_ClockSelection, |
68 | unsigned char_ b_TimingUnit, |
69 | ULONG_ ul_LowTiming, |
70 | ULONG_ ul_HighTiming, |
71 | PULONG_ pul_RealLowTiming, |
72 | PULONG_ pul_RealHighTiming) |
73 +----------------------------------------------------------------------------+
74 | Task : Configure the selected PWM (b_PWM) from selected module|
75 | (b_ModulNbr). The ul_LowTiming, ul_HighTiming and |
76 | ul_TimingUnit determine the low/high timing base for |
77 | the period. pul_RealLowTiming, pul_RealHighTiming |
78 | return the real timing value. |
79 | You must calling this function be for you call any |
80 | other function witch access of the PWM. |
81 +----------------------------------------------------------------------------+
82 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
83 | unsigned char_ b_ModulNbr : Module number to configure|
85 | unsigned char_ b_PWM : Selected PWM (0 or 1). |
86 | unsigned char_ b_ClockSelection : Selection from PCI bus |
88 | - APCI1710_30MHZ : |
89 | The PC have a 30 MHz |
91 | - APCI1710_33MHZ : |
92 | The PC have a 33 MHz |
95 | The APCI-1710 have a |
98 | unsigned char_ b_TimingUnit : Base timing Unit (0 to 4) |
104 | ULONG_ ul_LowTiming : Low base timing value. |
105 | ULONG_ ul_HighTiming : High base timing value. |
106 +----------------------------------------------------------------------------+
107 | Output Parameters : PULONG_ pul_RealLowTiming : Real low base timing |
109 | PULONG_ pul_RealHighTiming : Real high base timing |
111 +----------------------------------------------------------------------------+
112 | Return Value : 0: No error |
113 | -1: The handle parameter of the board is wrong |
114 | -2: Module selection wrong |
115 | -3: The module is not a PWM module |
116 | -4: PWM selection is wrong |
117 | -5: The selected input clock is wrong |
118 | -6: Timing Unit selection is wrong |
119 | -7: Low base timing selection is wrong |
120 | -8: High base timing selection is wrong |
121 | -9: You can not used the 40MHz clock selection with |
123 +----------------------------------------------------------------------------+
125 static int i_APCI1710_InitPWM(struct comedi_device *dev,
126 unsigned char b_ModulNbr,
128 unsigned char b_ClockSelection,
129 unsigned char b_TimingUnit,
130 unsigned int ul_LowTiming,
131 unsigned int ul_HighTiming,
132 unsigned int *pul_RealLowTiming,
133 unsigned int *pul_RealHighTiming)
135 struct addi_private *devpriv = dev->private;
136 int i_ReturnValue = 0;
137 unsigned int ul_LowTimerValue = 0;
138 unsigned int ul_HighTimerValue = 0;
139 unsigned int dw_Command;
140 double d_RealLowTiming = 0;
141 double d_RealHighTiming = 0;
143 /**************************/
144 /* Test the module number */
145 /**************************/
147 if (b_ModulNbr < 4) {
152 if ((devpriv->s_BoardInfos.
153 dw_MolduleConfiguration[b_ModulNbr] &
154 0xFFFF0000UL) == APCI1710_PWM) {
155 /**************************/
156 /* Test the PWM selection */
157 /**************************/
164 if ((b_ClockSelection == APCI1710_30MHZ) ||
165 (b_ClockSelection == APCI1710_33MHZ) ||
166 (b_ClockSelection == APCI1710_40MHZ)) {
167 /************************/
168 /* Test the timing unit */
169 /************************/
171 if (b_TimingUnit <= 4) {
172 /*********************************/
173 /* Test the low timing selection */
174 /*********************************/
176 if (((b_ClockSelection ==
185 || ((b_ClockSelection ==
194 || ((b_ClockSelection ==
203 || ((b_ClockSelection ==
212 || ((b_ClockSelection ==
220 || ((b_ClockSelection ==
229 || ((b_ClockSelection ==
238 || ((b_ClockSelection ==
247 || ((b_ClockSelection ==
256 || ((b_ClockSelection ==
264 || ((b_ClockSelection ==
273 || ((b_ClockSelection ==
282 || ((b_ClockSelection ==
291 || ((b_ClockSelection ==
300 || ((b_ClockSelection ==
309 /**********************************/
310 /* Test the High timing selection */
311 /**********************************/
313 if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
314 /**************************/
315 /* Test the board version */
316 /**************************/
318 if (((b_ClockSelection == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_ClockSelection != APCI1710_40MHZ)) {
320 /************************************/
321 /* Calculate the low division fator */
322 /************************************/
327 switch (b_TimingUnit) {
343 (0.00025 * b_ClockSelection));
345 /*******************/
346 /* Round the value */
347 /*******************/
349 if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
357 /*****************************/
358 /* Calculate the real timing */
359 /*****************************/
366 (0.00025 * (double)b_ClockSelection));
377 if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
396 if (b_ClockSelection != APCI1710_40MHZ) {
424 (0.25 * b_ClockSelection));
426 /*******************/
427 /* Round the value */
428 /*******************/
430 if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
438 /*****************************/
439 /* Calculate the real timing */
440 /*****************************/
447 (0.25 * (double)b_ClockSelection));
460 if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
479 if (b_ClockSelection != APCI1710_40MHZ) {
510 /*******************/
511 /* Round the value */
512 /*******************/
514 if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
522 /*****************************/
523 /* Calculate the real timing */
524 /*****************************/
531 (250.0 * (double)b_ClockSelection));
542 if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
561 if (b_ClockSelection != APCI1710_40MHZ) {
592 /*******************/
593 /* Round the value */
594 /*******************/
596 if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
604 /*****************************/
605 /* Calculate the real timing */
606 /*****************************/
627 if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
646 if (b_ClockSelection != APCI1710_40MHZ) {
681 /*******************/
682 /* Round the value */
683 /*******************/
685 if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
693 /*****************************/
694 /* Calculate the real timing */
695 /*****************************/
721 if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealLowTiming + 0.5)) {
740 if (b_ClockSelection != APCI1710_40MHZ) {
754 /*************************************/
755 /* Calculate the high division fator */
756 /*************************************/
758 switch (b_TimingUnit) {
774 (0.00025 * b_ClockSelection));
776 /*******************/
777 /* Round the value */
778 /*******************/
780 if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
788 /*****************************/
789 /* Calculate the real timing */
790 /*****************************/
797 (0.00025 * (double)b_ClockSelection));
808 if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
827 if (b_ClockSelection != APCI1710_40MHZ) {
855 (0.25 * b_ClockSelection));
857 /*******************/
858 /* Round the value */
859 /*******************/
861 if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
869 /*****************************/
870 /* Calculate the real timing */
871 /*****************************/
878 (0.25 * (double)b_ClockSelection));
891 if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
910 if (b_ClockSelection != APCI1710_40MHZ) {
941 /*******************/
942 /* Round the value */
943 /*******************/
945 if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
953 /*****************************/
954 /* Calculate the real timing */
955 /*****************************/
962 (250.0 * (double)b_ClockSelection));
973 if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
992 if (b_ClockSelection != APCI1710_40MHZ) {
1011 /******************/
1012 /* Timer 0 factor */
1013 /******************/
1024 /*******************/
1025 /* Round the value */
1026 /*******************/
1028 if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
1036 /*****************************/
1037 /* Calculate the real timing */
1038 /*****************************/
1059 if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
1078 if (b_ClockSelection != APCI1710_40MHZ) {
1097 /******************/
1098 /* Timer 0 factor */
1099 /******************/
1113 /*******************/
1114 /* Round the value */
1115 /*******************/
1117 if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
1125 /*****************************/
1126 /* Calculate the real timing */
1127 /*****************************/
1153 if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealHighTiming + 0.5)) {
1172 if (b_ClockSelection != APCI1710_40MHZ) {
1187 /****************************/
1188 /* Save the clock selection */
1189 /****************************/
1199 /************************/
1200 /* Save the timing unit */
1201 /************************/
1213 /****************************/
1214 /* Save the low base timing */
1215 /****************************/
1237 /****************************/
1238 /* Save the high base timing */
1239 /****************************/
1259 *pul_RealHighTiming;
1261 /************************/
1262 /* Write the low timing */
1263 /************************/
1265 outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
1267 /*************************/
1268 /* Write the high timing */
1269 /*************************/
1271 outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
1273 /***************************/
1274 /* Set the clock selection */
1275 /***************************/
1286 (20 * b_PWM) + (64 * b_ModulNbr));
1294 if (b_ClockSelection == APCI1710_40MHZ) {
1302 /***************************/
1303 /* Set the clock selection */
1304 /***************************/
1306 outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
1321 /***************************************************/
1322 /* You can not used the 40MHz clock selection with */
1324 /***************************************************/
1325 DPRINTK("You can not used the 40MHz clock selection with this board\n");
1331 /***************************************/
1332 /* High base timing selection is wrong */
1333 /***************************************/
1334 DPRINTK("High base timing selection is wrong\n");
1339 /**************************************/
1340 /* Low base timing selection is wrong */
1341 /**************************************/
1342 DPRINTK("Low base timing selection is wrong\n");
1345 } /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
1347 /**********************************/
1348 /* Timing unit selection is wrong */
1349 /**********************************/
1350 DPRINTK("Timing unit selection is wrong\n");
1352 } /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
1353 } /* if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ)) */
1355 /*******************************/
1356 /* The selected clock is wrong */
1357 /*******************************/
1358 DPRINTK("The selected clock is wrong\n");
1360 } /* if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ)) */
1361 } /* if (b_PWM >= 0 && b_PWM <= 1) */
1363 /******************************/
1364 /* Tor PWM selection is wrong */
1365 /******************************/
1366 DPRINTK("Tor PWM selection is wrong\n");
1368 } /* if (b_PWM >= 0 && b_PWM <= 1) */
1370 /**********************************/
1371 /* The module is not a PWM module */
1372 /**********************************/
1373 DPRINTK("The module is not a PWM module\n");
1377 /***********************/
1378 /* Module number error */
1379 /***********************/
1380 DPRINTK("Module number error\n");
1384 return i_ReturnValue;
1388 +----------------------------------------------------------------------------+
1389 | Function Name : _INT_ i_APCI1710_GetPWMInitialisation |
1390 | (unsigned char_ b_BoardHandle, |
1391 | unsigned char_ b_ModulNbr, |
1392 | unsigned char_ b_PWM, |
1393 | unsigned char *_ pb_TimingUnit, |
1394 | PULONG_ pul_LowTiming, |
1395 | PULONG_ pul_HighTiming, |
1396 | unsigned char *_ pb_StartLevel, |
1397 | unsigned char *_ pb_StopMode, |
1398 | unsigned char *_ pb_StopLevel, |
1399 | unsigned char *_ pb_ExternGate, |
1400 | unsigned char *_ pb_InterruptEnable, |
1401 | unsigned char *_ pb_Enable) |
1402 +----------------------------------------------------------------------------+
1403 | Task : Return the PWM (b_PWM) initialisation from selected |
1404 | module (b_ModulNbr). You must calling the |
1405 | "i_APCI1710_InitPWM" function be for you call this |
1407 +----------------------------------------------------------------------------+
1408 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
1409 | unsigned char_ b_ModulNbr : Selected module number (0 to 3) |
1410 | unsigned char_ b_PWM : Selected PWM (0 or 1) |
1411 +----------------------------------------------------------------------------+
1412 | Output Parameters : unsigned char *_ pb_TimingUnit : Base timing Unit (0 to 4) |
1418 | PULONG_ pul_LowTiming : Low base timing value. |
1419 | PULONG_ pul_HighTiming : High base timing value. |
1420 | unsigned char *_ pb_StartLevel : Start period level |
1422 | 0 : The period start |
1423 | with a low level |
1424 | 1 : The period start |
1425 | with a high level|
1426 | unsigned char *_ pb_StopMode : Stop mode selection |
1427 | 0 : The PWM is stopped |
1428 | directly after the |
1429 | "i_APCI1710_DisablePWM"|
1430 | function and break the|
1433 | "i_APCI1710_DisablePWM"|
1434 | function the PWM is |
1435 | stopped at the end |
1436 | from last period cycle|
1437 | unsigned char *_ pb_StopLevel : Stop PWM level selection |
1438 | 0 : The output signal |
1439 | keep the level after|
1441 | "i_APCI1710_DisablePWM"|
1443 | 1 : The output signal is|
1444 | set to low after the|
1445 | "i_APCI1710_DisablePWM"|
1447 | 2 : The output signal is|
1448 | set to high after |
1450 | "i_APCI1710_DisablePWM"|
1452 | unsigned char *_ pb_ExternGate : Extern gate action |
1454 | 0 : Extern gate signal |
1456 | 1 : Extern gate signal |
1458 | unsigned char *_ pb_InterruptEnable : Enable or disable the PWM |
1460 | - APCI1710_ENABLE : |
1461 | Enable the PWM interrupt|
1462 | A interrupt occur after |
1464 | - APCI1710_DISABLE : |
1467 | unsigned char *_ pb_Enable : Indicate if the PWM is |
1469 | 0 : PWM not enabled |
1471 +----------------------------------------------------------------------------+
1472 | Return Value : 0: No error |
1473 | -1: The handle parameter of the board is wrong |
1474 | -2: Module selection wrong |
1475 | -3: The module is not a PWM module |
1476 | -4: PWM selection is wrong |
1477 | -5: PWM not initialised see function |
1478 | "i_APCI1710_InitPWM" |
1479 +----------------------------------------------------------------------------+
1481 static int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
1482 unsigned char b_ModulNbr,
1483 unsigned char b_PWM,
1484 unsigned char *pb_TimingUnit,
1485 unsigned int *pul_LowTiming,
1486 unsigned int *pul_HighTiming,
1487 unsigned char *pb_StartLevel,
1488 unsigned char *pb_StopMode,
1489 unsigned char *pb_StopLevel,
1490 unsigned char *pb_ExternGate,
1491 unsigned char *pb_InterruptEnable,
1492 unsigned char *pb_Enable)
1494 struct addi_private *devpriv = dev->private;
1495 int i_ReturnValue = 0;
1496 unsigned int dw_Status;
1497 unsigned int dw_Command;
1499 /**************************/
1500 /* Test the module number */
1501 /**************************/
1503 if (b_ModulNbr < 4) {
1508 if ((devpriv->s_BoardInfos.
1509 dw_MolduleConfiguration[b_ModulNbr] &
1510 0xFFFF0000UL) == APCI1710_PWM) {
1511 /**************************/
1512 /* Test the PWM selection */
1513 /**************************/
1516 /***************************/
1517 /* Test if PWM initialised */
1518 /***************************/
1520 dw_Status = inl(devpriv->s_BoardInfos.
1521 ui_Address + 12 + (20 * b_PWM) +
1524 if (dw_Status & 0x10) {
1525 /***********************/
1526 /* Read the low timing */
1527 /***********************/
1530 inl(devpriv->s_BoardInfos.
1531 ui_Address + 0 + (20 * b_PWM) +
1534 /************************/
1535 /* Read the high timing */
1536 /************************/
1539 inl(devpriv->s_BoardInfos.
1540 ui_Address + 4 + (20 * b_PWM) +
1543 /********************/
1544 /* Read the command */
1545 /********************/
1547 dw_Command = inl(devpriv->s_BoardInfos.
1548 ui_Address + 8 + (20 * b_PWM) +
1552 (unsigned char) ((dw_Command >> 5) & 1);
1554 (unsigned char) ((dw_Command >> 0) & 1);
1556 (unsigned char) ((dw_Command >> 1) & 1);
1558 (unsigned char) ((dw_Command >> 4) & 1);
1559 *pb_InterruptEnable =
1560 (unsigned char) ((dw_Command >> 3) & 1);
1562 if (*pb_StopLevel) {
1565 (unsigned char) ((dw_Command >>
1569 /********************/
1570 /* Read the command */
1571 /********************/
1573 dw_Command = inl(devpriv->s_BoardInfos.
1574 ui_Address + 8 + (20 * b_PWM) +
1578 (unsigned char) ((dw_Command >> 0) & 1);
1580 *pb_TimingUnit = devpriv->
1581 s_ModuleInfo[b_ModulNbr].
1583 s_PWMInfo[b_PWM].b_TimingUnit;
1584 } /* if (dw_Status & 0x10) */
1586 /***********************/
1587 /* PWM not initialised */
1588 /***********************/
1589 DPRINTK("PWM not initialised\n");
1591 } /* if (dw_Status & 0x10) */
1592 } /* if (b_PWM >= 0 && b_PWM <= 1) */
1594 /******************************/
1595 /* Tor PWM selection is wrong */
1596 /******************************/
1597 DPRINTK("Tor PWM selection is wrong\n");
1599 } /* if (b_PWM >= 0 && b_PWM <= 1) */
1601 /**********************************/
1602 /* The module is not a PWM module */
1603 /**********************************/
1604 DPRINTK("The module is not a PWM module\n");
1608 /***********************/
1609 /* Module number error */
1610 /***********************/
1611 DPRINTK("Module number error\n");
1615 return i_ReturnValue;
1619 * Pwm Init and Get Pwm Initialisation
1621 static int i_APCI1710_InsnConfigPWM(struct comedi_device *dev,
1622 struct comedi_subdevice *s,
1623 struct comedi_insn *insn,
1626 unsigned char b_ConfigType;
1627 int i_ReturnValue = 0;
1628 b_ConfigType = CR_CHAN(insn->chanspec);
1630 switch (b_ConfigType) {
1631 case APCI1710_PWM_INIT:
1632 i_ReturnValue = i_APCI1710_InitPWM(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */
1633 (unsigned char) data[0], /* b_PWM */
1634 (unsigned char) data[1], /* b_ClockSelection */
1635 (unsigned char) data[2], /* b_TimingUnit */
1636 (unsigned int) data[3], /* ul_LowTiming */
1637 (unsigned int) data[4], /* ul_HighTiming */
1638 (unsigned int *) &data[0], /* pul_RealLowTiming */
1639 (unsigned int *) &data[1] /* pul_RealHighTiming */
1643 case APCI1710_PWM_GETINITDATA:
1644 i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */
1645 (unsigned char) data[0], /* b_PWM */
1646 (unsigned char *) &data[0], /* pb_TimingUnit */
1647 (unsigned int *) &data[1], /* pul_LowTiming */
1648 (unsigned int *) &data[2], /* pul_HighTiming */
1649 (unsigned char *) &data[3], /* pb_StartLevel */
1650 (unsigned char *) &data[4], /* pb_StopMode */
1651 (unsigned char *) &data[5], /* pb_StopLevel */
1652 (unsigned char *) &data[6], /* pb_ExternGate */
1653 (unsigned char *) &data[7], /* pb_InterruptEnable */
1654 (unsigned char *) &data[8] /* pb_Enable */
1659 printk(" Config Parameter Wrong\n");
1662 if (i_ReturnValue >= 0)
1663 i_ReturnValue = insn->n;
1664 return i_ReturnValue;
1668 +----------------------------------------------------------------------------+
1669 | Function Name : _INT_ i_APCI1710_EnablePWM |
1670 | (unsigned char_ b_BoardHandle, |
1671 | unsigned char_ b_ModulNbr, |
1672 | unsigned char_ b_PWM, |
1673 | unsigned char_ b_StartLevel, |
1674 | unsigned char_ b_StopMode, |
1675 | unsigned char_ b_StopLevel, |
1676 | unsigned char_ b_ExternGate, |
1677 | unsigned char_ b_InterruptEnable) |
1678 +----------------------------------------------------------------------------+
1679 | Task : Enable the selected PWM (b_PWM) from selected module |
1680 | (b_ModulNbr). You must calling the "i_APCI1710_InitPWM"|
1681 | function be for you call this function. |
1682 | If you enable the PWM interrupt, the PWM generate a |
1683 | interrupt after each period. |
1684 | See function "i_APCI1710_SetBoardIntRoutineX" and the |
1685 | Interrupt mask description chapter. |
1686 +----------------------------------------------------------------------------+
1687 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
1688 | unsigned char_ b_ModulNbr : Selected module number |
1690 | unsigned char_ b_PWM : Selected PWM (0 or 1) |
1691 | unsigned char_ b_StartLevel : Start period level selection |
1692 | 0 : The period start with a |
1694 | 1 : The period start with a |
1696 | unsigned char_ b_StopMode : Stop mode selection |
1697 | 0 : The PWM is stopped |
1698 | directly after the |
1699 | "i_APCI1710_DisablePWM" |
1700 | function and break the |
1703 | "i_APCI1710_DisablePWM" |
1704 | function the PWM is |
1705 | stopped at the end from|
1706 | last period cycle. |
1707 | unsigned char_ b_StopLevel : Stop PWM level selection |
1708 | 0 : The output signal keep |
1709 | the level after the |
1710 | "i_APCI1710_DisablePWM" |
1712 | 1 : The output signal is set|
1713 | to low after the |
1714 | "i_APCI1710_DisablePWM" |
1716 | 2 : The output signal is set|
1717 | to high after the |
1718 | "i_APCI1710_DisablePWM" |
1720 | unsigned char_ b_ExternGate : Extern gate action selection |
1721 | 0 : Extern gate signal not |
1723 | 1 : Extern gate signal used.|
1724 | unsigned char_ b_InterruptEnable : Enable or disable the PWM |
1726 | - APCI1710_ENABLE : |
1727 | Enable the PWM interrupt |
1728 | A interrupt occur after |
1730 | - APCI1710_DISABLE : |
1731 | Disable the PWM interrupt |
1732 +----------------------------------------------------------------------------+
1733 | Output Parameters : - |
1734 +----------------------------------------------------------------------------+
1735 | Return Value : 0: No error |
1736 | -1: The handle parameter of the board is wrong |
1737 | -2: Module selection wrong |
1738 | -3: The module is not a PWM module |
1739 | -4: PWM selection is wrong |
1740 | -5: PWM not initialised see function |
1741 | "i_APCI1710_InitPWM" |
1742 | -6: PWM start level selection is wrong |
1743 | -7: PWM stop mode selection is wrong |
1744 | -8: PWM stop level selection is wrong |
1745 | -9: Extern gate signal selection is wrong |
1746 | -10: Interrupt parameter is wrong |
1747 | -11: Interrupt function not initialised. |
1748 | See function "i_APCI1710_SetBoardIntRoutineX" |
1749 +----------------------------------------------------------------------------+
1751 static int i_APCI1710_EnablePWM(struct comedi_device *dev,
1752 unsigned char b_ModulNbr,
1753 unsigned char b_PWM,
1754 unsigned char b_StartLevel,
1755 unsigned char b_StopMode,
1756 unsigned char b_StopLevel,
1757 unsigned char b_ExternGate,
1758 unsigned char b_InterruptEnable)
1760 struct addi_private *devpriv = dev->private;
1761 int i_ReturnValue = 0;
1762 unsigned int dw_Status;
1763 unsigned int dw_Command;
1765 devpriv->tsk_Current = current; /* Save the current process task structure */
1766 /**************************/
1767 /* Test the module number */
1768 /**************************/
1770 if (b_ModulNbr < 4) {
1775 if ((devpriv->s_BoardInfos.
1776 dw_MolduleConfiguration[b_ModulNbr] &
1777 0xFFFF0000UL) == APCI1710_PWM) {
1778 /**************************/
1779 /* Test the PWM selection */
1780 /**************************/
1783 /***************************/
1784 /* Test if PWM initialised */
1785 /***************************/
1787 dw_Status = inl(devpriv->s_BoardInfos.
1788 ui_Address + 12 + (20 * b_PWM) +
1791 if (dw_Status & 0x10) {
1792 /**********************************/
1793 /* Test the start level selection */
1794 /**********************************/
1796 if (b_StartLevel <= 1) {
1797 /**********************/
1798 /* Test the stop mode */
1799 /**********************/
1801 if (b_StopMode <= 1) {
1802 /***********************/
1803 /* Test the stop level */
1804 /***********************/
1806 if (b_StopLevel <= 2) {
1807 /*****************************/
1808 /* Test the extern gate mode */
1809 /*****************************/
1813 /*****************************/
1814 /* Test the interrupt action */
1815 /*****************************/
1817 if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) {
1818 /******************************************/
1819 /* Test if interrupt function initialised */
1820 /******************************************/
1822 /********************/
1823 /* Read the command */
1824 /********************/
1835 (20 * b_PWM) + (64 * b_ModulNbr));
1843 /********************/
1844 /* Make the command */
1845 /********************/
1865 if (b_StopLevel & 3) {
1872 if (b_StopLevel & 2) {
1891 /*******************/
1892 /* Set the command */
1893 /*******************/
1895 outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
1897 /******************/
1898 /* Enable the PWM */
1899 /******************/
1900 outl(1, devpriv->s_BoardInfos.ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
1901 } /* if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) */
1903 /********************************/
1904 /* Interrupt parameter is wrong */
1905 /********************************/
1906 DPRINTK("Interrupt parameter is wrong\n");
1910 } /* if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) */
1911 } /* if (b_ExternGate >= 0 && b_ExternGate <= 1) */
1913 /*****************************************/
1914 /* Extern gate signal selection is wrong */
1915 /*****************************************/
1916 DPRINTK("Extern gate signal selection is wrong\n");
1920 } /* if (b_ExternGate >= 0 && b_ExternGate <= 1) */
1921 } /* if (b_StopLevel >= 0 && b_StopLevel <= 2) */
1923 /*************************************/
1924 /* PWM stop level selection is wrong */
1925 /*************************************/
1926 DPRINTK("PWM stop level selection is wrong\n");
1929 } /* if (b_StopLevel >= 0 && b_StopLevel <= 2) */
1930 } /* if (b_StopMode >= 0 && b_StopMode <= 1) */
1932 /************************************/
1933 /* PWM stop mode selection is wrong */
1934 /************************************/
1935 DPRINTK("PWM stop mode selection is wrong\n");
1937 } /* if (b_StopMode >= 0 && b_StopMode <= 1) */
1938 } /* if (b_StartLevel >= 0 && b_StartLevel <= 1) */
1940 /**************************************/
1941 /* PWM start level selection is wrong */
1942 /**************************************/
1943 DPRINTK("PWM start level selection is wrong\n");
1945 } /* if (b_StartLevel >= 0 && b_StartLevel <= 1) */
1946 } /* if (dw_Status & 0x10) */
1948 /***********************/
1949 /* PWM not initialised */
1950 /***********************/
1951 DPRINTK("PWM not initialised\n");
1953 } /* if (dw_Status & 0x10) */
1954 } /* if (b_PWM >= 0 && b_PWM <= 1) */
1956 /******************************/
1957 /* Tor PWM selection is wrong */
1958 /******************************/
1959 DPRINTK("Tor PWM selection is wrong\n");
1961 } /* if (b_PWM >= 0 && b_PWM <= 1) */
1963 /**********************************/
1964 /* The module is not a PWM module */
1965 /**********************************/
1966 DPRINTK("The module is not a PWM module\n");
1970 /***********************/
1971 /* Module number error */
1972 /***********************/
1973 DPRINTK("Module number error\n");
1977 return i_ReturnValue;
1981 +----------------------------------------------------------------------------+
1982 | Function Name : _INT_ i_APCI1710_DisablePWM (unsigned char_ b_BoardHandle, |
1983 | unsigned char_ b_ModulNbr, |
1984 | unsigned char_ b_PWM) |
1985 +----------------------------------------------------------------------------+
1986 | Task : Disable the selected PWM (b_PWM) from selected module |
1987 | (b_ModulNbr). The output signal level depend of the |
1988 | initialisation by the "i_APCI1710_EnablePWM". |
1989 | See the b_StartLevel, b_StopMode and b_StopLevel |
1990 | parameters from this function. |
1991 +----------------------------------------------------------------------------+
1992 | Input Parameters :BYTE_ b_BoardHandle : Handle of board APCI-1710 |
1993 | unsigned char_ b_ModulNbr : Selected module number (0 to 3) |
1994 | unsigned char_ b_PWM : Selected PWM (0 or 1) |
1995 +----------------------------------------------------------------------------+
1996 | Output Parameters : - |
1997 +----------------------------------------------------------------------------+
1998 | Return Value : 0: No error |
1999 | -1: The handle parameter of the board is wrong |
2000 | -2: Module selection wrong |
2001 | -3: The module is not a PWM module |
2002 | -4: PWM selection is wrong |
2003 | -5: PWM not initialised see function |
2004 | "i_APCI1710_InitPWM" |
2005 | -6: PWM not enabled see function |
2006 | "i_APCI1710_EnablePWM" |
2007 +----------------------------------------------------------------------------+
2009 static int i_APCI1710_DisablePWM(struct comedi_device *dev,
2010 unsigned char b_ModulNbr,
2011 unsigned char b_PWM)
2013 struct addi_private *devpriv = dev->private;
2014 int i_ReturnValue = 0;
2015 unsigned int dw_Status;
2017 /**************************/
2018 /* Test the module number */
2019 /**************************/
2021 if (b_ModulNbr < 4) {
2026 if ((devpriv->s_BoardInfos.
2027 dw_MolduleConfiguration[b_ModulNbr] &
2028 0xFFFF0000UL) == APCI1710_PWM) {
2029 /**************************/
2030 /* Test the PWM selection */
2031 /**************************/
2034 /***************************/
2035 /* Test if PWM initialised */
2036 /***************************/
2038 dw_Status = inl(devpriv->s_BoardInfos.
2039 ui_Address + 12 + (20 * b_PWM) +
2042 if (dw_Status & 0x10) {
2043 /***********************/
2044 /* Test if PWM enabled */
2045 /***********************/
2047 if (dw_Status & 0x1) {
2048 /*******************/
2049 /* Disable the PWM */
2050 /*******************/
2051 outl(0, devpriv->s_BoardInfos.
2055 } /* if (dw_Status & 0x1) */
2057 /*******************/
2058 /* PWM not enabled */
2059 /*******************/
2060 DPRINTK("PWM not enabled\n");
2062 } /* if (dw_Status & 0x1) */
2063 } /* if (dw_Status & 0x10) */
2065 /***********************/
2066 /* PWM not initialised */
2067 /***********************/
2068 DPRINTK(" PWM not initialised\n");
2070 } /* if (dw_Status & 0x10) */
2071 } /* if (b_PWM >= 0 && b_PWM <= 1) */
2073 /******************************/
2074 /* Tor PWM selection is wrong */
2075 /******************************/
2076 DPRINTK("Tor PWM selection is wrong\n");
2078 } /* if (b_PWM >= 0 && b_PWM <= 1) */
2080 /**********************************/
2081 /* The module is not a PWM module */
2082 /**********************************/
2083 DPRINTK("The module is not a PWM module\n");
2087 /***********************/
2088 /* Module number error */
2089 /***********************/
2090 DPRINTK("Module number error\n");
2094 return i_ReturnValue;
2098 +----------------------------------------------------------------------------+
2099 | Function Name : _INT_ i_APCI1710_SetNewPWMTiming |
2100 | (unsigned char_ b_BoardHandle, |
2101 | unsigned char_ b_ModulNbr, |
2102 | unsigned char_ b_PWM, |
2103 | unsigned char_ b_ClockSelection, |
2104 | unsigned char_ b_TimingUnit, |
2105 | ULONG_ ul_LowTiming, |
2106 | ULONG_ ul_HighTiming) |
2107 +----------------------------------------------------------------------------+
2108 | Task : Set a new timing. The ul_LowTiming, ul_HighTiming and |
2109 | ul_TimingUnit determine the low/high timing base for |
2111 +----------------------------------------------------------------------------+
2112 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
2113 | unsigned char_ b_ModulNbr : Module number to configure|
2115 | unsigned char_ b_PWM : Selected PWM (0 or 1). |
2116 | unsigned char_ b_TimingUnit : Base timing Unit (0 to 4) |
2122 | ULONG_ ul_LowTiming : Low base timing value. |
2123 | ULONG_ ul_HighTiming : High base timing value. |
2124 +----------------------------------------------------------------------------+
2125 | Output Parameters : - |
2126 +----------------------------------------------------------------------------+
2127 | Return Value : 0: No error |
2128 | -1: The handle parameter of the board is wrong |
2129 | -2: Module selection wrong |
2130 | -3: The module is not a PWM module |
2131 | -4: PWM selection is wrong |
2132 | -5: PWM not initialised |
2133 | -6: Timing Unit selection is wrong |
2134 | -7: Low base timing selection is wrong |
2135 | -8: High base timing selection is wrong |
2136 +----------------------------------------------------------------------------+
2138 static int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
2139 unsigned char b_ModulNbr,
2140 unsigned char b_PWM,
2141 unsigned char b_TimingUnit,
2142 unsigned int ul_LowTiming,
2143 unsigned int ul_HighTiming)
2145 struct addi_private *devpriv = dev->private;
2146 unsigned char b_ClockSelection;
2147 int i_ReturnValue = 0;
2148 unsigned int ul_LowTimerValue = 0;
2149 unsigned int ul_HighTimerValue = 0;
2150 unsigned int ul_RealLowTiming = 0;
2151 unsigned int ul_RealHighTiming = 0;
2152 unsigned int dw_Status;
2153 unsigned int dw_Command;
2154 double d_RealLowTiming = 0;
2155 double d_RealHighTiming = 0;
2157 /**************************/
2158 /* Test the module number */
2159 /**************************/
2161 if (b_ModulNbr < 4) {
2166 if ((devpriv->s_BoardInfos.
2167 dw_MolduleConfiguration[b_ModulNbr] &
2168 0xFFFF0000UL) == APCI1710_PWM) {
2169 /**************************/
2170 /* Test the PWM selection */
2171 /**************************/
2174 /***************************/
2175 /* Test if PWM initialised */
2176 /***************************/
2178 dw_Status = inl(devpriv->s_BoardInfos.
2179 ui_Address + 12 + (20 * b_PWM) +
2182 if (dw_Status & 0x10) {
2183 b_ClockSelection = devpriv->
2184 s_ModuleInfo[b_ModulNbr].
2188 /************************/
2189 /* Test the timing unit */
2190 /************************/
2192 if (b_TimingUnit <= 4) {
2193 /*********************************/
2194 /* Test the low timing selection */
2195 /*********************************/
2197 if (((b_ClockSelection ==
2206 || ((b_ClockSelection ==
2215 || ((b_ClockSelection ==
2224 || ((b_ClockSelection ==
2233 || ((b_ClockSelection ==
2241 || ((b_ClockSelection ==
2250 || ((b_ClockSelection ==
2259 || ((b_ClockSelection ==
2268 || ((b_ClockSelection ==
2277 || ((b_ClockSelection ==
2285 || ((b_ClockSelection ==
2294 || ((b_ClockSelection ==
2303 || ((b_ClockSelection ==
2312 || ((b_ClockSelection ==
2321 || ((b_ClockSelection ==
2330 /**********************************/
2331 /* Test the High timing selection */
2332 /**********************************/
2334 if (((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 266) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230650UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571230UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 571UL)) || ((b_ClockSelection == APCI1710_30MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 9UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 242) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691043UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 519691UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 520UL)) || ((b_ClockSelection == APCI1710_33MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 8UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 0) && (ul_HighTiming >= 200) && (ul_HighTiming <= 0xFFFFFFFFUL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 1) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496729UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 2) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429496UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 3) && (ul_HighTiming >= 1) && (ul_HighTiming <= 429UL)) || ((b_ClockSelection == APCI1710_40MHZ) && (b_TimingUnit == 4) && (ul_HighTiming >= 1) && (ul_HighTiming <= 7UL))) {
2335 /************************************/
2336 /* Calculate the low division fator */
2337 /************************************/
2340 switch (b_TimingUnit) {
2347 /******************/
2348 /* Timer 0 factor */
2349 /******************/
2356 (0.00025 * b_ClockSelection));
2358 /*******************/
2359 /* Round the value */
2360 /*******************/
2362 if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2370 /*****************************/
2371 /* Calculate the real timing */
2372 /*****************************/
2379 (0.00025 * (double)b_ClockSelection));
2390 if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
2409 if (b_ClockSelection != APCI1710_40MHZ) {
2428 /******************/
2429 /* Timer 0 factor */
2430 /******************/
2437 (0.25 * b_ClockSelection));
2439 /*******************/
2440 /* Round the value */
2441 /*******************/
2443 if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2451 /*****************************/
2452 /* Calculate the real timing */
2453 /*****************************/
2460 (0.25 * (double)b_ClockSelection));
2473 if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
2492 if (b_ClockSelection != APCI1710_40MHZ) {
2511 /******************/
2512 /* Timer 0 factor */
2513 /******************/
2523 /*******************/
2524 /* Round the value */
2525 /*******************/
2527 if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2535 /*****************************/
2536 /* Calculate the real timing */
2537 /*****************************/
2544 (250.0 * (double)b_ClockSelection));
2555 if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
2574 if (b_ClockSelection != APCI1710_40MHZ) {
2593 /******************/
2594 /* Timer 0 factor */
2595 /******************/
2606 /*******************/
2607 /* Round the value */
2608 /*******************/
2610 if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2618 /*****************************/
2619 /* Calculate the real timing */
2620 /*****************************/
2641 if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
2660 if (b_ClockSelection != APCI1710_40MHZ) {
2679 /******************/
2680 /* Timer 0 factor */
2681 /******************/
2695 /*******************/
2696 /* Round the value */
2697 /*******************/
2699 if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
2707 /*****************************/
2708 /* Calculate the real timing */
2709 /*****************************/
2735 if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealLowTiming + 0.5)) {
2754 if (b_ClockSelection != APCI1710_40MHZ) {
2768 /*************************************/
2769 /* Calculate the high division fator */
2770 /*************************************/
2772 switch (b_TimingUnit) {
2779 /******************/
2780 /* Timer 0 factor */
2781 /******************/
2788 (0.00025 * b_ClockSelection));
2790 /*******************/
2791 /* Round the value */
2792 /*******************/
2794 if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
2802 /*****************************/
2803 /* Calculate the real timing */
2804 /*****************************/
2811 (0.00025 * (double)b_ClockSelection));
2822 if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
2841 if (b_ClockSelection != APCI1710_40MHZ) {
2860 /******************/
2861 /* Timer 0 factor */
2862 /******************/
2869 (0.25 * b_ClockSelection));
2871 /*******************/
2872 /* Round the value */
2873 /*******************/
2875 if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
2883 /*****************************/
2884 /* Calculate the real timing */
2885 /*****************************/
2892 (0.25 * (double)b_ClockSelection));
2905 if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
2924 if (b_ClockSelection != APCI1710_40MHZ) {
2943 /******************/
2944 /* Timer 0 factor */
2945 /******************/
2955 /*******************/
2956 /* Round the value */
2957 /*******************/
2959 if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
2967 /*****************************/
2968 /* Calculate the real timing */
2969 /*****************************/
2976 (250.0 * (double)b_ClockSelection));
2987 if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
3006 if (b_ClockSelection != APCI1710_40MHZ) {
3025 /******************/
3026 /* Timer 0 factor */
3027 /******************/
3038 /*******************/
3039 /* Round the value */
3040 /*******************/
3042 if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
3050 /*****************************/
3051 /* Calculate the real timing */
3052 /*****************************/
3073 if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
3092 if (b_ClockSelection != APCI1710_40MHZ) {
3111 /******************/
3112 /* Timer 0 factor */
3113 /******************/
3127 /*******************/
3128 /* Round the value */
3129 /*******************/
3131 if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
3139 /*****************************/
3140 /* Calculate the real timing */
3141 /*****************************/
3167 if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealHighTiming + 0.5)) {
3186 if (b_ClockSelection != APCI1710_40MHZ) {
3202 /************************/
3203 /* Save the timing unit */
3204 /************************/
3216 /****************************/
3217 /* Save the low base timing */
3218 /****************************/
3240 /****************************/
3241 /* Save the high base timing */
3242 /****************************/
3264 /************************/
3265 /* Write the low timing */
3266 /************************/
3268 outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
3270 /*************************/
3271 /* Write the high timing */
3272 /*************************/
3274 outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
3276 /***************************/
3277 /* Set the clock selection */
3278 /***************************/
3286 (20 * b_PWM) + (64 * b_ModulNbr));
3292 if (b_ClockSelection == APCI1710_40MHZ) {
3300 /***************************/
3301 /* Set the clock selection */
3302 /***************************/
3309 (20 * b_PWM) + (64 * b_ModulNbr));
3311 /***************************************/
3312 /* High base timing selection is wrong */
3313 /***************************************/
3314 DPRINTK("High base timing selection is wrong\n");
3319 /**************************************/
3320 /* Low base timing selection is wrong */
3321 /**************************************/
3322 DPRINTK("Low base timing selection is wrong\n");
3325 } /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
3327 /**********************************/
3328 /* Timing unit selection is wrong */
3329 /**********************************/
3330 DPRINTK("Timing unit selection is wrong\n");
3332 } /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
3333 } /* if (dw_Status & 0x10) */
3335 /***********************/
3336 /* PWM not initialised */
3337 /***********************/
3338 DPRINTK("PWM not initialised\n");
3340 } /* if (dw_Status & 0x10) */
3341 } /* if (b_PWM >= 0 && b_PWM <= 1) */
3343 /******************************/
3344 /* Tor PWM selection is wrong */
3345 /******************************/
3346 DPRINTK("Tor PWM selection is wrong\n");
3348 } /* if (b_PWM >= 0 && b_PWM <= 1) */
3350 /**********************************/
3351 /* The module is not a PWM module */
3352 /**********************************/
3353 DPRINTK("The module is not a PWM module\n");
3357 /***********************/
3358 /* Module number error */
3359 /***********************/
3360 DPRINTK("Module number error\n");
3364 return i_ReturnValue;
3368 * Pwm Enable Disable and Set New Timing
3370 static int i_APCI1710_InsnWritePWM(struct comedi_device *dev,
3371 struct comedi_subdevice *s,
3372 struct comedi_insn *insn,
3375 unsigned char b_WriteType;
3376 int i_ReturnValue = 0;
3377 b_WriteType = CR_CHAN(insn->chanspec);
3379 switch (b_WriteType) {
3380 case APCI1710_PWM_ENABLE:
3381 i_ReturnValue = i_APCI1710_EnablePWM(dev,
3382 (unsigned char) CR_AREF(insn->chanspec),
3383 (unsigned char) data[0],
3384 (unsigned char) data[1],
3385 (unsigned char) data[2],
3386 (unsigned char) data[3], (unsigned char) data[4], (unsigned char) data[5]);
3389 case APCI1710_PWM_DISABLE:
3390 i_ReturnValue = i_APCI1710_DisablePWM(dev,
3391 (unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
3394 case APCI1710_PWM_NEWTIMING:
3395 i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev,
3396 (unsigned char) CR_AREF(insn->chanspec),
3397 (unsigned char) data[0],
3398 (unsigned char) data[1], (unsigned int) data[2], (unsigned int) data[3]);
3402 printk("Write Config Parameter Wrong\n");
3405 if (i_ReturnValue >= 0)
3406 i_ReturnValue = insn->n;
3407 return i_ReturnValue;
3411 +----------------------------------------------------------------------------+
3412 | Function Name : _INT_ i_APCI1710_GetPWMStatus |
3413 | (unsigned char_ b_BoardHandle, |
3414 | unsigned char_ b_ModulNbr, |
3415 | unsigned char_ b_PWM, |
3416 | unsigned char *_ pb_PWMOutputStatus, |
3417 | unsigned char *_ pb_ExternGateStatus) |
3418 +----------------------------------------------------------------------------+
3419 | Task : Return the status from selected PWM (b_PWM) from |
3420 | selected module (b_ModulNbr). |
3421 +----------------------------------------------------------------------------+
3422 | Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
3423 | unsigned char_ b_PWM : Selected PWM (0 or 1) |
3424 | unsigned char_ b_ModulNbr : Selected module number (0 to 3)
3425 b_ModulNbr =(unsigned char) CR_AREF(insn->chanspec);
3426 b_PWM =(unsigned char) data[0];
3429 +----------------------------------------------------------------------------+
3430 | Output Parameters : unsigned char *_ pb_PWMOutputStatus : Return the PWM output |
3432 | 0 : The PWM output level|
3434 | 1 : The PWM output level|
3436 | unsigned char *_ pb_ExternGateStatus : Return the extern gate |
3438 | 0 : The extern gate is |
3440 | 1 : The extern gate is |
3442 pb_PWMOutputStatus =(unsigned char *) data[0];
3443 pb_ExternGateStatus =(unsigned char *) data[1]; |
3444 +----------------------------------------------------------------------------+
3445 | Return Value : 0: No error |
3446 | -1: The handle parameter of the board is wrong |
3447 | -2: Module selection wrong |
3448 | -3: The module is not a PWM module |
3449 | -4: PWM selection is wrong |
3450 | -5: PWM not initialised see function |
3451 | "i_APCI1710_InitPWM" |
3452 | -6: PWM not enabled see function "i_APCI1710_EnablePWM"|
3453 +----------------------------------------------------------------------------+
3455 static int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev,
3456 struct comedi_subdevice *s,
3457 struct comedi_insn *insn,
3460 struct addi_private *devpriv = dev->private;
3461 int i_ReturnValue = 0;
3462 unsigned int dw_Status;
3463 unsigned char b_ModulNbr;
3464 unsigned char b_PWM;
3465 unsigned char *pb_PWMOutputStatus;
3466 unsigned char *pb_ExternGateStatus;
3468 i_ReturnValue = insn->n;
3469 b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
3470 b_PWM = (unsigned char) CR_CHAN(insn->chanspec);
3471 pb_PWMOutputStatus = (unsigned char *) &data[0];
3472 pb_ExternGateStatus = (unsigned char *) &data[1];
3474 /**************************/
3475 /* Test the module number */
3476 /**************************/
3478 if (b_ModulNbr < 4) {
3483 if ((devpriv->s_BoardInfos.
3484 dw_MolduleConfiguration[b_ModulNbr] &
3485 0xFFFF0000UL) == APCI1710_PWM) {
3486 /**************************/
3487 /* Test the PWM selection */
3488 /**************************/
3491 /***************************/
3492 /* Test if PWM initialised */
3493 /***************************/
3495 dw_Status = inl(devpriv->s_BoardInfos.
3496 ui_Address + 12 + (20 * b_PWM) +
3499 if (dw_Status & 0x10) {
3500 /***********************/
3501 /* Test if PWM enabled */
3502 /***********************/
3504 if (dw_Status & 0x1) {
3505 *pb_PWMOutputStatus =
3506 (unsigned char) ((dw_Status >> 7)
3508 *pb_ExternGateStatus =
3509 (unsigned char) ((dw_Status >> 6)
3511 } /* if (dw_Status & 0x1) */
3513 /*******************/
3514 /* PWM not enabled */
3515 /*******************/
3517 DPRINTK("PWM not enabled \n");
3519 } /* if (dw_Status & 0x1) */
3520 } /* if (dw_Status & 0x10) */
3522 /***********************/
3523 /* PWM not initialised */
3524 /***********************/
3526 DPRINTK("PWM not initialised\n");
3528 } /* if (dw_Status & 0x10) */
3529 } /* if (b_PWM >= 0 && b_PWM <= 1) */
3531 /******************************/
3532 /* Tor PWM selection is wrong */
3533 /******************************/
3535 DPRINTK("Tor PWM selection is wrong\n");
3537 } /* if (b_PWM >= 0 && b_PWM <= 1) */
3539 /**********************************/
3540 /* The module is not a PWM module */
3541 /**********************************/
3543 DPRINTK("The module is not a PWM module\n");
3547 /***********************/
3548 /* Module number error */
3549 /***********************/
3551 DPRINTK("Module number error\n");
3555 return i_ReturnValue;
3558 static int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev,
3559 struct comedi_subdevice *s,
3560 struct comedi_insn *insn,
3563 struct addi_private *devpriv = dev->private;
3565 data[0] = devpriv->s_InterruptParameters.
3566 s_FIFOInterruptParameters[devpriv->
3567 s_InterruptParameters.ui_Read].b_OldModuleMask;
3568 data[1] = devpriv->s_InterruptParameters.
3569 s_FIFOInterruptParameters[devpriv->
3570 s_InterruptParameters.ui_Read].ul_OldInterruptMask;
3571 data[2] = devpriv->s_InterruptParameters.
3572 s_FIFOInterruptParameters[devpriv->
3573 s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
3575 /**************************/
3576 /* Increment the read FIFO */
3577 /***************************/
3580 s_InterruptParameters.
3581 ui_Read = (devpriv->
3582 s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;