test_sdk/hw/d001/device_d001.cpp

471 lines
12 KiB
C++
Raw Normal View History

#include "device_d001.h"
#include "../adlink.h"
device_d001::device_d001(QObject *parent) : gtl::hw::device(parent), _is_full_restarting(true)
{
_count_ai = 4;
set_ai();
_device->set_name("d001");
}
device_d001::~device_d001()
{
stop();
}
QString device_d001::type() const
{
return "d001";
}
bool device_d001::start(QString id, qreal rate)
{
emit status_changed(INIT_IN_PROGRESS);
_ids.clear();
_modules.clear();
_id = id;
std::vector<int> ids;
QStringList str_ids = id.split(',');
for(int i = 0; i < str_ids.size(); i++)
{
bool is_ok;
int int_id = str_ids[i].toInt(&is_ok);
if(is_ok)
ids.push_back(int_id);
}
_ids_current.clear();
std::copy(ids.begin(), ids.end(), std::back_inserter(_ids_current));
U8 sn_test[] = ADLINK_SN_FIXED;
for (int i = 0; i < ids.size(); i++)
{
I16 err = UD_Register_Card(USB_2405, ids[i]);
_ids.insert(std::pair<int, int>(i, err));
if (err >= 0 && err < MAX_USB_DEVICE)
{
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;
}
}
ULONG access_cnt;
I16 err;
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("d001 ") + " #" + QString::number(iter_ids->first + 1), 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();
QJsonArray array_config = _config.toArray();
for(int i = 0; i < qMin(array_config.size(), count_ai()); i++)
{
ai(i)->blockSignals(true);
ai(i)->set_iepe(array_config[i].toObject().value("iepe").toBool());
ai(i)->set_coupling(array_config[i].toObject().value("ac").toBool());
ai(i)->blockSignals(false);
}
if (_is_full_restarting)
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_2405_Chan_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("d001 ") + " #" + QString::number(i + 1), tr("Error starting module"));
//emit error("start acquisition", "UD_AI_2405_Chan_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("d001 ") + " #" + QString::number(i + 1), 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 = P2405_AI_CONVSRC_INT;
trig_ctrl = P2405_AI_TRGSRC_SOFT;
}
else
{
conv_src = P2405_AI_CONVSRC_EXT;
if (i == _modules.size() - 1)
{
err = UD_DIO_2405_Config(_modules[i], P2405_PULSE_OUTPUT, P2405_DIGITAL_INPUT);
if (err != NoError_)
{
emit status_changed(INIT_FAILED);
emit error(tr("Init") + QString("d001 ") + " #" + QString::number(i + 1), tr("Error starting module"));
//emit error("start acquisition. module: " + QString::number(_modules[i]), "UD_DIO_2405_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("d001 ") + " #" + QString::number(i + 1), 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("d001 ") + " #" + QString::number(i + 1), 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("d001 ") + " #" + QString::number(i + 1), tr("Error starting module"));
//emit error("start acquisition. module: " + QString::number(_modules[i]), "UD_GPTC_Control error. code: " + QString::number(err));
break;
}
trig_ctrl = P2405_AI_TRGSRC_SOFT;
}
else
{
err = UD_DIO_2405_Config(_modules[i], P2405_DIGITAL_INPUT, P2405_DIGITAL_INPUT);
if (err != NoError_)
{
emit status_changed(INIT_FAILED);
emit error(tr("Init") + QString("d001 ") + " #" + QString::number(i + 1), tr("Error starting module"));
//emit error("start acquisition. module: " + QString::number(_modules[i]), "UD_DIO_2405_Config error. code: " + QString::number(err));
break;
}
trig_ctrl = P2405_AI_TRGSRC_DTRIG;
}
}
err = UD_AI_2405_Trig_Config(_modules[i], conv_src, P2405_AI_TRGMOD_POST, trig_ctrl, 0, 0, 0, 0);
if (err != NoError_)
{
emit status_changed(INIT_FAILED);
emit error(tr("Init") + QString("d001 ") + " #" + QString::number(i + 1), tr("Error starting module"));
//emit error("start acquisition", "UD_AI_2405_Trig_Config error. code: " + QString::number(err));
break;
}
int samples = rate/10;
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("d001 ") + " #" + QString::number(i + 1), 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(I32) * 4 * factor_size;
if (size > size_available)
{
samples = size_available / sizeof(I32) / factor_size / channels();
samples = qRound(samples / 128.0) * 128;
if (samples * sizeof(I32)*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("d001 ") + " #" + QString::number(i + 1), 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("d001 ") + " #" + QString::number(i + 1), 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("d001") + "[" + id + "]");
_device->set_id(_id);
_device->set_rate(rate);
QThread::start(QThread::HighestPriority);
emit status_changed(OK);
return true;
}
bool device_d001::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_2405_Config(_modules[i], P2405_DIGITAL_INPUT, P2405_DIGITAL_INPUT);
err = UD_Release_Card(_modules[i]);
}
return true;
}
void device_d001::set_config(const QJsonValue &config)
{
gtl::hw::device::set_config(config);
if(isRunning())
restart();
}
void device_d001::run()
{
qDebug() << "device started";
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);
QString title_err = "acquisition. module: " + QString::number(_modules[i]);
QString msg_err = QString("UD_AI_AsyncDblBufferHalfReady error. code: ") + QString::number(err);
emit error(title_err, msg_err);
qDebug() << title_err << msg_err;
return;
}
err = UD_AI_AsyncDblBufferTransfer32(_modules[i], &_buffer_read[i][0]);
if (err != NoError_)
{
emit status_changed(FAILED);
QString title_err = "acquisition. module: " + QString::number(_modules[i]);
QString msg_err = QString("UD_AI_AsyncDblBufferTransfer32 error. code: ") + QString::number(err);
emit error(title_err, msg_err);
qDebug() << title_err << msg_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_d001::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_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_d001::get_channel_config(int channel)
{
U16 iepe = (ai(channel)->is_iepe() ? P2405_AI_EnableIEPE : P2405_AI_DisableIEPE);
U16 coupling = (ai(channel)->is_iepe() ? P2405_AI_Coupling_AC : (ai(channel)->is_coupling() ? P2405_AI_Coupling_AC : P2405_AI_Coupling_None));
return iepe | coupling | P2405_AI_Differential;
}
void device_d001::ai_iepe_changed()
{
restart();
}
void device_d001::ai_coupling_changed()
{
restart();
}