182 lines
4.9 KiB
C++
182 lines
4.9 KiB
C++
#include "datasource.h"
|
|
#include "helpers.h"
|
|
|
|
static constexpr unsigned DATASIZE = 0x2000;
|
|
|
|
DataSource::DataSource(QObject * p) : QObject (p),
|
|
usart (QString("/dev/serial/by-id/usb-Kizarm_Labs._USB_Osciloscope_00001-if00")),
|
|
trigerSettings () {
|
|
in_buffer = new char [DATASIZE];
|
|
packet_buf = new char [DATASIZE];
|
|
packet_cnt = 0;
|
|
state = StateIdle;
|
|
catching = true;
|
|
|
|
connect (&usart, SIGNAL (readyRead()), this, SLOT (read_data()));
|
|
usart.open (QIODevice::ReadWrite);
|
|
}
|
|
DataSource::~DataSource() {
|
|
usart.close();
|
|
delete [] in_buffer;
|
|
delete [] packet_buf;
|
|
}
|
|
void DataSource::Start() {
|
|
catching = true;
|
|
}
|
|
|
|
void DataSource::read_data() {
|
|
const long numRead = usart.read(in_buffer, DATASIZE);
|
|
if (numRead == 0) return;
|
|
// qDebug ("readen = %ld", numRead);
|
|
parse_input (in_buffer, numRead);
|
|
}
|
|
void DataSource::parse_input(const char * data, const long len) {
|
|
for (long i=0; i<len; i++) {
|
|
const char c = data [i];
|
|
switch (c) {
|
|
case '$':
|
|
state = StateHeader;
|
|
packet_cnt = 0;
|
|
break;
|
|
case '#':
|
|
parse_header();
|
|
state = StateData;
|
|
packet_cnt = 0;
|
|
break;
|
|
case '\r':
|
|
case '\n':
|
|
parse_packet();
|
|
state = StateIdle;
|
|
packet_cnt = 0;
|
|
break;
|
|
default:
|
|
packet_buf [packet_cnt] = c;
|
|
packet_cnt += 1;
|
|
if (packet_cnt >= (int) DATASIZE) {
|
|
packet_cnt = 0;
|
|
qDebug ("Buffer overflow");
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
void DataSource::parse_header() {
|
|
if (packet_cnt != 4) return;
|
|
packet_buf [4] = '\0';
|
|
QString h (packet_buf);
|
|
bool ok = false;
|
|
const unsigned hdr = h.toUInt(&ok, 16);
|
|
if (!ok) return;
|
|
header.common = hdr;
|
|
//qDebug ("header:%04X", hdr);
|
|
if (header.bits.trig_flg) {
|
|
emit PaketTriggered ();
|
|
}
|
|
}
|
|
void DataSource::parse_packet() {
|
|
QVector<int> ChA, ChB;
|
|
if (state != StateData) return;
|
|
bool ok = false;
|
|
int k=0;
|
|
for (int n=0; n<packet_cnt; n+=3) {
|
|
char buf [4];
|
|
memcpy (buf, packet_buf+n, 3);
|
|
buf[3] = '\0';
|
|
QString s (buf);
|
|
const unsigned sample = s.toUInt(&ok, 16);
|
|
if (ok) {
|
|
if (k & 1) {
|
|
ChB.push_back (sample);
|
|
} else {
|
|
ChA.push_back (sample);
|
|
}
|
|
}
|
|
|
|
k += 1;
|
|
}
|
|
bool sok = true;
|
|
if (ChA.size() != (int) header.bits.pack_len) sok = false;
|
|
if (ChB.size() != (int) header.bits.pack_len) sok = false;
|
|
const size_t al = ChA.size(), bl = ChB.size();
|
|
if ((al != 1ul) and (al != 1024ul)) { qDebug ("A packet len = %zd", al); }
|
|
if ((bl != 1ul) and (bl != 1024ul)) { qDebug ("B packet len = %zd", bl); }
|
|
if (sok) {
|
|
if ((al == 1ul) or (bl == 1ul)) { // v kontinuálním módu odešli vždy
|
|
emit Channels_received (ChA, ChB);
|
|
} else if (trigerSettings.mode == TRIGER_MODE_SINGLE) {
|
|
if (catching) {
|
|
catching = false;
|
|
emit Channels_received (ChA, ChB);
|
|
}
|
|
} else {
|
|
emit Channels_received (ChA, ChB);
|
|
}
|
|
} else {
|
|
qDebug ("packet error: ChA=%d, ChB=%d, size=%d", ChA.size(), ChB.size(), header.bits.pack_len);
|
|
}
|
|
}
|
|
void DataSource::SendTrigerMode(int n) {
|
|
trigerSettings.mode = static_cast<TRIGER_MODE> (n);
|
|
send_trig_mode();
|
|
}
|
|
void DataSource::SendTrigerEdge(int n) {
|
|
trigerSettings.rising = n ? true : false;
|
|
send_trig_mode();
|
|
}
|
|
void DataSource::SendTrigerChan(int n) {
|
|
trigerSettings.channel = static_cast<ADC_CHANNELS> (n);
|
|
send_trig_mode();
|
|
}
|
|
|
|
void DataSource::send_trig_mode () {
|
|
RcvdHeader hdr;
|
|
hdr.common = 0u;
|
|
hdr.bits.destinat = DEST_TRIG;
|
|
hdr.bits.cmd_type = TRIGGER_CMD_MODE;
|
|
TriggerModeUnion tmu;
|
|
tmu.common = 0u;
|
|
tmu.bits.mode = trigerSettings.mode;
|
|
tmu.bits.channel = trigerSettings.channel;
|
|
tmu.bits.rissing = trigerSettings.rising ? 1u : 0u;
|
|
hdr.bits.cmd_value = tmu.common;
|
|
|
|
const unsigned len = 64;
|
|
char buffer [len];
|
|
int r = snprintf(buffer, len, "$%04X\r\n", (int) hdr.common);
|
|
buffer [r] = '\0';
|
|
usart.write (buffer, r);
|
|
qDebug ("%d:%s", r, strip_eol(buffer));
|
|
}
|
|
void DataSource::SettingChanged(int n) {
|
|
const MOVE_ITEMS items = static_cast<MOVE_ITEMS>(n);
|
|
RcvdHeader hdr;
|
|
hdr.common = 0u;
|
|
hdr.bits.destinat = DEST_TRIG;
|
|
switch (items) {
|
|
case MOVE_VALUE: hdr.bits.cmd_type = TRIGGER_CMD_VALUE; hdr.bits.cmd_value = trigerSettings.value; break;
|
|
case MOVE_OFSET: hdr.bits.cmd_type = TRIGGER_CMD_OFSET; hdr.bits.cmd_value = trigerSettings.offset; break;
|
|
default : break;
|
|
}
|
|
|
|
const unsigned len = 64;
|
|
char buffer [len];
|
|
int r = snprintf(buffer, len, "$%04X\r\n", (int) hdr.common);
|
|
buffer [r] = '\0';
|
|
usart.write (buffer, r);
|
|
// qDebug ("%d::%d:%s", n, r, strip_eol(buffer));
|
|
}
|
|
void DataSource::SendBaseRange (int n) {
|
|
RcvdHeader hdr;
|
|
hdr.common = 0u;
|
|
hdr.bits.destinat = DEST_BASE;
|
|
hdr.bits.cmd_value = n;
|
|
const unsigned len = 64;
|
|
char buffer [len];
|
|
int r = snprintf(buffer, len, "$%04X\r\n", (int) hdr.common);
|
|
buffer [r] = '\0';
|
|
usart.write (buffer, r);
|
|
qDebug ("%d:%s", r, strip_eol(buffer));
|
|
}
|
|
|
|
|
|
|