RISC-V/V203/usb/scope/software/datasource.cpp
2024-10-25 15:20:26 +02:00

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));
}