425 lines
12 KiB
C++
425 lines
12 KiB
C++
|
#include "adc.h"
|
||
|
|
||
|
ADC::ADC(uint16_t sn, QObject *parent)
|
||
|
: QObject{parent},
|
||
|
_state(ADC_ns::ADCState::DISCONNECTED),
|
||
|
_stpClient(new stpClient(QHostAddress())),
|
||
|
_adcqueue(new ADCQueue()),
|
||
|
_idServer(new idServer(sn)),
|
||
|
_discoverTimer(new QTimer()),
|
||
|
_dataCounter(0),
|
||
|
_modelId(0),
|
||
|
_sn(sn),
|
||
|
_channelsCount(0),
|
||
|
_isTachoSignal(false),
|
||
|
_isGen(false),
|
||
|
_freq(0),
|
||
|
_bitDepth(ADC_ns::bitDepth::BIT16),
|
||
|
_dhcp_mode(true),
|
||
|
_mac_address(QByteArray()),
|
||
|
_default_ip(QHostAddress()),
|
||
|
_default_gate(QHostAddress()),
|
||
|
_default_mask(QHostAddress()),
|
||
|
_static_ip(QHostAddress()),
|
||
|
_static_gate(QHostAddress()),
|
||
|
_static_mask(QHostAddress()),
|
||
|
_channels(new QList<ADCChannel *>())
|
||
|
{
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "adc created: " << sn;
|
||
|
#endif
|
||
|
|
||
|
_discoverTimer->setInterval(DISCOVER_PERIOD);
|
||
|
|
||
|
QObject::connect(_stpClient, &stpClient::STP_connected, [=] {
|
||
|
_dataCounter = 0;
|
||
|
_state = ADC_ns::ADCState::CONFIGURATION_READING;
|
||
|
_packReadADCParams();
|
||
|
|
||
|
emit ADC_connected();
|
||
|
});
|
||
|
|
||
|
QObject::connect(_stpClient, &stpClient::STP_disconnected, [=] {
|
||
|
if (_state != ADC_ns::ADCState::DISCONNECTED) {
|
||
|
_state = ADC_ns::ADCState::DISCONNECTED;
|
||
|
_adcqueue->stop();
|
||
|
|
||
|
emit ADC_disconnected();
|
||
|
}
|
||
|
});
|
||
|
|
||
|
|
||
|
QObject::connect(_stpClient, &stpClient::STP_newDataPacketReceived, [=](QByteArray data) {
|
||
|
if (_adcqueue->receiveData(data)) return;
|
||
|
emit ADC_dataPacketReceived(data);
|
||
|
});
|
||
|
|
||
|
QObject::connect(_discoverTimer, &QTimer::timeout, [=]{
|
||
|
_idServer->sendIdRequest();
|
||
|
});
|
||
|
|
||
|
QObject::connect(_idServer, &idServer::newIdMessage, [=](uint16_t model, uint16_t sn, QHostAddress address){
|
||
|
if (_state == ADC_ns::ADCState::DISCOVER) {
|
||
|
if (sn == _sn) {
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "Found ADC: " << sn << " on IP: " << address.toString();
|
||
|
#endif
|
||
|
_state = ADC_ns::ADCState::CONNECTING;
|
||
|
|
||
|
_discoverTimer->stop();
|
||
|
_stpClient->setAddress(address);
|
||
|
_stpClient->connectToHost();
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
QObject::connect(_adcqueue, &ADCQueue::sendData, [=](QByteArray data) {
|
||
|
_stpClient->sendData(&data);
|
||
|
});
|
||
|
|
||
|
QObject::connect(_adcqueue, &ADCQueue::queueIsEmpty, [=] {
|
||
|
if (_state == ADC_ns::ADCState::CONFIGURATION_READING) {
|
||
|
_state = ADC_ns::ADCState::WAITING_COMMAND;
|
||
|
|
||
|
emit ADC_configReadingFinished();
|
||
|
} else if (_state == ADC_ns::ADCState::ADC_START_SEND) {
|
||
|
_state = ADC_ns::ADCState::RUNNING;
|
||
|
|
||
|
emit ADC_started();
|
||
|
} else if (_state == ADC_ns::ADCState::ADC_STOP_SEND) {
|
||
|
_state = ADC_ns::ADCState::WAITING_COMMAND;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
QObject::connect(_adcqueue, &ADCQueue::registerReadFinished, [=](ADCQueue_ns::cmdItem cmd) {
|
||
|
_parseRegisterData(cmd);
|
||
|
});
|
||
|
|
||
|
QObject::connect(_adcqueue, &ADCQueue::registerWriteFinished, [=](ADCQueue_ns::cmdItem cmd) {
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "ADC " << _sn << "Register writen: " << cmd.regNumber;
|
||
|
#endif
|
||
|
});
|
||
|
|
||
|
QObject::connect(_adcqueue, &ADCQueue::registerReadError, [=](ADCQueue_ns::cmdItem cmd) {
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "ADC " << _sn << "Register read error: " << cmd.regNumber;
|
||
|
#endif
|
||
|
});
|
||
|
|
||
|
QObject::connect(_adcqueue, &ADCQueue::registerWriteError, [=](ADCQueue_ns::cmdItem cmd) {
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "ADC " << _sn << "Register write error: " << cmd.regNumber;
|
||
|
#endif
|
||
|
});
|
||
|
|
||
|
QObject::connect(_adcqueue, &ADCQueue::queueTimeout, [=] {
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "ADC " << _sn << "Queue timeout";
|
||
|
#endif
|
||
|
});
|
||
|
|
||
|
QObject::connect(_adcqueue, &ADCQueue::queueError, [=] {
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "ADC " << _sn << "Queue error";
|
||
|
#endif
|
||
|
});
|
||
|
}
|
||
|
|
||
|
ADC::~ADC()
|
||
|
{
|
||
|
delete _adcqueue;
|
||
|
delete _stpClient;
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "ADC destructor" << _sn;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void ADC::start()
|
||
|
{
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "ADC class start" << _sn;
|
||
|
#endif
|
||
|
|
||
|
_idServer->sendIdRequest();
|
||
|
_discoverTimer->start();
|
||
|
_state = ADC_ns::ADCState::DISCOVER;
|
||
|
}
|
||
|
|
||
|
void ADC::stop()
|
||
|
{
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "ADC class stop" << _sn;
|
||
|
#endif
|
||
|
|
||
|
_state = ADC_ns::ADCState::DISCONNECTED;
|
||
|
_adcqueue->stop();
|
||
|
_discoverTimer->stop();
|
||
|
_stpClient->disconnectFromHost();
|
||
|
}
|
||
|
|
||
|
void ADC::startADC(ADC_ns::SYNCMode mode)
|
||
|
{
|
||
|
_state = ADC_ns::ADCState::ADC_START_SEND;
|
||
|
_packStartADC(mode);
|
||
|
}
|
||
|
|
||
|
void ADC::stopADC()
|
||
|
{
|
||
|
_state = ADC_ns::ADCState::ADC_STOP_SEND;
|
||
|
_packStopADC();
|
||
|
}
|
||
|
|
||
|
void ADC::_packReadADCParams()
|
||
|
{
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, MODEL_ID);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, NETWORK_MODE);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, MAC_ADDRESS);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, DEFAULT_IP);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, DEFAULT_GATE);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, DEFAULT_MASK);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, STATIC_IP);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, STATIC_GATE);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, STATIC_MASK);
|
||
|
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, CHANNELS_COUNT);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, IS_TACHO_SIGNAL);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, IS_GEN);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, ADC_FREQ);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, BIT_DEPTH);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_READ, CALIBRATION_FACTOR);
|
||
|
}
|
||
|
|
||
|
void ADC::_parseRegisterData(ADCQueue_ns::cmdItem cmd)
|
||
|
{
|
||
|
QByteArray * __regData = ((QByteArray *)cmd.regData);
|
||
|
|
||
|
switch (cmd.regNumber) {
|
||
|
|
||
|
case MODEL_ID:
|
||
|
trans_ns::bytes2word __modelId;
|
||
|
__modelId.bytes.L = (*__regData)[0];
|
||
|
__modelId.bytes.H = (*__regData)[1];
|
||
|
_modelId = __modelId.word;
|
||
|
break;
|
||
|
|
||
|
case DEVICE_SN:
|
||
|
trans_ns::bytes2word __sn;
|
||
|
__sn.bytes.L = (*__regData)[0];
|
||
|
__sn.bytes.H = (*__regData)[1];
|
||
|
_sn = __sn.word;
|
||
|
break;
|
||
|
|
||
|
case CHANNELS_COUNT:
|
||
|
trans_ns::bytes2word __channelsCount;
|
||
|
__channelsCount.bytes.L = (*__regData)[0];
|
||
|
__channelsCount.bytes.H = (*__regData)[1];
|
||
|
_channelsCount = __channelsCount.word;
|
||
|
break;
|
||
|
|
||
|
case IS_TACHO_SIGNAL:
|
||
|
trans_ns::bytes2word __isTachoSignal;
|
||
|
__isTachoSignal.bytes.L = (*__regData)[0];
|
||
|
__isTachoSignal.bytes.H = (*__regData)[1];
|
||
|
_isTachoSignal = (__isTachoSignal.word == 1);
|
||
|
break;
|
||
|
|
||
|
case IS_GEN:
|
||
|
trans_ns::bytes2word __isGen;
|
||
|
__isGen.bytes.L = (*__regData)[0];
|
||
|
__isGen.bytes.H = (*__regData)[1];
|
||
|
_isGen = (__isGen.word == 1);
|
||
|
break;
|
||
|
|
||
|
|
||
|
case ADC_FREQ:
|
||
|
trans_ns::bytes2long __freq;
|
||
|
__freq.bytes.LL = (*__regData)[0];
|
||
|
__freq.bytes.LH = (*__regData)[1];
|
||
|
__freq.bytes.HL = (*__regData)[2];
|
||
|
__freq.bytes.HH = (*__regData)[3];
|
||
|
_freq = __freq.twinWord;
|
||
|
break;
|
||
|
|
||
|
case CALIBRATION_FACTOR:
|
||
|
_channels->clear();
|
||
|
|
||
|
if (__regData->size() < _channelsCount * 8) {
|
||
|
#ifdef ADC_DEBUG
|
||
|
qDebug() << "ADC " << _sn << "scale factor error";
|
||
|
#endif
|
||
|
|
||
|
for (int i=0; i<_channelsCount; i++) {
|
||
|
ADCChannel * __channel = new ADCChannel();
|
||
|
__channel->setFactor(1);
|
||
|
_channels->append(__channel);
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
for (int i=0; i<_channelsCount; i++) {
|
||
|
trans_ns::bytes2float __factor;
|
||
|
__factor.bytes.LL = (*__regData)[i*8];
|
||
|
__factor.bytes.LH = (*__regData)[i*8 + 1];
|
||
|
__factor.bytes.HL = (*__regData)[i*8 + 2];
|
||
|
__factor.bytes.HH = (*__regData)[i*8 + 3];
|
||
|
|
||
|
ADCChannel * __channel = new ADCChannel();
|
||
|
|
||
|
__channel->setFactor(__factor.floatValue);
|
||
|
|
||
|
_channels->append(__channel);
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case BIT_DEPTH:
|
||
|
trans_ns::bytes2word __bitDepth;
|
||
|
__bitDepth.bytes.L = (*__regData)[0];
|
||
|
__bitDepth.bytes.H = (*__regData)[1];
|
||
|
|
||
|
if (__bitDepth.word == 1 ) {
|
||
|
_bitDepth = ADC_ns::bitDepth::BIT24;
|
||
|
} else {
|
||
|
_bitDepth = ADC_ns::bitDepth::BIT16;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
|
||
|
case NETWORK_MODE:
|
||
|
trans_ns::bytes2word __networkMode;
|
||
|
__networkMode.bytes.L = (*__regData)[0];
|
||
|
__networkMode.bytes.H = (*__regData)[1];
|
||
|
_dhcp_mode = __networkMode.word == 0;
|
||
|
break;
|
||
|
|
||
|
case MAC_ADDRESS:
|
||
|
_mac_address = QByteArray(*__regData);
|
||
|
break;
|
||
|
|
||
|
case DEFAULT_IP:
|
||
|
trans_ns::bytes2long __defaultIP;
|
||
|
__defaultIP.bytes.LL = (*__regData)[3];
|
||
|
__defaultIP.bytes.LH = (*__regData)[2];
|
||
|
__defaultIP.bytes.HL = (*__regData)[1];
|
||
|
__defaultIP.bytes.HH = (*__regData)[0];
|
||
|
_default_ip = QHostAddress(__defaultIP.twinWord);
|
||
|
break;
|
||
|
|
||
|
case DEFAULT_GATE:
|
||
|
trans_ns::bytes2long __defaultGate;
|
||
|
__defaultGate.bytes.LL = (*__regData)[3];
|
||
|
__defaultGate.bytes.LH = (*__regData)[2];
|
||
|
__defaultGate.bytes.HL = (*__regData)[1];
|
||
|
__defaultGate.bytes.HH = (*__regData)[0];
|
||
|
_default_gate = QHostAddress(__defaultGate.twinWord);
|
||
|
break;
|
||
|
|
||
|
case DEFAULT_MASK:
|
||
|
trans_ns::bytes2long __defaultMask;
|
||
|
__defaultMask.bytes.LL = (*__regData)[3];
|
||
|
__defaultMask.bytes.LH = (*__regData)[2];
|
||
|
__defaultMask.bytes.HL = (*__regData)[1];
|
||
|
__defaultMask.bytes.HH = (*__regData)[0];
|
||
|
_default_mask = QHostAddress(__defaultMask.twinWord);
|
||
|
break;
|
||
|
|
||
|
case STATIC_IP:
|
||
|
trans_ns::bytes2long __staticIP;
|
||
|
__staticIP.bytes.LL = (*__regData)[3];
|
||
|
__staticIP.bytes.LH = (*__regData)[2];
|
||
|
__staticIP.bytes.HL = (*__regData)[1];
|
||
|
__staticIP.bytes.HH = (*__regData)[0];
|
||
|
_static_ip = QHostAddress(__staticIP.twinWord);
|
||
|
break;
|
||
|
|
||
|
case STATIC_GATE:
|
||
|
trans_ns::bytes2long __staticGate;
|
||
|
__staticGate.bytes.LL = (*__regData)[3];
|
||
|
__staticGate.bytes.LH = (*__regData)[2];
|
||
|
__staticGate.bytes.HL = (*__regData)[1];
|
||
|
__staticGate.bytes.HH = (*__regData)[0];
|
||
|
_static_gate = QHostAddress(__staticGate.twinWord);
|
||
|
break;
|
||
|
|
||
|
case STATIC_MASK:
|
||
|
trans_ns::bytes2long __staticMask;
|
||
|
__staticMask.bytes.LL = (*__regData)[3];
|
||
|
__staticMask.bytes.LH = (*__regData)[2];
|
||
|
__staticMask.bytes.HL = (*__regData)[1];
|
||
|
__staticMask.bytes.HH = (*__regData)[0];
|
||
|
_static_mask = QHostAddress(__staticMask.twinWord);
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ADC::_packStartADC(ADC_ns::SYNCMode mode)
|
||
|
{
|
||
|
QByteArray * __cmd2 = new QByteArray();
|
||
|
__cmd2->resize(1);
|
||
|
(*__cmd2)[0] = mode;
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_WRITE, SYNC_MODE, __cmd2);
|
||
|
|
||
|
QByteArray * __cmd3 = new QByteArray();
|
||
|
__cmd3->resize(1);
|
||
|
(*__cmd3)[0] = 0x01;
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_WRITE, ADC_START, __cmd3);
|
||
|
|
||
|
}
|
||
|
|
||
|
void ADC::_packStopADC()
|
||
|
{
|
||
|
QByteArray * __cmd = new QByteArray();
|
||
|
__cmd->resize(1);
|
||
|
(*__cmd)[0] = 0x00;
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_WRITE, ADC_START, __cmd);
|
||
|
}
|
||
|
|
||
|
void ADC::setChannelIEPE(int channel, bool value)
|
||
|
{
|
||
|
QByteArray * __cmd = new QByteArray();
|
||
|
__cmd->resize(1);
|
||
|
(*__cmd)[0] = value;
|
||
|
_channels->at(channel)->setIEPE(value);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_WRITE, CH_IEPE_OFFSET + channel, __cmd);
|
||
|
|
||
|
if (!value) {
|
||
|
setChannelMODE(channel, _channels->at(channel)->getMode());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void ADC::setChannelMODE(int channel, ADC_ns::channelMode mode)
|
||
|
{
|
||
|
QByteArray * __cmd = new QByteArray();
|
||
|
__cmd->resize(1);
|
||
|
(*__cmd)[0] = mode;
|
||
|
_channels->at(channel)->setMode(mode);
|
||
|
_adcqueue->appendCmd(stpProtocol_ns::stpCommand::REG_WRITE, CH_ACDC_OFFSET + channel, __cmd);
|
||
|
}
|
||
|
|
||
|
int ADC::getSamplesCount()
|
||
|
{
|
||
|
int __result;
|
||
|
|
||
|
switch (_modelId) {
|
||
|
case 1: // 2 CH 24B + GEN
|
||
|
__result = 222;
|
||
|
break;
|
||
|
case 2: // 2 CH 16B + TACHO
|
||
|
__result = 333;
|
||
|
break;
|
||
|
case 4: // 4 CH 16B + TACHO
|
||
|
__result = 167;
|
||
|
break;
|
||
|
|
||
|
|
||
|
default:
|
||
|
__result = 0;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return __result;
|
||
|
}
|
||
|
|