#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(0, err)); ULONG access_cnt; for (std::map::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; }