blob: 8883e66621158bb3b73a7e058c9a681e1263783f [file] [log] [blame]
/**
@verbatim
Copyright (C) 2004,2005 ADDI-DATA GmbH for the source code of this module.
ADDI-DATA GmbH
Dieselstrasse 3
D-77833 Ottersweier
Tel: +19(0)7223/9493-0
Fax: +49(0)7223/9493-92
http://www.addi-data.com
info@addi-data.com
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.
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.
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
You should also find the complete GPL in the COPYING file accompanying this source code.
@endverbatim
*/
/*
+-----------------------------------------------------------------------+
| (C) ADDI-DATA GmbH Dieselstraße 3 D-77833 Ottersweier |
+-----------------------------------------------------------------------+
| Tel : +49 (0) 7223/9493-0 | email : info@addi-data.com |
| Fax : +49 (0) 7223/9493-92 | Internet : http://www.addi-data.com |
+-----------------------------------------------------------------------+
| Project : API APCI1710 | Compiler : gcc |
| Module name : PWM.C | Version : 2.96 |
+-------------------------------+---------------------------------------+
| Project manager: Eric Stolz | Date : 02/12/2002 |
+-----------------------------------------------------------------------+
| Description : APCI-1710 Wulse wide modulation module |
| |
| |
+-----------------------------------------------------------------------+
| UPDATES |
+-----------------------------------------------------------------------+
| Date | Author | Description of updates |
+-----------------------------------------------------------------------+
| 08/05/00 | Guinot C | - 0400/0228 All Function in RING 0 |
| | | available |
+-----------------------------------------------------------------------+
*/
/*
+----------------------------------------------------------------------------+
| Included files |
+----------------------------------------------------------------------------+
*/
#include "APCI1710_Pwm.h"
/*
+----------------------------------------------------------------------------+
| Function Name :INT i_APCI1710_InsnConfigPWM(struct comedi_device *dev,
struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+----------------------------------------------------------------------------+
| Task : Pwm Init and Get Pwm Initialisation |
+----------------------------------------------------------------------------+
| Input Parameters :
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value :
+----------------------------------------------------------------------------+
*/
int i_APCI1710_InsnConfigPWM(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
unsigned char b_ConfigType;
int i_ReturnValue = 0;
b_ConfigType = CR_CHAN(insn->chanspec);
switch (b_ConfigType) {
case APCI1710_PWM_INIT:
i_ReturnValue = i_APCI1710_InitPWM(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */
(unsigned char) data[0], /* b_PWM */
(unsigned char) data[1], /* b_ClockSelection */
(unsigned char) data[2], /* b_TimingUnit */
(unsigned int) data[3], /* ul_LowTiming */
(unsigned int) data[4], /* ul_HighTiming */
(unsigned int *) &data[0], /* pul_RealLowTiming */
(unsigned int *) &data[1] /* pul_RealHighTiming */
);
break;
case APCI1710_PWM_GETINITDATA:
i_ReturnValue = i_APCI1710_GetPWMInitialisation(dev, (unsigned char) CR_AREF(insn->chanspec), /* b_ModulNbr */
(unsigned char) data[0], /* b_PWM */
(unsigned char *) &data[0], /* pb_TimingUnit */
(unsigned int *) &data[1], /* pul_LowTiming */
(unsigned int *) &data[2], /* pul_HighTiming */
(unsigned char *) &data[3], /* pb_StartLevel */
(unsigned char *) &data[4], /* pb_StopMode */
(unsigned char *) &data[5], /* pb_StopLevel */
(unsigned char *) &data[6], /* pb_ExternGate */
(unsigned char *) &data[7], /* pb_InterruptEnable */
(unsigned char *) &data[8] /* pb_Enable */
);
break;
default:
printk(" Config Parameter Wrong\n");
}
if (i_ReturnValue >= 0)
i_ReturnValue = insn->n;
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_InitPWM |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PWM, |
| unsigned char_ b_ClockSelection, |
| unsigned char_ b_TimingUnit, |
| ULONG_ ul_LowTiming, |
| ULONG_ ul_HighTiming, |
| PULONG_ pul_RealLowTiming, |
| PULONG_ pul_RealHighTiming) |
+----------------------------------------------------------------------------+
| Task : Configure the selected PWM (b_PWM) from selected module|
| (b_ModulNbr). The ul_LowTiming, ul_HighTiming and |
| ul_TimingUnit determine the low/high timing base for |
| the period. pul_RealLowTiming, pul_RealHighTiming |
| return the real timing value. |
| You must calling this function be for you call any |
| other function witch access of the PWM. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Module number to configure|
| (0 to 3) |
| unsigned char_ b_PWM : Selected PWM (0 or 1). |
| unsigned char_ b_ClockSelection : Selection from PCI bus |
| clock |
| - APCI1710_30MHZ : |
| The PC have a 30 MHz |
| PCI bus clock |
| - APCI1710_33MHZ : |
| The PC have a 33 MHz |
| PCI bus clock |
| - APCI1710_40MHZ |
| The APCI-1710 have a |
| integrated 40Mhz |
| quartz. |
| unsigned char_ b_TimingUnit : Base timing Unit (0 to 4) |
| 0 : ns |
| 1 : æs |
| 2 : ms |
| 3 : s |
| 4 : mn |
| ULONG_ ul_LowTiming : Low base timing value. |
| ULONG_ ul_HighTiming : High base timing value. |
+----------------------------------------------------------------------------+
| Output Parameters : PULONG_ pul_RealLowTiming : Real low base timing |
| value. |
| PULONG_ pul_RealHighTiming : Real high base timing |
| value. |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection wrong |
| -3: The module is not a PWM module |
| -4: PWM selection is wrong |
| -5: The selected input clock is wrong |
| -6: Timing Unit selection is wrong |
| -7: Low base timing selection is wrong |
| -8: High base timing selection is wrong |
| -9: You can not used the 40MHz clock selection with |
| this board |
+----------------------------------------------------------------------------+
*/
int i_APCI1710_InitPWM(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned char b_PWM,
unsigned char b_ClockSelection,
unsigned char b_TimingUnit,
unsigned int ul_LowTiming,
unsigned int ul_HighTiming,
unsigned int *pul_RealLowTiming, unsigned int *pul_RealHighTiming)
{
int i_ReturnValue = 0;
unsigned int ul_LowTimerValue = 0;
unsigned int ul_HighTimerValue = 0;
unsigned int dw_Command;
double d_RealLowTiming = 0;
double d_RealHighTiming = 0;
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***************/
/* Test if PWM */
/***************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_PWM) {
/**************************/
/* Test the PWM selection */
/**************************/
if (b_PWM <= 1) {
/******************/
/* Test the clock */
/******************/
if ((b_ClockSelection == APCI1710_30MHZ) ||
(b_ClockSelection == APCI1710_33MHZ) ||
(b_ClockSelection == APCI1710_40MHZ)) {
/************************/
/* Test the timing unit */
/************************/
if (b_TimingUnit <= 4) {
/*********************************/
/* Test the low timing selection */
/*********************************/
if (((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 0)
&& (ul_LowTiming
>= 266)
&& (ul_LowTiming
<=
0xFFFFFFFFUL))
|| ((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 1)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
571230650UL))
|| ((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 2)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
571230UL))
|| ((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 3)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
571UL))
|| ((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 4)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<= 9UL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 0)
&& (ul_LowTiming
>= 242)
&& (ul_LowTiming
<=
0xFFFFFFFFUL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 1)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
519691043UL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 2)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
519691UL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 3)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
520UL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 4)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<= 8UL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 0)
&& (ul_LowTiming
>= 200)
&& (ul_LowTiming
<=
0xFFFFFFFFUL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 1)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
429496729UL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 2)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
429496UL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 3)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
429UL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 4)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
7UL))) {
/**********************************/
/* Test the High timing selection */
/**********************************/
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))) {
/**************************/
/* Test the board version */
/**************************/
if (((b_ClockSelection == APCI1710_40MHZ) && (devpriv->s_BoardInfos.b_BoardVersion > 0)) || (b_ClockSelection != APCI1710_40MHZ)) {
/************************************/
/* Calculate the low division fator */
/************************************/
fpu_begin
();
switch (b_TimingUnit) {
/******/
/* ns */
/******/
case 0:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
(unsigned int)
(ul_LowTiming
*
(0.00025 * b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(0.00025 * (double)b_ClockSelection));
d_RealLowTiming
=
(double)
ul_LowTimerValue
/
(0.00025
*
(double)
b_ClockSelection);
if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
*pul_RealLowTiming
=
*pul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
/******/
/* æs */
/******/
case 1:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
(unsigned int)
(ul_LowTiming
*
(0.25 * b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(0.25 * (double)b_ClockSelection));
d_RealLowTiming
=
(double)
ul_LowTimerValue
/
(
(double)
0.25
*
(double)
b_ClockSelection);
if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
*pul_RealLowTiming
=
*pul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
/******/
/* ms */
/******/
case 2:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
ul_LowTiming
*
(250.0
*
b_ClockSelection);
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(250.0 * (double)b_ClockSelection));
d_RealLowTiming
=
(double)
ul_LowTimerValue
/
(250.0
*
(double)
b_ClockSelection);
if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
*pul_RealLowTiming
=
*pul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
/*****/
/* s */
/*****/
case 3:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
(unsigned int)
(ul_LowTiming
*
(250000.0
*
b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(250000.0
*
(double)
b_ClockSelection));
d_RealLowTiming
=
(double)
ul_LowTimerValue
/
(250000.0
*
(double)
b_ClockSelection);
if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealLowTiming + 0.5)) {
*pul_RealLowTiming
=
*pul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
/******/
/* mn */
/******/
case 4:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
(unsigned int)
(
(ul_LowTiming
*
60)
*
(250000.0
*
b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(250000.0
*
(double)
b_ClockSelection))
/
60;
d_RealLowTiming
=
(
(double)
ul_LowTimerValue
/
(250000.0
*
(double)
b_ClockSelection))
/
60.0;
if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealLowTiming + 0.5)) {
*pul_RealLowTiming
=
*pul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
}
/*************************************/
/* Calculate the high division fator */
/*************************************/
switch (b_TimingUnit) {
/******/
/* ns */
/******/
case 0:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
(unsigned int)
(ul_HighTiming
*
(0.00025 * b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(0.00025 * (double)b_ClockSelection));
d_RealHighTiming
=
(double)
ul_HighTimerValue
/
(0.00025
*
(double)
b_ClockSelection);
if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
*pul_RealHighTiming
=
*pul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
/******/
/* æs */
/******/
case 1:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
(unsigned int)
(ul_HighTiming
*
(0.25 * b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(0.25 * (double)b_ClockSelection));
d_RealHighTiming
=
(double)
ul_HighTimerValue
/
(
(double)
0.25
*
(double)
b_ClockSelection);
if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
*pul_RealHighTiming
=
*pul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
/******/
/* ms */
/******/
case 2:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
ul_HighTiming
*
(250.0
*
b_ClockSelection);
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(250.0 * (double)b_ClockSelection));
d_RealHighTiming
=
(double)
ul_HighTimerValue
/
(250.0
*
(double)
b_ClockSelection);
if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
*pul_RealHighTiming
=
*pul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
/*****/
/* s */
/*****/
case 3:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
(unsigned int)
(ul_HighTiming
*
(250000.0
*
b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(250000.0
*
(double)
b_ClockSelection));
d_RealHighTiming
=
(double)
ul_HighTimerValue
/
(250000.0
*
(double)
b_ClockSelection);
if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)*pul_RealHighTiming + 0.5)) {
*pul_RealHighTiming
=
*pul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
/******/
/* mn */
/******/
case 4:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
(unsigned int)
(
(ul_HighTiming
*
60)
*
(250000.0
*
b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
*pul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(250000.0
*
(double)
b_ClockSelection))
/
60;
d_RealHighTiming
=
(
(double)
ul_HighTimerValue
/
(250000.0
*
(double)
b_ClockSelection))
/
60.0;
if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)*pul_RealHighTiming + 0.5)) {
*pul_RealHighTiming
=
*pul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
}
fpu_end();
/****************************/
/* Save the clock selection */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
b_ClockSelection
=
b_ClockSelection;
/************************/
/* Save the timing unit */
/************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
b_TimingUnit
=
b_TimingUnit;
/****************************/
/* Save the low base timing */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
d_LowTiming
=
d_RealLowTiming;
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
ul_RealLowTiming
=
*pul_RealLowTiming;
/****************************/
/* Save the high base timing */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
d_HighTiming
=
d_RealHighTiming;
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
ul_RealHighTiming
=
*pul_RealHighTiming;
/************************/
/* Write the low timing */
/************************/
outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
/*************************/
/* Write the high timing */
/*************************/
outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
/***************************/
/* Set the clock selection */
/***************************/
dw_Command
=
inl
(devpriv->
s_BoardInfos.
ui_Address
+
8
+
(20 * b_PWM) + (64 * b_ModulNbr));
dw_Command
=
dw_Command
&
0x7F;
if (b_ClockSelection == APCI1710_40MHZ) {
dw_Command
=
dw_Command
|
0x80;
}
/***************************/
/* Set the clock selection */
/***************************/
outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
/*************/
/* PWM init. */
/*************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
b_PWMInit
=
1;
} else {
/***************************************************/
/* You can not used the 40MHz clock selection with */
/* this board */
/***************************************************/
DPRINTK("You can not used the 40MHz clock selection with this board\n");
i_ReturnValue
=
-9;
}
} else {
/***************************************/
/* High base timing selection is wrong */
/***************************************/
DPRINTK("High base timing selection is wrong\n");
i_ReturnValue =
-8;
}
} else {
/**************************************/
/* Low base timing selection is wrong */
/**************************************/
DPRINTK("Low base timing selection is wrong\n");
i_ReturnValue = -7;
}
} /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
else {
/**********************************/
/* Timing unit selection is wrong */
/**********************************/
DPRINTK("Timing unit selection is wrong\n");
i_ReturnValue = -6;
} /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
} /* if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ)) */
else {
/*******************************/
/* The selected clock is wrong */
/*******************************/
DPRINTK("The selected clock is wrong\n");
i_ReturnValue = -5;
} /* if ((b_ClockSelection == APCI1710_30MHZ) || (b_ClockSelection == APCI1710_33MHZ) || (b_ClockSelection == APCI1710_40MHZ)) */
} /* if (b_PWM >= 0 && b_PWM <= 1) */
else {
/******************************/
/* Tor PWM selection is wrong */
/******************************/
DPRINTK("Tor PWM selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_PWM >= 0 && b_PWM <= 1) */
} else {
/**********************************/
/* The module is not a PWM module */
/**********************************/
DPRINTK("The module is not a PWM module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_GetPWMInitialisation |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PWM, |
| unsigned char *_ pb_TimingUnit, |
| PULONG_ pul_LowTiming, |
| PULONG_ pul_HighTiming, |
| unsigned char *_ pb_StartLevel, |
| unsigned char *_ pb_StopMode, |
| unsigned char *_ pb_StopLevel, |
| unsigned char *_ pb_ExternGate, |
| unsigned char *_ pb_InterruptEnable, |
| unsigned char *_ pb_Enable) |
+----------------------------------------------------------------------------+
| Task : Return the PWM (b_PWM) initialisation from selected |
| module (b_ModulNbr). You must calling the |
| "i_APCI1710_InitPWM" function be for you call this |
| function. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Selected module number (0 to 3) |
| unsigned char_ b_PWM : Selected PWM (0 or 1) |
+----------------------------------------------------------------------------+
| Output Parameters : unsigned char *_ pb_TimingUnit : Base timing Unit (0 to 4) |
| 0 : ns |
| 1 : æs |
| 2 : ms |
| 3 : s |
| 4 : mn |
| PULONG_ pul_LowTiming : Low base timing value. |
| PULONG_ pul_HighTiming : High base timing value. |
| unsigned char *_ pb_StartLevel : Start period level |
| selection |
| 0 : The period start |
| with a low level |
| 1 : The period start |
| with a high level|
| unsigned char *_ pb_StopMode : Stop mode selection |
| 0 : The PWM is stopped |
| directly after the |
| "i_APCI1710_DisablePWM"|
| function and break the|
| last period |
| 1 : After the |
| "i_APCI1710_DisablePWM"|
| function the PWM is |
| stopped at the end |
| from last period cycle|
| unsigned char *_ pb_StopLevel : Stop PWM level selection |
| 0 : The output signal |
| keep the level after|
| the |
| "i_APCI1710_DisablePWM"|
| function |
| 1 : The output signal is|
| set to low after the|
| "i_APCI1710_DisablePWM"|
| function |
| 2 : The output signal is|
| set to high after |
| the |
| "i_APCI1710_DisablePWM"|
| function |
| unsigned char *_ pb_ExternGate : Extern gate action |
| selection |
| 0 : Extern gate signal |
| not used. |
| 1 : Extern gate signal |
| used. |
| unsigned char *_ pb_InterruptEnable : Enable or disable the PWM |
| interrupt. |
| - APCI1710_ENABLE : |
| Enable the PWM interrupt|
| A interrupt occur after |
| each period |
| - APCI1710_DISABLE : |
| Disable the PWM |
| interrupt |
| unsigned char *_ pb_Enable : Indicate if the PWM is |
| enabled or no |
| 0 : PWM not enabled |
| 1 : PWM enabled |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection wrong |
| -3: The module is not a PWM module |
| -4: PWM selection is wrong |
| -5: PWM not initialised see function |
| "i_APCI1710_InitPWM" |
+----------------------------------------------------------------------------+
*/
int i_APCI1710_GetPWMInitialisation(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned char b_PWM,
unsigned char *pb_TimingUnit,
unsigned int *pul_LowTiming,
unsigned int *pul_HighTiming,
unsigned char *pb_StartLevel,
unsigned char *pb_StopMode,
unsigned char *pb_StopLevel,
unsigned char *pb_ExternGate, unsigned char *pb_InterruptEnable, unsigned char *pb_Enable)
{
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int dw_Command;
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***************/
/* Test if PWM */
/***************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_PWM) {
/**************************/
/* Test the PWM selection */
/**************************/
if (b_PWM <= 1) {
/***************************/
/* Test if PWM initialised */
/***************************/
dw_Status = inl(devpriv->s_BoardInfos.
ui_Address + 12 + (20 * b_PWM) +
(64 * b_ModulNbr));
if (dw_Status & 0x10) {
/***********************/
/* Read the low timing */
/***********************/
*pul_LowTiming =
inl(devpriv->s_BoardInfos.
ui_Address + 0 + (20 * b_PWM) +
(64 * b_ModulNbr));
/************************/
/* Read the high timing */
/************************/
*pul_HighTiming =
inl(devpriv->s_BoardInfos.
ui_Address + 4 + (20 * b_PWM) +
(64 * b_ModulNbr));
/********************/
/* Read the command */
/********************/
dw_Command = inl(devpriv->s_BoardInfos.
ui_Address + 8 + (20 * b_PWM) +
(64 * b_ModulNbr));
*pb_StartLevel =
(unsigned char) ((dw_Command >> 5) & 1);
*pb_StopMode =
(unsigned char) ((dw_Command >> 0) & 1);
*pb_StopLevel =
(unsigned char) ((dw_Command >> 1) & 1);
*pb_ExternGate =
(unsigned char) ((dw_Command >> 4) & 1);
*pb_InterruptEnable =
(unsigned char) ((dw_Command >> 3) & 1);
if (*pb_StopLevel) {
*pb_StopLevel =
*pb_StopLevel +
(unsigned char) ((dw_Command >>
2) & 1);
}
/********************/
/* Read the command */
/********************/
dw_Command = inl(devpriv->s_BoardInfos.
ui_Address + 8 + (20 * b_PWM) +
(64 * b_ModulNbr));
*pb_Enable =
(unsigned char) ((dw_Command >> 0) & 1);
*pb_TimingUnit = devpriv->
s_ModuleInfo[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo[b_PWM].b_TimingUnit;
} /* if (dw_Status & 0x10) */
else {
/***********************/
/* PWM not initialised */
/***********************/
DPRINTK("PWM not initialised\n");
i_ReturnValue = -5;
} /* if (dw_Status & 0x10) */
} /* if (b_PWM >= 0 && b_PWM <= 1) */
else {
/******************************/
/* Tor PWM selection is wrong */
/******************************/
DPRINTK("Tor PWM selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_PWM >= 0 && b_PWM <= 1) */
} else {
/**********************************/
/* The module is not a PWM module */
/**********************************/
DPRINTK("The module is not a PWM module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name :INT i_APCI1710_InsnWritePWM(struct comedi_device *dev,
struct comedi_subdevice *s,struct comedi_insn *insn,unsigned int *data) |
+----------------------------------------------------------------------------+
| Task : Pwm Enable Disable and Set New Timing |
+----------------------------------------------------------------------------+
| Input Parameters :
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value :
+----------------------------------------------------------------------------+
*/
int i_APCI1710_InsnWritePWM(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
unsigned char b_WriteType;
int i_ReturnValue = 0;
b_WriteType = CR_CHAN(insn->chanspec);
switch (b_WriteType) {
case APCI1710_PWM_ENABLE:
i_ReturnValue = i_APCI1710_EnablePWM(dev,
(unsigned char) CR_AREF(insn->chanspec),
(unsigned char) data[0],
(unsigned char) data[1],
(unsigned char) data[2],
(unsigned char) data[3], (unsigned char) data[4], (unsigned char) data[5]);
break;
case APCI1710_PWM_DISABLE:
i_ReturnValue = i_APCI1710_DisablePWM(dev,
(unsigned char) CR_AREF(insn->chanspec), (unsigned char) data[0]);
break;
case APCI1710_PWM_NEWTIMING:
i_ReturnValue = i_APCI1710_SetNewPWMTiming(dev,
(unsigned char) CR_AREF(insn->chanspec),
(unsigned char) data[0],
(unsigned char) data[1], (unsigned int) data[2], (unsigned int) data[3]);
break;
default:
printk("Write Config Parameter Wrong\n");
}
if (i_ReturnValue >= 0)
i_ReturnValue = insn->n;
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_EnablePWM |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PWM, |
| unsigned char_ b_StartLevel, |
| unsigned char_ b_StopMode, |
| unsigned char_ b_StopLevel, |
| unsigned char_ b_ExternGate, |
| unsigned char_ b_InterruptEnable) |
+----------------------------------------------------------------------------+
| Task : Enable the selected PWM (b_PWM) from selected module |
| (b_ModulNbr). You must calling the "i_APCI1710_InitPWM"|
| function be for you call this function. |
| If you enable the PWM interrupt, the PWM generate a |
| interrupt after each period. |
| See function "i_APCI1710_SetBoardIntRoutineX" and the |
| Interrupt mask description chapter. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Selected module number |
| (0 to 3) |
| unsigned char_ b_PWM : Selected PWM (0 or 1) |
| unsigned char_ b_StartLevel : Start period level selection |
| 0 : The period start with a |
| low level |
| 1 : The period start with a |
| high level |
| unsigned char_ b_StopMode : Stop mode selection |
| 0 : The PWM is stopped |
| directly after the |
| "i_APCI1710_DisablePWM" |
| function and break the |
| last period |
| 1 : After the |
| "i_APCI1710_DisablePWM" |
| function the PWM is |
| stopped at the end from|
| last period cycle. |
| unsigned char_ b_StopLevel : Stop PWM level selection |
| 0 : The output signal keep |
| the level after the |
| "i_APCI1710_DisablePWM" |
| function |
| 1 : The output signal is set|
| to low after the |
| "i_APCI1710_DisablePWM" |
| function |
| 2 : The output signal is set|
| to high after the |
| "i_APCI1710_DisablePWM" |
| function |
| unsigned char_ b_ExternGate : Extern gate action selection |
| 0 : Extern gate signal not |
| used. |
| 1 : Extern gate signal used.|
| unsigned char_ b_InterruptEnable : Enable or disable the PWM |
| interrupt. |
| - APCI1710_ENABLE : |
| Enable the PWM interrupt |
| A interrupt occur after |
| each period |
| - APCI1710_DISABLE : |
| Disable the PWM interrupt |
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection wrong |
| -3: The module is not a PWM module |
| -4: PWM selection is wrong |
| -5: PWM not initialised see function |
| "i_APCI1710_InitPWM" |
| -6: PWM start level selection is wrong |
| -7: PWM stop mode selection is wrong |
| -8: PWM stop level selection is wrong |
| -9: Extern gate signal selection is wrong |
| -10: Interrupt parameter is wrong |
| -11: Interrupt function not initialised. |
| See function "i_APCI1710_SetBoardIntRoutineX" |
+----------------------------------------------------------------------------+
*/
int i_APCI1710_EnablePWM(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned char b_PWM,
unsigned char b_StartLevel,
unsigned char b_StopMode,
unsigned char b_StopLevel, unsigned char b_ExternGate, unsigned char b_InterruptEnable)
{
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned int dw_Command;
devpriv->tsk_Current = current; /* Save the current process task structure */
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***************/
/* Test if PWM */
/***************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_PWM) {
/**************************/
/* Test the PWM selection */
/**************************/
if (b_PWM <= 1) {
/***************************/
/* Test if PWM initialised */
/***************************/
dw_Status = inl(devpriv->s_BoardInfos.
ui_Address + 12 + (20 * b_PWM) +
(64 * b_ModulNbr));
if (dw_Status & 0x10) {
/**********************************/
/* Test the start level selection */
/**********************************/
if (b_StartLevel <= 1) {
/**********************/
/* Test the stop mode */
/**********************/
if (b_StopMode <= 1) {
/***********************/
/* Test the stop level */
/***********************/
if (b_StopLevel <= 2) {
/*****************************/
/* Test the extern gate mode */
/*****************************/
if (b_ExternGate
<= 1) {
/*****************************/
/* Test the interrupt action */
/*****************************/
if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) {
/******************************************/
/* Test if interrupt function initialised */
/******************************************/
/********************/
/* Read the command */
/********************/
dw_Command
=
inl
(devpriv->
s_BoardInfos.
ui_Address
+
8
+
(20 * b_PWM) + (64 * b_ModulNbr));
dw_Command
=
dw_Command
&
0x80;
/********************/
/* Make the command */
/********************/
dw_Command
=
dw_Command
|
b_StopMode
|
(b_InterruptEnable
<<
3)
|
(b_ExternGate
<<
4)
|
(b_StartLevel
<<
5);
if (b_StopLevel & 3) {
dw_Command
=
dw_Command
|
2;
if (b_StopLevel & 2) {
dw_Command
=
dw_Command
|
4;
}
}
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
b_InterruptEnable
=
b_InterruptEnable;
/*******************/
/* Set the command */
/*******************/
outl(dw_Command, devpriv->s_BoardInfos.ui_Address + 8 + (20 * b_PWM) + (64 * b_ModulNbr));
/******************/
/* Enable the PWM */
/******************/
outl(1, devpriv->s_BoardInfos.ui_Address + 12 + (20 * b_PWM) + (64 * b_ModulNbr));
} /* if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) */
else {
/********************************/
/* Interrupt parameter is wrong */
/********************************/
DPRINTK("Interrupt parameter is wrong\n");
i_ReturnValue
=
-10;
} /* if (b_InterruptEnable == APCI1710_ENABLE || b_InterruptEnable == APCI1710_DISABLE) */
} /* if (b_ExternGate >= 0 && b_ExternGate <= 1) */
else {
/*****************************************/
/* Extern gate signal selection is wrong */
/*****************************************/
DPRINTK("Extern gate signal selection is wrong\n");
i_ReturnValue
=
-9;
} /* if (b_ExternGate >= 0 && b_ExternGate <= 1) */
} /* if (b_StopLevel >= 0 && b_StopLevel <= 2) */
else {
/*************************************/
/* PWM stop level selection is wrong */
/*************************************/
DPRINTK("PWM stop level selection is wrong\n");
i_ReturnValue =
-8;
} /* if (b_StopLevel >= 0 && b_StopLevel <= 2) */
} /* if (b_StopMode >= 0 && b_StopMode <= 1) */
else {
/************************************/
/* PWM stop mode selection is wrong */
/************************************/
DPRINTK("PWM stop mode selection is wrong\n");
i_ReturnValue = -7;
} /* if (b_StopMode >= 0 && b_StopMode <= 1) */
} /* if (b_StartLevel >= 0 && b_StartLevel <= 1) */
else {
/**************************************/
/* PWM start level selection is wrong */
/**************************************/
DPRINTK("PWM start level selection is wrong\n");
i_ReturnValue = -6;
} /* if (b_StartLevel >= 0 && b_StartLevel <= 1) */
} /* if (dw_Status & 0x10) */
else {
/***********************/
/* PWM not initialised */
/***********************/
DPRINTK("PWM not initialised\n");
i_ReturnValue = -5;
} /* if (dw_Status & 0x10) */
} /* if (b_PWM >= 0 && b_PWM <= 1) */
else {
/******************************/
/* Tor PWM selection is wrong */
/******************************/
DPRINTK("Tor PWM selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_PWM >= 0 && b_PWM <= 1) */
} else {
/**********************************/
/* The module is not a PWM module */
/**********************************/
DPRINTK("The module is not a PWM module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_DisablePWM (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PWM) |
+----------------------------------------------------------------------------+
| Task : Disable the selected PWM (b_PWM) from selected module |
| (b_ModulNbr). The output signal level depend of the |
| initialisation by the "i_APCI1710_EnablePWM". |
| See the b_StartLevel, b_StopMode and b_StopLevel |
| parameters from this function. |
+----------------------------------------------------------------------------+
| Input Parameters :BYTE_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Selected module number (0 to 3) |
| unsigned char_ b_PWM : Selected PWM (0 or 1) |
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection wrong |
| -3: The module is not a PWM module |
| -4: PWM selection is wrong |
| -5: PWM not initialised see function |
| "i_APCI1710_InitPWM" |
| -6: PWM not enabled see function |
| "i_APCI1710_EnablePWM" |
+----------------------------------------------------------------------------+
*/
int i_APCI1710_DisablePWM(struct comedi_device *dev, unsigned char b_ModulNbr, unsigned char b_PWM)
{
int i_ReturnValue = 0;
unsigned int dw_Status;
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***************/
/* Test if PWM */
/***************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_PWM) {
/**************************/
/* Test the PWM selection */
/**************************/
if (b_PWM <= 1) {
/***************************/
/* Test if PWM initialised */
/***************************/
dw_Status = inl(devpriv->s_BoardInfos.
ui_Address + 12 + (20 * b_PWM) +
(64 * b_ModulNbr));
if (dw_Status & 0x10) {
/***********************/
/* Test if PWM enabled */
/***********************/
if (dw_Status & 0x1) {
/*******************/
/* Disable the PWM */
/*******************/
outl(0, devpriv->s_BoardInfos.
ui_Address + 12 +
(20 * b_PWM) +
(64 * b_ModulNbr));
} /* if (dw_Status & 0x1) */
else {
/*******************/
/* PWM not enabled */
/*******************/
DPRINTK("PWM not enabled\n");
i_ReturnValue = -6;
} /* if (dw_Status & 0x1) */
} /* if (dw_Status & 0x10) */
else {
/***********************/
/* PWM not initialised */
/***********************/
DPRINTK(" PWM not initialised\n");
i_ReturnValue = -5;
} /* if (dw_Status & 0x10) */
} /* if (b_PWM >= 0 && b_PWM <= 1) */
else {
/******************************/
/* Tor PWM selection is wrong */
/******************************/
DPRINTK("Tor PWM selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_PWM >= 0 && b_PWM <= 1) */
} else {
/**********************************/
/* The module is not a PWM module */
/**********************************/
DPRINTK("The module is not a PWM module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_SetNewPWMTiming |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PWM, |
| unsigned char_ b_ClockSelection, |
| unsigned char_ b_TimingUnit, |
| ULONG_ ul_LowTiming, |
| ULONG_ ul_HighTiming) |
+----------------------------------------------------------------------------+
| Task : Set a new timing. The ul_LowTiming, ul_HighTiming and |
| ul_TimingUnit determine the low/high timing base for |
| the period. |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_ModulNbr : Module number to configure|
| (0 to 3) |
| unsigned char_ b_PWM : Selected PWM (0 or 1). |
| unsigned char_ b_TimingUnit : Base timing Unit (0 to 4) |
| 0 : ns |
| 1 : æs |
| 2 : ms |
| 3 : s |
| 4 : mn |
| ULONG_ ul_LowTiming : Low base timing value. |
| ULONG_ ul_HighTiming : High base timing value. |
+----------------------------------------------------------------------------+
| Output Parameters : - |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection wrong |
| -3: The module is not a PWM module |
| -4: PWM selection is wrong |
| -5: PWM not initialised |
| -6: Timing Unit selection is wrong |
| -7: Low base timing selection is wrong |
| -8: High base timing selection is wrong |
+----------------------------------------------------------------------------+
*/
int i_APCI1710_SetNewPWMTiming(struct comedi_device *dev,
unsigned char b_ModulNbr,
unsigned char b_PWM, unsigned char b_TimingUnit, unsigned int ul_LowTiming, unsigned int ul_HighTiming)
{
unsigned char b_ClockSelection;
int i_ReturnValue = 0;
unsigned int ul_LowTimerValue = 0;
unsigned int ul_HighTimerValue = 0;
unsigned int ul_RealLowTiming = 0;
unsigned int ul_RealHighTiming = 0;
unsigned int dw_Status;
unsigned int dw_Command;
double d_RealLowTiming = 0;
double d_RealHighTiming = 0;
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***************/
/* Test if PWM */
/***************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_PWM) {
/**************************/
/* Test the PWM selection */
/**************************/
if (b_PWM <= 1) {
/***************************/
/* Test if PWM initialised */
/***************************/
dw_Status = inl(devpriv->s_BoardInfos.
ui_Address + 12 + (20 * b_PWM) +
(64 * b_ModulNbr));
if (dw_Status & 0x10) {
b_ClockSelection = devpriv->
s_ModuleInfo[b_ModulNbr].
s_PWMModuleInfo.
b_ClockSelection;
/************************/
/* Test the timing unit */
/************************/
if (b_TimingUnit <= 4) {
/*********************************/
/* Test the low timing selection */
/*********************************/
if (((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 0)
&& (ul_LowTiming
>= 266)
&& (ul_LowTiming
<=
0xFFFFFFFFUL))
|| ((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 1)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
571230650UL))
|| ((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 2)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
571230UL))
|| ((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 3)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
571UL))
|| ((b_ClockSelection ==
APCI1710_30MHZ)
&& (b_TimingUnit
== 4)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<= 9UL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 0)
&& (ul_LowTiming
>= 242)
&& (ul_LowTiming
<=
0xFFFFFFFFUL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 1)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
519691043UL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 2)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
519691UL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 3)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
520UL))
|| ((b_ClockSelection ==
APCI1710_33MHZ)
&& (b_TimingUnit
== 4)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<= 8UL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 0)
&& (ul_LowTiming
>= 200)
&& (ul_LowTiming
<=
0xFFFFFFFFUL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 1)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
429496729UL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 2)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
429496UL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 3)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
429UL))
|| ((b_ClockSelection ==
APCI1710_40MHZ)
&& (b_TimingUnit
== 4)
&& (ul_LowTiming
>= 1)
&& (ul_LowTiming
<=
7UL))) {
/**********************************/
/* Test the High timing selection */
/**********************************/
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))) {
/************************************/
/* Calculate the low division fator */
/************************************/
fpu_begin();
switch (b_TimingUnit) {
/******/
/* ns */
/******/
case 0:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
(unsigned int)
(ul_LowTiming
*
(0.00025 * b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_LowTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(0.00025 * (double)b_ClockSelection));
d_RealLowTiming
=
(double)
ul_LowTimerValue
/
(0.00025
*
(double)
b_ClockSelection);
if ((double)((double)ul_LowTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
ul_RealLowTiming
=
ul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
/******/
/* æs */
/******/
case 1:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
(unsigned int)
(ul_LowTiming
*
(0.25 * b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_LowTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(0.25 * (double)b_ClockSelection));
d_RealLowTiming
=
(double)
ul_LowTimerValue
/
(
(double)
0.25
*
(double)
b_ClockSelection);
if ((double)((double)ul_LowTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
ul_RealLowTiming
=
ul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
/******/
/* ms */
/******/
case 2:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
ul_LowTiming
*
(250.0
*
b_ClockSelection);
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_LowTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(250.0 * (double)b_ClockSelection));
d_RealLowTiming
=
(double)
ul_LowTimerValue
/
(250.0
*
(double)
b_ClockSelection);
if ((double)((double)ul_LowTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
ul_RealLowTiming
=
ul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
/*****/
/* s */
/*****/
case 3:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
(unsigned int)
(ul_LowTiming
*
(250000.0
*
b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_LowTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(250000.0
*
(double)
b_ClockSelection));
d_RealLowTiming
=
(double)
ul_LowTimerValue
/
(250000.0
*
(double)
b_ClockSelection);
if ((double)((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealLowTiming + 0.5)) {
ul_RealLowTiming
=
ul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
/******/
/* mn */
/******/
case 4:
/******************/
/* Timer 0 factor */
/******************/
ul_LowTimerValue
=
(unsigned int)
(
(ul_LowTiming
*
60)
*
(250000.0
*
b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)(ul_LowTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_LowTimerValue + 0.5))) {
ul_LowTimerValue
=
ul_LowTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealLowTiming
=
(unsigned int)
(ul_LowTimerValue
/
(250000.0
*
(double)
b_ClockSelection))
/
60;
d_RealLowTiming
=
(
(double)
ul_LowTimerValue
/
(250000.0
*
(double)
b_ClockSelection))
/
60.0;
if ((double)(((double)ul_LowTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealLowTiming + 0.5)) {
ul_RealLowTiming
=
ul_RealLowTiming
+
1;
}
ul_LowTiming
=
ul_LowTiming
-
1;
ul_LowTimerValue
=
ul_LowTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_LowTimerValue
=
(unsigned int)
(
(double)
(ul_LowTimerValue)
*
1.007752288);
}
break;
}
/*************************************/
/* Calculate the high division fator */
/*************************************/
switch (b_TimingUnit) {
/******/
/* ns */
/******/
case 0:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
(unsigned int)
(ul_HighTiming
*
(0.00025 * b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_HighTiming * (0.00025 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(0.00025 * (double)b_ClockSelection));
d_RealHighTiming
=
(double)
ul_HighTimerValue
/
(0.00025
*
(double)
b_ClockSelection);
if ((double)((double)ul_HighTimerValue / (0.00025 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
ul_RealHighTiming
=
ul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
/******/
/* æs */
/******/
case 1:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
(unsigned int)
(ul_HighTiming
*
(0.25 * b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_HighTiming * (0.25 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(0.25 * (double)b_ClockSelection));
d_RealHighTiming
=
(double)
ul_HighTimerValue
/
(
(double)
0.25
*
(double)
b_ClockSelection);
if ((double)((double)ul_HighTimerValue / (0.25 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
ul_RealHighTiming
=
ul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
/******/
/* ms */
/******/
case 2:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
ul_HighTiming
*
(250.0
*
b_ClockSelection);
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_HighTiming * (250.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(250.0 * (double)b_ClockSelection));
d_RealHighTiming
=
(double)
ul_HighTimerValue
/
(250.0
*
(double)
b_ClockSelection);
if ((double)((double)ul_HighTimerValue / (250.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
ul_RealHighTiming
=
ul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
/*****/
/* s */
/*****/
case 3:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
(unsigned int)
(ul_HighTiming
*
(250000.0
*
b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)ul_HighTiming * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(250000.0
*
(double)
b_ClockSelection));
d_RealHighTiming
=
(double)
ul_HighTimerValue
/
(250000.0
*
(double)
b_ClockSelection);
if ((double)((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) >= (double)((double)ul_RealHighTiming + 0.5)) {
ul_RealHighTiming
=
ul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
/******/
/* mn */
/******/
case 4:
/******************/
/* Timer 0 factor */
/******************/
ul_HighTimerValue
=
(unsigned int)
(
(ul_HighTiming
*
60)
*
(250000.0
*
b_ClockSelection));
/*******************/
/* Round the value */
/*******************/
if ((double)((double)(ul_HighTiming * 60.0) * (250000.0 * (double)b_ClockSelection)) >= ((double)((double)ul_HighTimerValue + 0.5))) {
ul_HighTimerValue
=
ul_HighTimerValue
+
1;
}
/*****************************/
/* Calculate the real timing */
/*****************************/
ul_RealHighTiming
=
(unsigned int)
(ul_HighTimerValue
/
(250000.0
*
(double)
b_ClockSelection))
/
60;
d_RealHighTiming
=
(
(double)
ul_HighTimerValue
/
(250000.0
*
(double)
b_ClockSelection))
/
60.0;
if ((double)(((double)ul_HighTimerValue / (250000.0 * (double)b_ClockSelection)) / 60.0) >= (double)((double)ul_RealHighTiming + 0.5)) {
ul_RealHighTiming
=
ul_RealHighTiming
+
1;
}
ul_HighTiming
=
ul_HighTiming
-
1;
ul_HighTimerValue
=
ul_HighTimerValue
-
2;
if (b_ClockSelection != APCI1710_40MHZ) {
ul_HighTimerValue
=
(unsigned int)
(
(double)
(ul_HighTimerValue)
*
1.007752288);
}
break;
}
fpu_end();
/************************/
/* Save the timing unit */
/************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
b_TimingUnit
=
b_TimingUnit;
/****************************/
/* Save the low base timing */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
d_LowTiming
=
d_RealLowTiming;
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
ul_RealLowTiming
=
ul_RealLowTiming;
/****************************/
/* Save the high base timing */
/****************************/
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
d_HighTiming
=
d_RealHighTiming;
devpriv->
s_ModuleInfo
[b_ModulNbr].
s_PWMModuleInfo.
s_PWMInfo
[b_PWM].
ul_RealHighTiming
=
ul_RealHighTiming;
/************************/
/* Write the low timing */
/************************/
outl(ul_LowTimerValue, devpriv->s_BoardInfos.ui_Address + 0 + (20 * b_PWM) + (64 * b_ModulNbr));
/*************************/
/* Write the high timing */
/*************************/
outl(ul_HighTimerValue, devpriv->s_BoardInfos.ui_Address + 4 + (20 * b_PWM) + (64 * b_ModulNbr));
/***************************/
/* Set the clock selection */
/***************************/
dw_Command =
inl
(devpriv->
s_BoardInfos.
ui_Address
+ 8 +
(20 * b_PWM) + (64 * b_ModulNbr));
dw_Command =
dw_Command
& 0x7F;
if (b_ClockSelection == APCI1710_40MHZ) {
dw_Command
=
dw_Command
|
0x80;
}
/***************************/
/* Set the clock selection */
/***************************/
outl(dw_Command,
devpriv->
s_BoardInfos.
ui_Address
+ 8 +
(20 * b_PWM) + (64 * b_ModulNbr));
} else {
/***************************************/
/* High base timing selection is wrong */
/***************************************/
DPRINTK("High base timing selection is wrong\n");
i_ReturnValue =
-8;
}
} else {
/**************************************/
/* Low base timing selection is wrong */
/**************************************/
DPRINTK("Low base timing selection is wrong\n");
i_ReturnValue = -7;
}
} /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
else {
/**********************************/
/* Timing unit selection is wrong */
/**********************************/
DPRINTK("Timing unit selection is wrong\n");
i_ReturnValue = -6;
} /* if ((b_TimingUnit >= 0) && (b_TimingUnit <= 4)) */
} /* if (dw_Status & 0x10) */
else {
/***********************/
/* PWM not initialised */
/***********************/
DPRINTK("PWM not initialised\n");
i_ReturnValue = -5;
} /* if (dw_Status & 0x10) */
} /* if (b_PWM >= 0 && b_PWM <= 1) */
else {
/******************************/
/* Tor PWM selection is wrong */
/******************************/
DPRINTK("Tor PWM selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_PWM >= 0 && b_PWM <= 1) */
} else {
/**********************************/
/* The module is not a PWM module */
/**********************************/
DPRINTK("The module is not a PWM module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
/*
+----------------------------------------------------------------------------+
| Function Name : _INT_ i_APCI1710_GetPWMStatus |
| (unsigned char_ b_BoardHandle, |
| unsigned char_ b_ModulNbr, |
| unsigned char_ b_PWM, |
| unsigned char *_ pb_PWMOutputStatus, |
| unsigned char *_ pb_ExternGateStatus) |
+----------------------------------------------------------------------------+
| Task : Return the status from selected PWM (b_PWM) from |
| selected module (b_ModulNbr). |
+----------------------------------------------------------------------------+
| Input Parameters : unsigned char_ b_BoardHandle : Handle of board APCI-1710 |
| unsigned char_ b_PWM : Selected PWM (0 or 1) |
| unsigned char_ b_ModulNbr : Selected module number (0 to 3)
b_ModulNbr =(unsigned char) CR_AREF(insn->chanspec);
b_PWM =(unsigned char) data[0];
|
+----------------------------------------------------------------------------+
| Output Parameters : unsigned char *_ pb_PWMOutputStatus : Return the PWM output |
| level status. |
| 0 : The PWM output level|
| is low. |
| 1 : The PWM output level|
| is high. |
| unsigned char *_ pb_ExternGateStatus : Return the extern gate |
| level status. |
| 0 : The extern gate is |
| low. |
| 1 : The extern gate is |
| high.
pb_PWMOutputStatus =(unsigned char *) data[0];
pb_ExternGateStatus =(unsigned char *) data[1]; |
+----------------------------------------------------------------------------+
| Return Value : 0: No error |
| -1: The handle parameter of the board is wrong |
| -2: Module selection wrong |
| -3: The module is not a PWM module |
| -4: PWM selection is wrong |
| -5: PWM not initialised see function |
| "i_APCI1710_InitPWM" |
| -6: PWM not enabled see function "i_APCI1710_EnablePWM"|
+----------------------------------------------------------------------------+
*/
int i_APCI1710_InsnReadGetPWMStatus(struct comedi_device *dev, struct comedi_subdevice *s,
struct comedi_insn *insn, unsigned int *data)
{
int i_ReturnValue = 0;
unsigned int dw_Status;
unsigned char b_ModulNbr;
unsigned char b_PWM;
unsigned char *pb_PWMOutputStatus;
unsigned char *pb_ExternGateStatus;
i_ReturnValue = insn->n;
b_ModulNbr = (unsigned char) CR_AREF(insn->chanspec);
b_PWM = (unsigned char) CR_CHAN(insn->chanspec);
pb_PWMOutputStatus = (unsigned char *) &data[0];
pb_ExternGateStatus = (unsigned char *) &data[1];
/**************************/
/* Test the module number */
/**************************/
if (b_ModulNbr < 4) {
/***************/
/* Test if PWM */
/***************/
if ((devpriv->s_BoardInfos.
dw_MolduleConfiguration[b_ModulNbr] &
0xFFFF0000UL) == APCI1710_PWM) {
/**************************/
/* Test the PWM selection */
/**************************/
if (b_PWM <= 1) {
/***************************/
/* Test if PWM initialised */
/***************************/
dw_Status = inl(devpriv->s_BoardInfos.
ui_Address + 12 + (20 * b_PWM) +
(64 * b_ModulNbr));
if (dw_Status & 0x10) {
/***********************/
/* Test if PWM enabled */
/***********************/
if (dw_Status & 0x1) {
*pb_PWMOutputStatus =
(unsigned char) ((dw_Status >> 7)
& 1);
*pb_ExternGateStatus =
(unsigned char) ((dw_Status >> 6)
& 1);
} /* if (dw_Status & 0x1) */
else {
/*******************/
/* PWM not enabled */
/*******************/
DPRINTK("PWM not enabled \n");
i_ReturnValue = -6;
} /* if (dw_Status & 0x1) */
} /* if (dw_Status & 0x10) */
else {
/***********************/
/* PWM not initialised */
/***********************/
DPRINTK("PWM not initialised\n");
i_ReturnValue = -5;
} /* if (dw_Status & 0x10) */
} /* if (b_PWM >= 0 && b_PWM <= 1) */
else {
/******************************/
/* Tor PWM selection is wrong */
/******************************/
DPRINTK("Tor PWM selection is wrong\n");
i_ReturnValue = -4;
} /* if (b_PWM >= 0 && b_PWM <= 1) */
} else {
/**********************************/
/* The module is not a PWM module */
/**********************************/
DPRINTK("The module is not a PWM module\n");
i_ReturnValue = -3;
}
} else {
/***********************/
/* Module number error */
/***********************/
DPRINTK("Module number error\n");
i_ReturnValue = -2;
}
return i_ReturnValue;
}
int i_APCI1710_InsnBitsReadPWMInterrupt(struct comedi_device *dev,
struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data)
{
data[0] = devpriv->s_InterruptParameters.
s_FIFOInterruptParameters[devpriv->
s_InterruptParameters.ui_Read].b_OldModuleMask;
data[1] = devpriv->s_InterruptParameters.
s_FIFOInterruptParameters[devpriv->
s_InterruptParameters.ui_Read].ul_OldInterruptMask;
data[2] = devpriv->s_InterruptParameters.
s_FIFOInterruptParameters[devpriv->
s_InterruptParameters.ui_Read].ul_OldCounterLatchValue;
/**************************/
/* Increment the read FIFO */
/***************************/
devpriv->
s_InterruptParameters.
ui_Read = (devpriv->
s_InterruptParameters.ui_Read + 1) % APCI1710_SAVE_INTERRUPT;
return insn->n;
}