test_sdk/hw/d002/device_d002.cpp

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;
}