I'm currently working on a project where I must set up PCI 6259 in real-time Linux Xenomai, probably with analogy library. The development environment is C++ in QT. I manage to implement analog output with analogy, however, I find little resources, examples or online help about how to configure or read quadrature X4 encoder through analogy API in Xenomai. Could anyone give me an example code?
FYI: I can make it work in RTAI Linux, with comedi library. The code is extracted and attached below to show how I configured the counter, in case it might help. I just want to do the same thing in Xenomai. Thank you in advance,
#include <comedilib.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <sched.h>
#include <sys/mman.h>
#include <string.h>
#include <time.h>
static comedi_t* pDevice = nullptr;
/**
* @brief DAQ_InitDevice initialized the DAQ card PCI-6259
* @return
*/
int32 DAQ_InitDevice()
{
// If already created.
if (pDevice != nullptr) return 0;
// Create device
char* pDeviceName = "/dev/comedi0";
pDevice = comedi_open(pDeviceName);
if (pDevice == nullptr) {
qDebug("comedi_open");
return -1;
}
// Set global out of range behavior
comedi_set_global_oor_behavior(COMEDI_OOR_NUMBER);
return 0;
}
/**
* @brief DAQ_InitCounter_Sub
* @param device: PCI-6259
* @param subdev: represents counter subdevice
* @return
*/
int32 DAQ_InitCounter_Sub(comedi_t *device, const int subdev)
{
lsampl_t initial_value;
lsampl_t data;
lsampl_t maxData_c;
lsampl_t counter_mode;
comedi_range *range_info_c;
int a,b,z;
int stt;
// Reset counter
stt = comedi_reset(device, subdev);
if (stt<0) return stt;
// Set counter mode
counter_mode = (NI_GPCT_COUNTING_MODE_QUADRATURE_X4_BITS |
NI_GPCT_COUNTING_DIRECTION_HW_UP_DOWN_BITS);
range_info_c = comedi_get_range(device, subdev, 0, 0);
maxData_c = comedi_get_maxdata(device, subdev, 0);
initial_value = comedi_from_phys(0, range_info_c, maxData_c);
/* set initial counter value by writing to channel 0 */
stt = comedi_data_write(device, subdev, 0, 0, 0, initial_value);
if (stt<0) return stt;
/* set "load a" register to initial_value by writing to channel 1 */
stt = comedi_data_write(device, subdev, 1, 0, 0, initial_value);
if (stt<0) return stt;
/* set "load b" register to initial_value by writing to channel 2 */
stt = comedi_data_write(device, subdev, 2, 0, 0, initial_value);
if (stt<0) return stt;
stt = comedi_set_gate_source(device, subdev, 0, 0, NI_GPCT_DISABLED_GATE_SELECT);
if (stt<0) return stt;
stt = comedi_set_gate_source(device, subdev, 0, 1, NI_GPCT_DISABLED_GATE_SELECT);
if (stt<0) return stt;
if (subdev == 12) {
// Left motor, counter 1
// Set pin number
a = NI_GPCT_PFI_OTHER_SELECT(3);
b = NI_GPCT_PFI_OTHER_SELECT(11);
} else if (subdev == 11) {
// Right motor, counter 0
// Set pin number
a = NI_GPCT_PFI_OTHER_SELECT(8);
b = NI_GPCT_PFI_OTHER_SELECT(10);
} else {
qDebug("Error: DAQ_InitCounter_Sub: No such counter %d !! \n", subdev);
return -1;
}
z = NI_GPCT_DISABLED_GATE_SELECT;
stt = comedi_set_other_source(device, subdev, 0, NI_GPCT_SOURCE_ENCODER_A, a);
if (stt<0) return stt;
stt = comedi_set_other_source(device, subdev, 0, NI_GPCT_SOURCE_ENCODER_B, b);
if (stt<0) return stt;
stt = comedi_set_other_source(device, subdev, 0, NI_GPCT_SOURCE_ENCODER_Z, z);
if (stt<0) return stt;
stt = comedi_set_counter_mode(device, subdev, 0, counter_mode);
if (stt<0) return stt;
stt = comedi_arm(device, subdev, NI_GPCT_ARM_IMMEDIATE);
if (stt<0) return stt;
return stt;
}
/**
* @brief DAQ_InitCounter initializes two counters: the subdevice 11 & 12
* @param pDevice: PCI-6259 device.
* @return
*/
int32 DAQ_InitCounter(comedi_t* pDevice)
{
const int subdev_counter0 = 11;
const int subdev_counter1 = 12;
int stt = 0;
if(pDevice == nullptr) {
qDebug("Error: No comedi DAQ device found!! \n");
return -1;
}
// Init for counter 0: right motor
stt = DAQ_InitCounter_Sub(pDevice, subdev_counter0);
if (stt<0) return stt;
// Init for counter 1: left motor
stt = DAQ_InitCounter_Sub(pDevice, subdev_counter1);
if (stt<0) return stt;
return stt;
}
/**
* @brief DAQ_ReadCounter reads counters' value. The device is defined by
* static pDevice; the counters are attached to subdevice 11 & 12.
* @param data_left: raw data, output for left motor position
* @param data_right: raw data, output for right motor position
* @return status
*/
int32 DAQ_ReadCounter(lsampl_t &data_left, lsampl_t &data_right)
{
const int subdev_counter0 = 11;
const int subdev_counter1 = 12;
int range = 0;
int aref = 0;
int channel = 0;
int stt = 0;
if(pDevice == nullptr) {
qDebug("Error: No comedi DAQ device found!! \n");
return -1;
}
//
// Read right motor position :
//
stt = comedi_data_read(pDevice, subdev_counter0, channel, range, aref, &data_right);
if (stt<0) return stt;
//
// Read left motor position :
//
stt = comedi_data_read(Mechanism::mDevice, subdev_counter1, channel, range, aref, &data_left);
if (stt<0) return stt;
return stt;
}