Sorry for the long delay in replying.
It seems that the PWM subdevice for the PCI1760 needs to be operated
differently to the PWM subdevice on some other devices. On the PCI1760
PWM subdevice, all operations are done using the INSN_CONFIG instruction:
* INSN_CONFIG_PWM_OUTPUT - disables PWM output and sets PWM high and low
periods in nanoseconds:
lsampl_t data[5];
comedi_insn insn;
insn.subdev = 2; // PWM subdevice
insn.insn = INSN_CONFIG;
insn.chanspec = channel; // 0 or 1
insn.n = 5;
insn.data = data;
data[0] = INSN_CONFIG_PWM_OUTPUT;
// set rounding for high period
data[1] = CMDF_ROUND_NEAREST; // or CMDF_ROUND_UP or CMDF_ROUND_DOWN
data[2] = high_ns; // high period in ns
// set rounding for low period
data[3] = CMDF_ROUND_NEAREST; // or CMDF_ROUND_UP or CMDF_ROUND_DOWN
data[4] = low_ns; // low period in ns
ret = comedi_do_insn(device, &insn);
Note: on success, data[2] and data[4] are set to the rounded high and
low periods.
* INSN_CONFIG_ARM - enables PWM output and sets number of cycles or
"continuous":
lsampl_t data[2];
comedi_insn insn;
insn.subdev = 2; // PWM subdevice
insn.insn = INSN_CONFIG;
insn.chanspec = channel; // 0 or 1
insn.n = 2;
insn.data = data;
data[0] = INSN_CONFIG_ARM;
data[1] = 0; // 0 = "continuous", 1 to 65535 = number of cycles
ret = comedi_do_insn(device, &insn);
* INSN_CONFIG_DISARM - disables PWM output:
lsampl_t data[1];
comedi_insn insn;
insn.subdev = 2; // PWM subdevice
insn.insn = INSN_CONFIG;
insn.chanspec = channel; // 0 or 1
insn.n = 1;
insn.data = data;
data[0] = INSN_CONFIG_DISARM;
ret = comedi_do_insn(device, &insn);
* INSN_CONFIG_GET_PWM_OUTPUT - get configured high and low periods:
lsampl_t data[3];
comedi_insn insn;
insn.subdev = 2; // PWM subdevice
insn.insn = INSN_CONFIG;
insn.chanspec = channel; // 0 or 1
insn.n = 3;
insn.data = data;
data[0] = INSN_CONFIG_GET_PWM_OUTPUT;
ret = comedi_do_insn(device, &insn);
On success, the high period is in data[1] and the low period is in
data[2].
* INSN_CONFIG_GET_PWM_STATUS - get PWM status:
lsampl_t data[2];
comedi_insn insn;
insn.subdev = 2; // PWM subdevice
insn.insn = INSN_CONFIG;
insn.chanspec = channel; // 0 or 1
insn.n = 2;
insn.data = data;
data[0] = INSN_CONFIG_GET_PWM_STATUS;
ret = comedi_do_insn(device, &insn);
On success, the enable/disable status in in data[1].
Unfortunately, there seems to be a bug in the driver which probably
stops most of the above instructions from working. The problem is that
the driver is sending wrong command code to read the PWM status
register. In the driver code at
<
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/comedi/drivers/adv_pci1760.c?h=v6.1>
the PCI1760_CMD_GET_STATUS macro should be defined as 0x07, not 0x03.
I'll send a patch to the Linux kernel mailing lists to get it fixed, but
it will be some time before it makes its way into the stable kernel
versions.
--
-=( Ian Abbott <
abb...@mev.co.uk> || MEV Ltd. is a company )=-
-=( registered in England & Wales. Regd. number: 02862268. )=-
-=( Regd. addr.: S11 & 12 Building 67, Europa Business Park, )=-
-=( Bird Hall Lane, STOCKPORT, SK3 0XA, UK. ||
www.mev.co.uk )=-