419 lines
9.8 KiB
C++
419 lines
9.8 KiB
C++
|
#include "device_d002.h"
|
||
|
|
||
|
#include "../adlink.h"
|
||
|
|
||
|
device_d002::device_d002(QObject *parent) : gtl::hw::device(parent)
|
||
|
{
|
||
|
_device->set_name("d002");
|
||
|
}
|
||
|
|
||
|
device_d002::~device_d002()
|
||
|
{
|
||
|
stop();
|
||
|
}
|
||
|
|
||
|
QString device_d002::type() const
|
||
|
{
|
||
|
return "d002";
|
||
|
}
|
||
|
|
||
|
|
||
|
bool device_d002::start(QString id, qreal rate)
|
||
|
{
|
||
|
|
||
|
emit status_changed(INIT_IN_PROGRESS);
|
||
|
|
||
|
_ids.clear();
|
||
|
_modules.clear();
|
||
|
|
||
|
_id = id;
|
||
|
|
||
|
bool is_ok;
|
||
|
int int_id = id.toInt(&is_ok);
|
||
|
|
||
|
|
||
|
I16 err = UD_Register_Card(USB_1210, int_id);
|
||
|
|
||
|
if (err >= 0 && err < MAX_USB_DEVICE)
|
||
|
{
|
||
|
U8 sn_test[] = ADLINK_SN_FIXED;
|
||
|
U8 sn[16];
|
||
|
UD_Serial_Number_Read(err, sn);
|
||
|
|
||
|
if (memcmp(sn_test, sn, sizeof(sn)) == 0)
|
||
|
_modules.push_back(err);
|
||
|
else
|
||
|
err = MAX_USB_DEVICE + 1;
|
||
|
}
|
||
|
|
||
|
// _ids.insert(std::pair<int, int>(0, err));
|
||
|
|
||
|
ULONG access_cnt;
|
||
|
|
||
|
for (std::map<int, int>::iterator iter_ids = _ids.begin(); iter_ids != _ids.end(); iter_ids++)
|
||
|
{
|
||
|
if (iter_ids->second < 0 || iter_ids->second >= MAX_USB_DEVICE)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
}
|
||
|
//emit error("init hardware #" + QString::number(iter_ids->first + 1), "UD_Register_Card error. code: " + QString::number(iter_ids->second));
|
||
|
}
|
||
|
|
||
|
_buffer.resize(_modules.size());
|
||
|
_buffer_read.resize(_modules.size());
|
||
|
_count_ai = (int)_modules.size()*4;
|
||
|
|
||
|
_rate = rate;
|
||
|
|
||
|
set_ai();
|
||
|
|
||
|
emit channels_changed();
|
||
|
|
||
|
if (_modules.empty())
|
||
|
return false;
|
||
|
|
||
|
|
||
|
for (int i = 0; i < _modules.size(); i++)
|
||
|
{
|
||
|
err = UD_AI_AsyncClear(_modules[i], &access_cnt);
|
||
|
// err = UD_GPTC_Control(_modules[i], 0, IntENABLE, 0);
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < _modules.size(); i++)
|
||
|
{
|
||
|
|
||
|
err = UD_AI_Channel_Config(_modules[i], get_channel_config(i * 4 + 0), get_channel_config(i * 4 + 1), get_channel_config(i * 4 + 2), get_channel_config(i * 4 + 3));
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition", "UD_AI_Channel_Config error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
err = UD_AI_AsyncDblBufferMode(_modules[i], 1);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition", "UD_AI_AsyncDblBufferMode error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
U16 trig_ctrl;
|
||
|
U16 conv_src;
|
||
|
|
||
|
if (_modules.size() == 1)
|
||
|
{
|
||
|
conv_src = UD_AI_CONVSRC_INT;
|
||
|
trig_ctrl = UD_AI_TRGSRC_SOFT;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
conv_src = UD_AI_CONVSRC_EXT;
|
||
|
|
||
|
if (i == _modules.size() - 1)
|
||
|
{
|
||
|
err = UD_DIO_Config(_modules[i], UD_DIO_PULSE_OUTPUT, UD_DIO_DIGITAL_INPUT);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition. module: " + QString::number(_modules[i]), "UD_DIO_Config error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
err = UD_GPTC_Clear(_modules[i], 0);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition. module: " + QString::number(_modules[i]), "UD_GPTC_Clear error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
err = UD_GPTC_Setup(_modules[i], 0, ContGatedPulseGenPWM, 0, GPTC_OUTPUT_HACTIVE, qRound(40e+6 / rate), 0, 0);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition. module: " + QString::number(_modules[i]), "UD_GPTC_Setup error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
//err = UD_GPTC_Control(_modules[i], 0, IntENABLE, 0);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition. module: " + QString::number(_modules[i]), "UD_GPTC_Control error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
trig_ctrl = UD_AI_TRGSRC_SOFT;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
err = UD_DIO_Config(_modules[i], UD_DIO_DIGITAL_INPUT, UD_DIO_DIGITAL_INPUT);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition. module: " + QString::number(_modules[i]), "UD_DIO_Config error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
trig_ctrl = UD_AI_TRGSRC_DTRIG;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
err = UD_AI_Trigger_Config(_modules[i], conv_src, UD_AI_TRGMOD_POST, trig_ctrl, 0, 0, 0, 0);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition", "UD_AI_Trigger_Config error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
int samples = rate/10/*50*/;
|
||
|
samples = qRound(samples / 128.0) * 128;
|
||
|
|
||
|
U32 size_available = 0;
|
||
|
err = UD_AI_InitialMemoryAllocated(_modules[i], &size_available);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition", "UD_AI_InitialMemoryAllocated error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
int factor_size = 2;
|
||
|
|
||
|
size_available *= 1024;
|
||
|
int size = samples * sizeof(I16) * 4 * factor_size;
|
||
|
|
||
|
if (size > size_available)
|
||
|
{
|
||
|
samples = size_available / sizeof(I16) / factor_size / channels();
|
||
|
|
||
|
samples = qRound(samples / 128.0) * 128;
|
||
|
|
||
|
if (samples * sizeof(I16)*4 > size_available)
|
||
|
samples--;
|
||
|
}
|
||
|
|
||
|
_buffer[i].resize(samples * 4 * factor_size);
|
||
|
|
||
|
|
||
|
F64 rate_actual = 0;
|
||
|
UD_AI_DDS_ActualRate_Get(_modules[i], rate, &rate_actual);
|
||
|
|
||
|
//emit set_timing(_settings->rate(), samples);
|
||
|
|
||
|
U16 gains[] = { AD_B_10_V, AD_B_10_V, AD_B_10_V, AD_B_10_V };
|
||
|
|
||
|
U16 ch[4] = { 0, 1, 2, 3 };
|
||
|
|
||
|
|
||
|
|
||
|
err = UD_AI_ContReadMultiChannels(_modules[i], 4, ch, gains, (U16*)&_buffer[i][0], (_buffer[i].size() * 1), _rate, ASYNCH_OP);
|
||
|
|
||
|
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition", "UD_AI_ContReadMultiChannels error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (i == _modules.size() - 1 && _modules.size() != 1)
|
||
|
{
|
||
|
err = UD_GPTC_Control(_modules[i], 0, IntENABLE, 1);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(INIT_FAILED);
|
||
|
emit error(tr("Init") + QString("d002 "), tr("Error starting module"));
|
||
|
//emit error("start acquisition. module: " + QString::number(_modules[i]), "UD_GPTC_Control error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
_device->set_name(QString("d002") + "[" + id + "]");
|
||
|
_device->set_id(_id);
|
||
|
_device->set_rate(rate);
|
||
|
|
||
|
QThread::start(QThread::HighestPriority);
|
||
|
|
||
|
emit status_changed(OK);
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
bool device_d002::stop()
|
||
|
{
|
||
|
if (isRunning())
|
||
|
{
|
||
|
ULONG access_cnt;
|
||
|
I16 err;
|
||
|
|
||
|
bool res = true;
|
||
|
|
||
|
for (int i = 0; i < _modules.size(); i++)
|
||
|
{
|
||
|
err = UD_AI_AsyncClear(_modules[i], &access_cnt);
|
||
|
|
||
|
res &= err == NoError_;
|
||
|
}
|
||
|
|
||
|
wait();
|
||
|
// return res;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
ULONG access_cnt;
|
||
|
I16 err;
|
||
|
|
||
|
for (int i = 0; i < _modules.size(); i++)
|
||
|
{
|
||
|
err = UD_AI_AsyncClear(_modules[i], &access_cnt);
|
||
|
//err = UD_GPTC_Control(_modules[i], 0, IntENABLE, 0);
|
||
|
err = UD_GPTC_Clear(_modules[i], 0);
|
||
|
err = UD_DIO_Config(_modules[i], UD_DIO_DIGITAL_INPUT, UD_DIO_DIGITAL_INPUT);
|
||
|
err = UD_Release_Card(_modules[i]);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void device_d002::run()
|
||
|
{
|
||
|
|
||
|
|
||
|
BOOLEAN HalfReady;
|
||
|
BOOLEAN fstop;
|
||
|
I16 err;
|
||
|
|
||
|
|
||
|
|
||
|
while (true)
|
||
|
{
|
||
|
|
||
|
bool is_stop = true;
|
||
|
|
||
|
for (int i = 0; i < _modules.size(); i++)
|
||
|
{
|
||
|
_buffer_read[i].resize(_buffer[i].size() / 2);
|
||
|
|
||
|
do
|
||
|
{
|
||
|
err = UD_AI_AsyncDblBufferHalfReady(_modules[i], &HalfReady, &fstop);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(FAILED);
|
||
|
emit error("acquisition. module: " + QString::number(_modules[i]), "UD_AI_AsyncDblBufferHalfReady error. code: " + QString::number(err));
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
err = UD_AI_AsyncDblBufferTransfer(_modules[i], &_buffer_read[i][0]);
|
||
|
|
||
|
if (err != NoError_)
|
||
|
{
|
||
|
emit status_changed(FAILED);
|
||
|
emit error("acquisition. module: " + QString::number(_modules[i]), "UD_AI_AsyncDblBufferTransfer32 error. code: " + QString::number(err));
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} while (!HalfReady && !fstop);
|
||
|
|
||
|
// qDebug() << "read half buffer";
|
||
|
|
||
|
is_stop &= (bool)fstop;
|
||
|
}
|
||
|
|
||
|
if (is_stop)
|
||
|
break;
|
||
|
|
||
|
send_data();
|
||
|
|
||
|
}
|
||
|
|
||
|
emit status_changed(IDLE);
|
||
|
}
|
||
|
|
||
|
void device_d002::send_data()
|
||
|
{
|
||
|
|
||
|
_buffer_send.clear();
|
||
|
|
||
|
|
||
|
int samples = _buffer_read[0].size() / 4;
|
||
|
|
||
|
|
||
|
|
||
|
for (int i = 0; i < samples; i++)
|
||
|
{
|
||
|
for (int j = 0; j < _buffer_read.size(); j++)
|
||
|
{
|
||
|
for (int k = 0; k < 4; k++)
|
||
|
{
|
||
|
F64 voltage;
|
||
|
UD_AI_VoltScale(_modules[j], AD_B_10_V, _buffer_read[j][i*4 + k], &voltage);
|
||
|
// UD_AI_VoltScale32(_modules[j], AD_B_10_V, 0, _buffer_read[j][i*4 + k], &voltage);
|
||
|
|
||
|
if (voltage > 10)
|
||
|
voltage = 10;
|
||
|
else if (voltage < -10)
|
||
|
voltage = -10;
|
||
|
|
||
|
_buffer_send.push_back(voltage);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
set_ai_data(&_buffer_send[0], (int)_buffer_send.size());
|
||
|
|
||
|
|
||
|
// qDebug() << "send data";
|
||
|
|
||
|
emit received_data();
|
||
|
}
|
||
|
|
||
|
U16 device_d002::get_channel_config(int channel) const
|
||
|
{
|
||
|
return UD_AI_Differential;
|
||
|
}
|
||
|
|