Commit bbb57a25 authored by Юрий Аляев's avatar Юрий Аляев

New fucntions for Fastwel cards

parent e4527c9f
......@@ -3,6 +3,7 @@
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <alloca.h>
#include "ComediInterface.h"
// -----------------------------------------------------------------------------
using namespace UniSetTypes;
......@@ -43,6 +44,37 @@ int ComediInterface::getAnalogChannel( int subdev, int channel, int range, int a
return data;
}
// -----------------------------------------------------------------------------
std::vector<lsampl_t> ComediInterface::getAnalogPacket( int subdev, int channel, int range, int aref )
throw(UniSetTypes::Exception)
{
lsampl_t* data = (lsampl_t *)alloca(1024); /* FIFO size, maximum possible samples */
comedi_insn insn;
memset(&insn, 0, sizeof(insn));
insn.insn = INSN_READ;
insn.n = 1024;
insn.data = data;
insn.subdev = subdev;
insn.chanspec = CR_PACK(channel, range, aref);
int ret = comedi_do_insn(card, &insn);
if( ret < 0 )
{
ostringstream err;
err << "(ComediInterface:getAnalogPacket): can`t read data from subdev=" << subdev
<< " channel=" << channel << " range=" << range <<" aref="<< aref
<< " err: " << ret << " (" << strerror(ret) << ")";
throw Exception(err.str());
return std::vector<lsampl_t>(0);
}
std::vector<lsampl_t> result(ret);
if(ret > 0)
memcpy(&result[0], data, ret * sizeof(lsampl_t));
return result;
}
// -----------------------------------------------------------------------------
void ComediInterface::setAnalogChannel( int subdev, int channel, int data, int range, int aref )
throw(UniSetTypes::Exception)
{
......@@ -82,6 +114,42 @@ void ComediInterface::setDigitalChannel( int subdev, int channel, bool bit )
throw Exception(err.str());
}
}
// -----------------------------------------------------------------------------
void ComediInterface::instrChannel( int subdev, int channel, const std::string instr,
std::vector<lsampl_t> args, int range, int aref )
throw(UniSetTypes::Exception)
{
lsampl_t ins = instr2type(instr);
comedi_insn insn;
if(ins < 0)
{
ostringstream err;
err << "(ComediInterface:instrChannel): unknown instruction "
<< " subdev=" << subdev << " channel=" << channel << " instruction=" << instr;
throw Exception(err.str());
return;
}
args.insert(args.begin(), ins);
memset(&insn,0,sizeof(insn));
insn.insn = INSN_CONFIG;
insn.n = args.size();
insn.data = &args[0];
insn.subdev = subdev;
insn.chanspec = CR_PACK(channel,range,aref);
if( comedi_do_insn(card,&insn) < 0 )
{
ostringstream err;
err << "(ComediInterface:instrChannel): can`t execute the instruction "
<< " subdev=" << subdev << " channel=" << channel << " instruction=" << instr;
throw Exception(err.str());
}
return;
}
// -----------------------------------------------------------------------------
void ComediInterface::configureChannel( int subdev, int channel, ChannelType t,
int range, int aref )
......@@ -139,21 +207,39 @@ void ComediInterface::configureChannel( int subdev, int channel, ChannelType t,
void ComediInterface::configureSubdev( int subdev, SubdevType t )
throw(UniSetTypes::Exception)
{
lsampl_t cmd = 102;
static const unsigned char chans[4] = {0, 8, 16, 20}; /* We can configure only one channel per 8-bit port (4-bit for CL and CH). This is not true for UNIO, the more general mechanism should be applied... */
lsampl_t cmd[4]; /* Ports A, B, CL, CH */
comedi_insn insn;
memset(&insn,0,sizeof(insn));
insn.insn = INSN_CONFIG;
insn.n = 1;
insn.data = &cmd;
insn.unused[0] = t;
insn.subdev = subdev;
insn.chanspec = 0;
if( comedi_do_insn(card,&insn) < 0 )
switch(t)
{
ostringstream err;
err << "(ComediInterface:configureSubdev): can`t configure subdev "
<< " subdev=" << subdev << " type=" << t;
throw Exception(err.str());
case TBI24_0:
cmd[0] = cmd[1] = cmd[2] = cmd[3] = INSN_CONFIG_DIO_INPUT;
break;
case TBI0_24:
default:
cmd[0] = cmd[1] = cmd[2] = cmd[3] = INSN_CONFIG_DIO_OUTPUT;
break;
case TBI16_8:
cmd[0] = cmd[1] = INSN_CONFIG_DIO_INPUT;
cmd[2] = cmd[3] = INSN_CONFIG_DIO_OUTPUT;
break;
}
for(int i = 0; i < 4; i++) {
memset(&insn,0,sizeof(insn));
insn.insn = INSN_CONFIG;
insn.n = 1;
insn.data = &cmd[i];
insn.subdev = subdev;
insn.chanspec = CR_PACK(chans[i], 0, 0);
if( comedi_do_insn(card,&insn) < 0 )
{
ostringstream err;
err << "(ComediInterface:configureSubdev): can`t configure subdev "
<< " subdev=" << subdev << " type=" << t;
throw Exception(err.str());
}
}
}
// -----------------------------------------------------------------------------
......@@ -191,3 +277,46 @@ ComediInterface::SubdevType ComediInterface::str2type( const std::string s )
return Unknown;
}
// -----------------------------------------------------------------------------
ComediInterface::EventType ComediInterface::event2type( const std::string s )
{
if( s == "Front" )
return Front;
if( s == "Rear" )
return Rear;
if( s == "FrontThenRear" )
return FrontThenRear;
return No;
}
// -----------------------------------------------------------------------------
lsampl_t ComediInterface::instr2type( const std::string s )
{
if( s == "AVERAGING" || s == "BOUNCE_SUPPRESSION" ) /* This are the same instructions, one for AI, another for DI */
return INSN_CONFIG_AVERAGING;
if( s == "TIMER" )
return INSN_CONFIG_TIMER_1;
if( s == "INPUT_MASK" )
return INSN_CONFIG_INPUT_MASK;
if( s == "FILTER" )
return INSN_CONFIG_FILTER;
if( s == "0mA" )
return INSN_CONFIG_0MA;
if( s == "COMPL" )
return INSN_CONFIG_COMPL;
if( s == "COUNTER" )
return INSN_CONFIG_COUNTER;
if( s == "DI_MODE" )
return INSN_CONFIG_DI_MODE;
return -1;
}
// -----------------------------------------------------------------------------
......@@ -4,6 +4,7 @@
#define ComediInterface_H_
// -----------------------------------------------------------------------------
#include <string>
#include <vector>
#include <comedilib.h>
#include "Exceptions.h"
// -----------------------------------------------------------------------------
......@@ -17,6 +18,9 @@ class ComediInterface
int getAnalogChannel( int subdev, int channel, int range=0, int aref=AREF_GROUND )
throw(UniSetTypes::Exception);
std::vector<lsampl_t> getAnalogPacket( int subdev, int channel, int range=0, int aref=AREF_GROUND )
throw(UniSetTypes::Exception);
void setAnalogChannel( int subdev, int channel, int data, int range=0, int aref=AREF_GROUND )
throw(UniSetTypes::Exception);
......@@ -32,10 +36,10 @@ class ComediInterface
{
DI = INSN_CONFIG_DIO_INPUT,
DO = INSN_CONFIG_DIO_OUTPUT,
AI = 100, // INSN_CONFIG_AIO_INPUT,
AO = 101 // INSN_CONFIG_AIO_OUTPUT
AI = INSN_CONFIG_AIO_INPUT,
AO = INSN_CONFIG_AIO_OUTPUT
};
enum SubdevType
{
Unknown = 0,
......@@ -43,18 +47,31 @@ class ComediInterface
TBI0_24 = 2,
TBI16_8 = 3
};
enum EventType
{
No = 0,
Front = 1,
Rear = 2,
FrontThenRear = 3
};
static std::string type2str( SubdevType t );
static SubdevType str2type( const std::string s );
static EventType event2type( const std::string s );
static lsampl_t instr2type( const std::string s );
void configureSubdev( int subdev, SubdevType type ) throw(UniSetTypes::Exception);
void configureChannel( int subdev, int channel, ChannelType type, int range=0, int aref=0 )
throw(UniSetTypes::Exception);
/* Perform extended instruction at the channel. Arguments are being taken as C++ vector. */
void instrChannel( int subdev, int channel, const std::string instr, std::vector<lsampl_t> args, int range=0, int aref=0 )
throw(UniSetTypes::Exception);
inline const std::string devname(){ return dname; }
protected:
comedi_t* card; /*!< / */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment