731 lines
26 KiB
C++
731 lines
26 KiB
C++
#include "adccluster_device.h"
|
|
|
|
ADCCluster_device::ADCCluster_device(QObject *parent)
|
|
: gtl::hw::device(parent),
|
|
_slavesADC(new QList<ADC *>()),
|
|
_adcs(new QMap<int, ADC *>),
|
|
_config(new QJsonObject()),
|
|
_state(ADCCluster_ns::clusterState::IDLE),
|
|
_rrdStack(new RRDStack()),
|
|
_isMasterAllreadyInited(false),
|
|
_currentSingleStack(new singleStack(0, ADC_ns::bitDepth::BIT16, new QList<ADCChannel *>(), 0)),
|
|
_singleQueue(new QQueue<singleStack *>()),
|
|
_clusterQueue(new QQueue<clusterStack *>()),
|
|
_singleMode(true),
|
|
_initError(false)
|
|
{
|
|
|
|
}
|
|
|
|
ADCCluster_device::~ADCCluster_device()
|
|
{
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "cluster desctructor";
|
|
#endif
|
|
stop();
|
|
}
|
|
|
|
void ADCCluster_device::restart()
|
|
{
|
|
|
|
}
|
|
|
|
ADC *ADCCluster_device::_initMasterADC(QList<int> * adcSNs)
|
|
{
|
|
int __masterSN = adcSNs->at(0);
|
|
|
|
ADC * __masterADC = new ADC(__masterSN);
|
|
|
|
QObject::connect(__masterADC, &ADC::ADC_connected, [=]() {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << QTime::currentTime().toString() << "master adc connected" << __masterSN;
|
|
#endif
|
|
});
|
|
|
|
QObject::connect(__masterADC, &ADC::ADC_disconnected, [=]() {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << QTime::currentTime().toString() << "master adc disconnected" << __masterSN;
|
|
#endif
|
|
|
|
_destroySlaves();
|
|
|
|
// hw
|
|
_device->set_name("ADCCluster [MASTER DISCONNECTED]");
|
|
// hw
|
|
|
|
_state = ADCCluster_ns::clusterState::CONFIG;
|
|
});
|
|
|
|
QObject::connect(__masterADC, &ADC::ADC_started, [=]() {
|
|
_rrdStack = new RRDStack();
|
|
_state = ADCCluster_ns::clusterState::RUNNING;
|
|
__masterADC->setDataCounter(0);
|
|
_device->set_name("ADCCluster [RUNNING]");
|
|
});
|
|
|
|
|
|
QObject::connect(__masterADC, &ADC::ADC_configReadingFinished, [=]() {
|
|
|
|
#ifdef CLUSTER_DEBUG
|
|
_debugPrintADCParams(__masterADC);
|
|
#endif
|
|
|
|
if (__masterADC->getModelID() == 0) { // TODO критериии некорректной инициализации
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "init failed";
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
for (int __slaveID = 1; __slaveID < adcSNs->count(); __slaveID++) {
|
|
ADC * __slave = _initSlaveADC(adcSNs->at(__slaveID), __slaveID);
|
|
_slavesADC->append(__slave);
|
|
__slave->start();
|
|
}
|
|
|
|
// hw
|
|
_device->set_name("ADCCluster [WAITING SLAVES]");
|
|
// hw
|
|
|
|
for (int __i=0; __i<_slavesADC->count(); __i++) {
|
|
ADC * __slave = _slavesADC->at(__i);
|
|
QObject::connect(__slave, &ADC::ADC_disconnected, [=]() {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << QTime::currentTime().toString() << "slave adc disconnected" << __slave->getSN();
|
|
#endif
|
|
|
|
// hw
|
|
_device->set_name("ADCCluster [SLAVE DISONNECTED]");
|
|
// hw
|
|
|
|
_state = ADCCluster_ns::clusterState::CONFIG;
|
|
|
|
if (__masterADC->getADCState() == ADC_ns::ADCState::RUNNING) {
|
|
__masterADC->stopADC();
|
|
}
|
|
_stopSlaves();
|
|
});
|
|
|
|
QObject::connect(__slave, &ADC::ADC_started, [=]{
|
|
bool __allReady = true;
|
|
|
|
for (int __i = 0; __i < _slavesADC->count(); __i++) {
|
|
if (_slavesADC->at(__i)->getADCState() != ADC_ns::ADCState::RUNNING) {
|
|
__allReady = false;
|
|
}
|
|
|
|
if (_slavesADC->at(__i)->getADCState() == ADC_ns::ADCState::WAITING_COMMAND) {
|
|
_slavesADC->at(__i)->startADC(ADC_ns::SYNCMode::SLAVE);
|
|
}
|
|
|
|
if (_slavesADC->at(__i)->getModelID() != __masterADC->getModelID()) {
|
|
__allReady = false;
|
|
_state = ADCCluster_ns::clusterState::CONFIG;
|
|
_device->set_name("ADCCluster [SLAVES INCOMPATIBILITY]");
|
|
}
|
|
}
|
|
|
|
if (__allReady) {
|
|
if (!_isMasterAllreadyInited) {
|
|
// hw api
|
|
_rate = __masterADC->getFreq();
|
|
_device->set_rate(__masterADC->getFreq());
|
|
_device->set_id("ADCCluster");
|
|
_device->set_name("ADCCluster [STARTING CLUSTER]");
|
|
_count_ai = (_slavesADC->count() + 1) * (__masterADC->getChannelsCount() + __masterADC->getIsTachoSignal());
|
|
set_ai();
|
|
|
|
for (int __i = 0; __i < _count_ai; __i++) {
|
|
int __adcNo = __i / (__masterADC->getChannelsCount() + __masterADC->getIsTachoSignal());
|
|
int __channelNo = __i % (__masterADC->getChannelsCount() + __masterADC->getIsTachoSignal());
|
|
|
|
int __adcSN = 0;
|
|
|
|
if (__adcNo == 0) {
|
|
__adcSN = __masterADC->getSN();
|
|
} else {
|
|
__adcSN = _slavesADC->at(__adcNo - 1)->getSN();
|
|
}
|
|
|
|
QString __prefix = QString::number(__adcSN);
|
|
|
|
if (__channelNo == __masterADC->getChannelsCount()) {
|
|
ai(__i)->set_name(__prefix + " [ pulse ]");
|
|
} else {
|
|
ai(__i)->set_name(__prefix + " [ " + QString::number(__channelNo) + " ]");
|
|
}
|
|
}
|
|
|
|
// hw api
|
|
|
|
_isMasterAllreadyInited = true;
|
|
}
|
|
|
|
__masterADC->startADC(ADC_ns::SYNCMode::MASTER);
|
|
}
|
|
|
|
});
|
|
}
|
|
});
|
|
|
|
QObject::connect(__masterADC, &ADC::ADC_dataPacketReceived, [=](QByteArray packet) {
|
|
trans_ns::bytes2long __num;
|
|
__num.bytes.LL = packet[0];
|
|
__num.bytes.LH = packet[1];
|
|
__num.bytes.HL = packet[2];
|
|
__num.bytes.HH = packet[3];
|
|
|
|
if (_masterADC->getDataCounter() != __num.twinWord) {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "propusk: " << _masterADC->getSN() << _masterADC->getDataCounter() << " : " << __num.twinWord << " packets lost = " << __num.twinWord - _masterADC->getDataCounter();
|
|
#endif
|
|
_masterADC->setDataCounter(__num.twinWord);
|
|
}
|
|
_masterADC->incDataCounter();
|
|
|
|
clusterStack * __currentStack = _rrdStack->getStackByPacketNumber(__num.twinWord);
|
|
|
|
if (__currentStack == nullptr) {
|
|
__currentStack = new clusterStack(45 * (int)(__num.twinWord / 45), _masterADC->getBitDeph(), _masterADC->getChannelsConfig(), _masterADC->getSamplesCount(), _slavesADC);
|
|
_clusterQueue->enqueue(_rrdStack->pushStack(__currentStack));
|
|
}
|
|
|
|
int __packetIndex = __num.twinWord - __currentStack->getFirstPacketIndex();
|
|
|
|
__currentStack->insert(0, __packetIndex, packet);
|
|
|
|
});
|
|
|
|
return __masterADC;
|
|
}
|
|
|
|
void ADCCluster_device::_stopSlaves()
|
|
{
|
|
foreach(ADC * __slave, *_slavesADC) {
|
|
if (__slave->getADCState() == ADC_ns::ADCState::RUNNING){
|
|
__slave->stopADC();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ADCCluster_device::_destroySlaves()
|
|
{
|
|
while (!_slavesADC->isEmpty()) {
|
|
ADC * __slave = _slavesADC->takeAt(0);
|
|
__slave->stop();
|
|
delete __slave;
|
|
}
|
|
}
|
|
|
|
|
|
ADC * ADCCluster_device::_initSlaveADC(uint16_t sn, int adcNo)
|
|
{
|
|
ADC * __slaveADC = new ADC(sn);
|
|
|
|
QObject::connect(__slaveADC, &ADC::ADC_connected, [=]() {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << QTime::currentTime().toString() << "slave adc connected" << sn;
|
|
#endif
|
|
});
|
|
|
|
QObject::connect(__slaveADC, &ADC::ADC_configReadingFinished, [=]() {
|
|
#ifdef CLUSTER_DEBUG
|
|
_debugPrintADCParams(__slaveADC);
|
|
#endif
|
|
|
|
if (__slaveADC->getModelID() == 0) { // TODO критериии некорректной инициализации
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "init failed";
|
|
#endif
|
|
//emit status_changed(fail);
|
|
return;
|
|
}
|
|
|
|
__slaveADC->startADC(ADC_ns::SYNCMode::SLAVE);
|
|
});
|
|
|
|
QObject::connect(__slaveADC, &ADC::ADC_dataPacketReceived, [=](QByteArray packet) {
|
|
trans_ns::bytes2long __num;
|
|
__num.bytes.LL = packet[0];
|
|
__num.bytes.LH = packet[1];
|
|
__num.bytes.HL = packet[2];
|
|
__num.bytes.HH = packet[3];
|
|
|
|
if (__slaveADC->getDataCounter() != __num.twinWord) {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "propusk: " << __slaveADC->getSN() << __slaveADC->getDataCounter() << " : " << __num.twinWord << " packets lost = " << __num.twinWord - __slaveADC->getDataCounter();
|
|
#endif
|
|
__slaveADC->setDataCounter(__num.twinWord);
|
|
}
|
|
__slaveADC->incDataCounter();
|
|
|
|
clusterStack * __currentStack = _rrdStack->getStackByPacketNumber(__num.twinWord);
|
|
|
|
if (__currentStack == nullptr) {
|
|
__currentStack = new clusterStack(45 * (int)(__num.twinWord / 45), _masterADC->getBitDeph(), _masterADC->getChannelsConfig(), _masterADC->getSamplesCount(), _slavesADC);
|
|
_clusterQueue->enqueue(_rrdStack->pushStack(__currentStack));
|
|
}
|
|
|
|
int __packetIndex = __num.twinWord - __currentStack->getFirstPacketIndex();
|
|
|
|
__currentStack->insert(adcNo, __packetIndex, packet);
|
|
});
|
|
|
|
return __slaveADC;
|
|
}
|
|
|
|
void ADCCluster_device::_runSingleMode()
|
|
{
|
|
int __samplesCount = _singleADC->getSamplesCount();
|
|
int __clusterPacketSize = 45;
|
|
int __outputChannelsCount = _singleADC->getChannelsCount() + (int)_singleADC->getIsTachoSignal();
|
|
int __tachoCannelIndex = _singleADC->getChannelsCount();
|
|
int __oneBufferSize = __clusterPacketSize * __samplesCount * __outputChannelsCount;
|
|
|
|
QQueue<singleStack *> __temp;
|
|
|
|
while (!_singleQueue->isEmpty()) {
|
|
__temp.enqueue(_singleQueue->dequeue());
|
|
}
|
|
|
|
if (__temp.count() == 0) return;
|
|
|
|
_buffer_read.resize(__oneBufferSize * __temp.count());
|
|
|
|
for (int __i = 0; __i < __oneBufferSize * __temp.count(); __i++) {
|
|
_buffer_read[__i] = 0;
|
|
}
|
|
|
|
int __counter = 0;
|
|
|
|
while (!__temp.isEmpty()) {
|
|
singleStack * __clusterPacket = __temp.dequeue();
|
|
|
|
for (int __packetNo = 0; __packetNo < __clusterPacketSize; __packetNo++) {
|
|
for (int __sampleNo = 0; __sampleNo < __samplesCount; __sampleNo++) {
|
|
// номер пакета * количество отсчетов * количество каналов + количество каналов * номер отсчета
|
|
int __samplePosition = __outputChannelsCount * (__packetNo * __samplesCount + __sampleNo);
|
|
|
|
for (int __channelIndex = 0; __channelIndex < _singleADC->getChannelsCount(); __channelIndex++) {
|
|
// количество отсчетов * номер канала + порядковый номер отсчета
|
|
_buffer_read[__oneBufferSize * __counter + __samplePosition + __channelIndex]
|
|
= __clusterPacket->getValue(__packetNo, __channelIndex, __sampleNo);
|
|
}
|
|
|
|
if (_singleADC->getIsTachoSignal()) {
|
|
_buffer_read[__oneBufferSize * __counter + __samplePosition + __tachoCannelIndex]
|
|
= __clusterPacket->getTachoValue(__packetNo, __sampleNo) ? 1.0 : 0.0;
|
|
}
|
|
}
|
|
}
|
|
delete __clusterPacket;
|
|
__counter++;
|
|
}
|
|
|
|
send_data();
|
|
}
|
|
|
|
void ADCCluster_device::_runClusterMode()
|
|
{
|
|
int __adcCount = _slavesADC->count() + 1; // '1' это мастер
|
|
int __aiCount = _masterADC->getChannelsCount();
|
|
//int __samplesCount = 333;
|
|
int __samplesCount = _masterADC->getSamplesCount();
|
|
int __clusterPacketSize = 45;
|
|
int __outputChannelsCount = (_masterADC->getChannelsCount() + _masterADC->getIsTachoSignal()) * (_slavesADC->count() + 1);
|
|
int __oneBufferSize = __clusterPacketSize * __samplesCount * __outputChannelsCount;
|
|
|
|
QQueue<clusterStack *> __snapshotQueue;
|
|
|
|
while (!_clusterQueue->isEmpty()) {
|
|
clusterStack * __stackTemp = _clusterQueue->dequeue();
|
|
if (__stackTemp!=nullptr) __snapshotQueue.enqueue(__stackTemp);
|
|
}
|
|
|
|
if (__snapshotQueue.count() == 0) return;
|
|
|
|
_buffer_read.resize(__oneBufferSize * __snapshotQueue.count());
|
|
|
|
for (int __i = 0; __i < __oneBufferSize * __snapshotQueue.count(); __i++) {
|
|
_buffer_read[__i] = 0;
|
|
}
|
|
|
|
int __counter = 0;
|
|
|
|
while (!__snapshotQueue.isEmpty()) {
|
|
clusterStack * __clusterPacket = __snapshotQueue.dequeue();
|
|
|
|
for (int __packetNo = 0; __packetNo < __clusterPacketSize; __packetNo++) {
|
|
|
|
for (int __sampleNo = 0; __sampleNo < __samplesCount; __sampleNo++) {
|
|
|
|
// номер пакета * количество отсчетов * количество каналов + количество каналов * номер отсчета
|
|
int __samplePosition = __outputChannelsCount * (__packetNo * __samplesCount + __sampleNo);
|
|
|
|
int __offset = 0;
|
|
|
|
for (int __adcNo = 0; __adcNo < __adcCount; __adcNo++) {
|
|
for (int __channelIndex = 0; __channelIndex < __aiCount; __channelIndex++) {
|
|
// количество отсчетов * номер канала + порядковый номер отсчета
|
|
if (__oneBufferSize * __counter + __samplePosition + __offset > _buffer_read.size()) {
|
|
qDebug() << __oneBufferSize * __counter + __samplePosition + __offset;
|
|
}
|
|
_buffer_read[__oneBufferSize * __counter + __samplePosition + __offset]
|
|
= __clusterPacket->getValue(__adcNo, __packetNo, __channelIndex, __sampleNo);
|
|
__offset++;
|
|
}
|
|
|
|
if (_masterADC->getIsTachoSignal()) {
|
|
_buffer_read[__oneBufferSize * __counter + __samplePosition + __offset]
|
|
= __clusterPacket->getTachoValue(__adcNo, __packetNo, __sampleNo) ? 1.0 : 0.0; // TODO tacho
|
|
__offset++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
delete __clusterPacket;
|
|
__counter++;
|
|
}
|
|
send_data();
|
|
}
|
|
|
|
void ADCCluster_device::_debugPrintADCParams(ADC *adc)
|
|
{
|
|
qDebug() << "Model id: " << adc->getModelID();
|
|
qDebug() << "Device sn: " << adc->getSN();
|
|
qDebug() << "DHCP mode: " << adc->getIsDHCPMode();
|
|
qDebug() << "MAC address: " << adc->getMacAddress().toHex('-');
|
|
qDebug() << "Default address: " << adc->getDefaultIP().toString();
|
|
qDebug() << "Default gate: " << adc->getDefaultGate().toString();
|
|
qDebug() << "Default mask: " << adc->getDefaultMask().toString();
|
|
qDebug() << "Static address: " << adc->getStaticIP().toString();
|
|
qDebug() << "Static gate: " << adc->getStaticGate().toString();
|
|
qDebug() << "Static mask: " << adc->getStaticMask().toString();
|
|
qDebug() << "Channels count: " << adc->getChannelsCount();
|
|
qDebug() << "Bit depth: " << (adc->getBitDeph() == ADC_ns::bitDepth::BIT16 ? "16" : "24");
|
|
|
|
for (int i=0; i< adc->getChannelsConfig()->count(); i++) {
|
|
qDebug() << "Channel " << i << " Factor: " << adc->getChannelsConfig()->at(i)->getFactor();
|
|
}
|
|
|
|
qDebug() << "Is tacho signal: " << adc->getIsTachoSignal();
|
|
qDebug() << "Is gen: " << adc->getIsGen();
|
|
qDebug() << "ADC freq: " << adc->getFreq();
|
|
}
|
|
|
|
void ADCCluster_device::_stateChanged(gtl::hw::device::ADCState state)
|
|
{
|
|
emit status_changed(state);
|
|
}
|
|
|
|
void ADCCluster_device::ai_iepe_changed()
|
|
{
|
|
if (_singleMode) {
|
|
for (int __i = 0; __i < _count_ai; __i++) {
|
|
if (ai(__i) == sender()) {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "single mode: iepe changed: channel: " << __i << "to:" << ai(__i)->is_iepe();
|
|
#endif
|
|
_singleADC->setChannelIEPE(__i, ai(__i)->is_iepe());
|
|
}
|
|
}
|
|
} else {
|
|
for (int __i = 0; __i < _count_ai; __i++) {
|
|
if (ai(__i) == sender()) {
|
|
int __adcIndex = __i / (_masterADC->getChannelsCount() + _masterADC->getIsTachoSignal());
|
|
int __channelIndex = __i % (_masterADC->getChannelsCount() + _masterADC->getIsTachoSignal());
|
|
bool __IPEPEnable = ai(__i)->is_iepe();
|
|
|
|
if (__adcIndex == 0) {
|
|
// master
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "cluster iepe changed: master";
|
|
qDebug() << "cluster iepe changed: ADC SN: " << _masterADC->getSN();
|
|
qDebug() << "cluster iepe changed: channel: " << __channelIndex;
|
|
qDebug() << "cluster iepe changed: " << __IPEPEnable;
|
|
#endif
|
|
_masterADC->setChannelIEPE(__channelIndex, __IPEPEnable);
|
|
} else {
|
|
// slave
|
|
__adcIndex = __adcIndex - 1;
|
|
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "cluster iepe changed: slave index: " << __adcIndex;
|
|
qDebug() << "cluster iepe changed: ADC SN: " << _slavesADC->at(__adcIndex)->getSN();
|
|
qDebug() << "cluster iepe changed: channel: " << __channelIndex;
|
|
qDebug() << "cluster iepe changed: " << __IPEPEnable;
|
|
#endif
|
|
_slavesADC->at(__adcIndex)->setChannelIEPE(__channelIndex, __IPEPEnable);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ADCCluster_device::ai_coupling_changed()
|
|
{
|
|
if (_singleMode) {
|
|
for (int __i = 0; __i < _count_ai; __i++) {
|
|
if (ai(__i) == sender()) {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "single mode: channel coupling changed: channel: " << __i << "to:" << ai(__i)->is_coupling();
|
|
#endif
|
|
if (ai(__i)->is_coupling()) {
|
|
_singleADC->setChannelMODE(__i, ADC_ns::channelMode::AC);
|
|
} else {
|
|
_singleADC->setChannelMODE(__i, ADC_ns::channelMode::ACDC);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for (int __i = 0; __i < _count_ai; __i++) {
|
|
if (ai(__i) == sender()) {
|
|
int __adcIndex = __i / (_masterADC->getChannelsCount() + _masterADC->getIsTachoSignal());
|
|
int __channelIndex = __i % (_masterADC->getChannelsCount() + _masterADC->getIsTachoSignal());
|
|
bool __couplingEnable = ai(__i)->is_coupling();
|
|
|
|
if (__adcIndex == 0) {
|
|
// master
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "cluster coupling changed: master";
|
|
qDebug() << "cluster coupling changed: ADC SN: " << _masterADC->getSN();
|
|
qDebug() << "cluster coupling changed: channel: " << __channelIndex;
|
|
qDebug() << "cluster coupling changed: " << __couplingEnable;
|
|
#endif
|
|
if (ai(__i)->is_coupling()) {
|
|
_masterADC->setChannelMODE(__channelIndex, ADC_ns::channelMode::AC);
|
|
} else {
|
|
_masterADC->setChannelMODE(__channelIndex, ADC_ns::channelMode::ACDC);
|
|
}
|
|
} else {
|
|
// slave
|
|
__adcIndex = __adcIndex - 1;
|
|
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "cluster coupling changed: slave index: " << __adcIndex;
|
|
qDebug() << "cluster coupling changed: ADC SN: " << _slavesADC->at(__adcIndex)->getSN();
|
|
qDebug() << "cluster coupling changed: channel: " << __channelIndex;
|
|
qDebug() << "cluster coupling changed: " << __couplingEnable;
|
|
#endif
|
|
if (ai(__i)->is_coupling()) {
|
|
_slavesADC->at(__adcIndex)->setChannelMODE(__channelIndex, ADC_ns::channelMode::AC);
|
|
} else {
|
|
_slavesADC->at(__adcIndex)->setChannelMODE(__channelIndex, ADC_ns::channelMode::ACDC);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
ADC *ADCCluster_device::_initSingleADC(uint16_t sn)
|
|
{
|
|
ADC * __singleADC = new ADC(sn);
|
|
|
|
QObject::connect(__singleADC, &ADC::ADC_connected, [=]() {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << QTime::currentTime().toString() << "single adc connected" << sn;
|
|
#endif
|
|
});
|
|
|
|
QObject::connect(__singleADC, &ADC::ADC_disconnected, [=]() {
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << QTime::currentTime().toString() << "single adc disconnected";
|
|
#endif
|
|
|
|
// hw api
|
|
_count_ai = 0;
|
|
set_ai();
|
|
_stateChanged(gtl::hw::device::ADCState::FAILED);
|
|
// hw api
|
|
});
|
|
|
|
QObject::connect(__singleADC, &ADC::ADC_started, [=](){
|
|
_state = ADCCluster_ns::clusterState::RUNNING;
|
|
_stateChanged(gtl::hw::device::ADCState::OK);
|
|
});
|
|
|
|
QObject::connect(__singleADC, &ADC::ADC_configReadingFinished, [=]() {
|
|
// TODO применить загруженные из XML настройки и как-то передать их в ADC
|
|
// и вызвать ещё раз load - т.к. мы только сейчас знаем какие настойки
|
|
|
|
#ifdef CLUSTER_DEBUG
|
|
_debugPrintADCParams(__singleADC);
|
|
#endif
|
|
|
|
if (__singleADC->getModelID() == 0) { // TODO критериии некорректной инициализации
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "init failed";
|
|
#endif
|
|
_stateChanged(gtl::hw::device::ADCState::INIT_FAILED);
|
|
return;
|
|
}
|
|
|
|
// hw api
|
|
_rate = __singleADC->getFreq();
|
|
_device->set_rate(__singleADC->getFreq());
|
|
_count_ai = __singleADC->getChannelsCount() + (int)__singleADC->getIsTachoSignal();
|
|
|
|
set_ai();
|
|
|
|
for (int __i = 0; __i < __singleADC->getChannelsCount(); __i++) {
|
|
ai(__i)->set_name("input [" + QString::number(__i) + "]");
|
|
}
|
|
|
|
if (__singleADC->getIsTachoSignal()) ai(__singleADC->getChannelsCount())->set_name("pulse");
|
|
// hw api
|
|
|
|
__singleADC->startADC(ADC_ns::SYNCMode::MASTER);
|
|
});
|
|
|
|
QObject::connect(__singleADC, &ADC::ADC_dataPacketReceived, [=](QByteArray packet) {
|
|
trans_ns::bytes2long __num;
|
|
__num.bytes.LL = packet[0];
|
|
__num.bytes.LH = packet[1];
|
|
__num.bytes.HL = packet[2];
|
|
__num.bytes.HH = packet[3];
|
|
|
|
int __packetIndex = __num.twinWord - _currentSingleStack->getFirstPacketIndex();
|
|
|
|
if (__num.twinWord - _currentSingleStack->getFirstPacketIndex() > 44) {
|
|
_singleQueue->enqueue(_currentSingleStack);
|
|
_currentSingleStack = new singleStack(__num.twinWord, __singleADC->getBitDeph(), __singleADC->getChannelsConfig(), __singleADC->getSamplesCount());
|
|
_currentSingleStack->insert(__packetIndex % 45, packet);
|
|
} else {
|
|
_currentSingleStack->insert(__packetIndex, packet);
|
|
}
|
|
|
|
if (__singleADC->getDataCounter() != __num.twinWord) {
|
|
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "propusk: " << __singleADC->getSN() << __singleADC->getDataCounter()
|
|
<< " : "
|
|
<< __num.twinWord
|
|
<< " packets lost = "
|
|
<< __num.twinWord - __singleADC->getDataCounter();
|
|
#endif
|
|
|
|
__singleADC->setDataCounter(__num.twinWord);
|
|
}
|
|
__singleADC->incDataCounter();
|
|
});
|
|
|
|
// hw api
|
|
_device->set_name("S_" + QString::number(sn));
|
|
_device->set_id(QString::number(sn));
|
|
_id = QString::number(sn);
|
|
_stateChanged(gtl::hw::device::ADCState::INIT_IN_PROGRESS);
|
|
// hw api
|
|
|
|
return __singleADC;
|
|
}
|
|
|
|
bool ADCCluster_device::start(QString id, qreal rate)
|
|
{
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "external cluster start: " << id;
|
|
#endif
|
|
|
|
bool __idIsDigit;
|
|
uint16_t __sn = id.toInt(&__idIsDigit);
|
|
|
|
if (__idIsDigit) {
|
|
// TODO вычитать настройки из XML и применить их
|
|
_state = ADCCluster_ns::clusterState::CONFIG;
|
|
_id = id;
|
|
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "cluster in simple mode";
|
|
#endif
|
|
_singleADC = _initSingleADC(__sn);
|
|
_singleADC->start();
|
|
_singleMode = true;
|
|
} else {
|
|
_state = ADCCluster_ns::clusterState::CONFIG;
|
|
|
|
_id = id;
|
|
|
|
#ifdef CLUSTER_DEBUG
|
|
qDebug() << "cluster in extended mode";
|
|
#endif
|
|
|
|
_device->set_name("ADCCluster [starting...]");
|
|
|
|
QList<int> * __SNs = new QList<int>();
|
|
|
|
foreach(QString __subString, id.split(',')) {
|
|
bool __snCheck;
|
|
int __ADCsn = __subString.toInt(&__snCheck);
|
|
if (__snCheck) __SNs->append(__ADCsn);
|
|
}
|
|
|
|
if (__SNs->count() == 0) {
|
|
_initError = true;
|
|
return false;
|
|
}
|
|
|
|
_masterADC = _initMasterADC(__SNs);
|
|
_masterADC->start();
|
|
|
|
_singleMode = false;
|
|
}
|
|
|
|
QThread::start(QThread::HighestPriority);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool ADCCluster_device::stop()
|
|
{
|
|
if (_initError) return true;
|
|
|
|
if (_state != ADCCluster_ns::clusterState::IDLE) {
|
|
if (_singleMode) {
|
|
_state = ADCCluster_ns::clusterState::IDLE;
|
|
msleep(110);
|
|
_singleADC->stop();
|
|
delete(_singleADC);
|
|
} else {
|
|
_state = ADCCluster_ns::clusterState::IDLE;
|
|
|
|
_isMasterAllreadyInited = false;
|
|
|
|
msleep(110);
|
|
_masterADC->stop();
|
|
delete(_masterADC);
|
|
|
|
while (_slavesADC->count() > 0) {
|
|
ADC * __slave =_slavesADC->takeAt(0);
|
|
__slave->stop();
|
|
msleep(110);
|
|
delete(__slave);
|
|
}
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void ADCCluster_device::run()
|
|
{
|
|
while (_state != ADCCluster_ns::clusterState::IDLE)
|
|
{
|
|
if (_state == ADCCluster_ns::clusterState::RUNNING) {
|
|
if (_singleMode) {
|
|
_runSingleMode();
|
|
} else {
|
|
_runClusterMode();
|
|
}
|
|
}
|
|
msleep(150);
|
|
}
|
|
}
|
|
|
|
void ADCCluster_device::send_data()
|
|
{
|
|
set_ai_data(&_buffer_read[0], (int)_buffer_read.size());
|
|
|
|
emit received_data();
|
|
}
|