#include #include #include #include #include #include #include #include #include #include "wsclient.h" using json = nlohmann::json; using namespace std; using namespace seasocks; static const uint8_t VoltageRangeTable [] = { S100mV, S200mV, S500mV, S1V, S2V, S5V, S10V, S20V, S50V, }; static uint8_t find_index (uint8_t n) { unsigned m = sizeof (VoltageRangeTable); for (unsigned i=0u; i & a, const vector & b) { json msg; msg["a"] = a; msg["b"] = b; return msg.dump(); } bool WsClient::start() { cout << "Client Start\n"; const char * name = "/dev/serial/by-id/usb-Kizarm_Labs._USB_Osciloscope_00001-if00"; running = false; fd = ::open (name, O_RDWR); if (fd < 0) return running; epoll_event wakeUsart = {EPOLLIN, {this}}; epoll_ctl (pollfd, EPOLL_CTL_ADD, fd, &wakeUsart); struct termios LineFlags; int attr = tcgetattr (fd, &LineFlags); if (attr) { printf ("Nelze zjistit parametry portu %s\r\n", name); ::close (fd); return running; } // nastaveni komunikacnich parametru do struct termios LineFlags.c_iflag = IGNPAR /* | IXON | IXOFF*/; // ignoruj chyby parity LineFlags.c_oflag = 0; // normalni nastaveni LineFlags.c_cflag = CS8 | CREAD | CLOCAL; // 8-bit, povol prijem LineFlags.c_lflag = 0; // Raw input bez echa LineFlags.c_cc [VMIN] = 1; // minimalni pocet znaku pro cteni LineFlags.c_cc [VTIME] = 1; // read timeout 0.1 s tcsetattr (fd, TCSANOW, &LineFlags); fcntl (fd, F_SETFL, 0); int flag = TIOCM_DTR; ioctl(fd, TIOCMBIS, & flag); printf ("Port %s opened (%d)\r\n", name, fd); usleep (1000); const int r = ::write (fd, "?\r\n", 3); (void) r; running = true; return running; } void WsClient::stop() { cout << "Client Stop\n"; epoll_ctl (pollfd, EPOLL_CTL_DEL, fd, nullptr); int flag = TIOCM_DTR; ioctl(fd, TIOCMBIC, & flag); ::close (fd); running = false; } void WsClient::receive() { if (!running) return; const int recmax = 64; char tmpbuf [recmax]; ssize_t r = ::read (fd, tmpbuf, recmax); bool end = false; for (int n=0; n= DATASIZE) { packet_cnt = 0; printf ("Buffer overflow\n"); } break; } } } void WsClient::parse_header() { if (packet_cnt != 4) return; packet_buf [4] = '\0'; const long hdr = strtoul (packet_buf, nullptr, 16); header.common = hdr; /* //qDebug ("header:%04X", hdr); if (header.bits.trig_flg) { emit PaketTriggered (); } */ } static uint8_t from_hex (const char * ptr) { uint8_t result = 0u; for (unsigned n=0; n<2u; n++) { result *= 0x10; const char c = ptr [n]; const uint8_t v = c > '9' ? c - 'A' + 10 : c - '0'; result += v; } return result; } void WsClient::parse_reply(const char * data, const int len) { printf("(%d):%s\n", len, data); TrigerSettings ts; ChannelVoltage cv; AllSettings as (ts, 0, cv); const int bl = len >> 1; int k = 0; for (int n=0; nsend(s); } void WsClient::parse_packet() { if (state == StateReply) { packet_buf[packet_cnt] = '\0'; parse_reply(packet_buf, packet_cnt); return; } vector ChA, ChB; if (state != StateData) return; int k=0; for (int n=0; nsend(outs); /* if (trigerSettings.mode == TRIGER_MODE_SINGLE) { if (catching) { catching = false; emit Channels_received (ChA, ChB); } } else { emit Channels_received (ChA, ChB); } */ } else { printf ("packet error: ChA=%d, ChB=%d, size=%d\n", Al, Bl, header.bits.pack_len); } } /*******************************************************************/ void WsClient::send(const char * data) { // cout << "data is \"" << data << "\"\n"; // prijata data json received = json::parse (string (data)); int value = 0; if (!received["value"].is_null()) { received["value"].get_to (value); } string type; if (!received["type"].is_null()) { received["type"].get_to (type); if (type == "trg_src") { SendTrigerChan(value); } else if (type == "trg_mod") { SendTrigerMode(value); } else if (type == "trg_edg") { SendTrigerEdge(value); } else if (type == "trg_val") { trigerSettings.value = value; SettingChanged(0); } else if (type == "trg_ofs") { trigerSettings.offset = value; SettingChanged(1); } else if (type == "tim_bas") { SendBaseRange(value); } else if (type == "cha_set") { SendVoltage(0, VoltageRangeTable[value]); } else if (type == "chb_set") { SendVoltage(1, VoltageRangeTable[value]); } else if (type == "start") { Start (); } } // cout << "type=" << type << ", value=" << value << endl; } void WsClient::SendVoltage(int ch, int n) { const int k = (unsigned) n >= sizeof (VoltageRangeTable) ? (sizeof (VoltageRangeTable) - 1u) : n; uint8_t v = VoltageRangeTable [k]; RcvdHeader hdr; hdr.common = 0u; hdr.bits.destinat = ch == 0 ? DEST_CHA : DEST_CHB; hdr.bits.cmd_value = v; const unsigned len = 64; char buffer [len]; int r = snprintf(buffer, len, "$%04X\r\n", (int) hdr.common); buffer [r] = '\0'; write (buffer, r); } void WsClient::SendTrigerChan(int n) { trigerSettings.channel = static_cast (n); send_trig_mode(); } void WsClient::SendTrigerMode(int n) { trigerSettings.mode = static_cast (n); send_trig_mode(); } void WsClient::SendTrigerEdge(int n) { trigerSettings.rising = n ? true : false; send_trig_mode(); } void WsClient::SettingChanged(int n) { const MOVE_ITEMS items = static_cast(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'; write (buffer, r); } void WsClient::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'; write (buffer, r); } void WsClient::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'; write (buffer, r); } int WsClient::write(const char * data, const int len) { if (!running) return 0; string out (data, len); cout << out; int r = ::write (fd, data, len); (void) r; //ws->send(out); return len; } void WsClient::Start() { }