From 143f18efb386f19bc25db5f072359da727541151 Mon Sep 17 00:00:00 2001 From: Teuniz Date: Wed, 28 Dec 2016 11:48:47 +0100 Subject: [PATCH] Work in progress. --- dsremote.pro | 4 + global.h | 8 +- interface.cpp | 21 +- mainwindow.h | 5 +- save_data.cpp | 59 +- settings_dialog.h | 4 +- wave_dialog.cpp | 146 +++++ wave_dialog.h | 83 +++ wave_view.cpp | 1573 +++++++++++++++++++++++++++++++++++++++++++++ wave_view.h | 131 ++++ 10 files changed, 2010 insertions(+), 24 deletions(-) create mode 100644 wave_dialog.cpp create mode 100644 wave_dialog.h create mode 100644 wave_view.cpp create mode 100644 wave_view.h diff --git a/dsremote.pro b/dsremote.pro index ba74dd3..7ff2ad3 100644 --- a/dsremote.pro +++ b/dsremote.pro @@ -58,6 +58,8 @@ HEADERS += read_settings_thread.h HEADERS += save_data_thread.h HEADERS += decode_dialog.h HEADERS += tdial.h +HEADERS += wave_dialog.h +HEADERS += wave_view.h HEADERS += third_party/kiss_fft/kiss_fft.h HEADERS += third_party/kiss_fft/_kiss_fft_guts.h @@ -85,6 +87,8 @@ SOURCES += read_settings_thread.cpp SOURCES += save_data_thread.cpp SOURCES += decode_dialog.cpp SOURCES += tdial.cpp +SOURCES += wave_dialog.cpp +SOURCES += wave_view.cpp SOURCES += third_party/kiss_fft/kiss_fft.c SOURCES += third_party/kiss_fft/kiss_fftr.c diff --git a/global.h b/global.h index 367efaf..882e060 100644 --- a/global.h +++ b/global.h @@ -35,7 +35,7 @@ #define PROGRAM_NAME "DSRemote" -#define PROGRAM_VERSION "0.33_1612261016" +#define PROGRAM_VERSION "0.33_1612281147" #define MAX_PATHLEN 4096 @@ -92,7 +92,7 @@ #define DECODE_MODE_SPI 2 #define DECODE_MODE_I2C 3 -#define DECODE_MAX_CHARS 256 +#define DECODE_MAX_CHARS 512 @@ -173,7 +173,7 @@ struct device_settings int acquiretype; // 0=normal, 1=average, 2=peak, 3=highres int acquireaverages; // 2, 4, 8, 16, 32, 64, etc. to 8192 int acquirememdepth; // Number of waveform points that the oscilloscope can - //store in a single trigger sample. 0=AUTO + // store in a single trigger sample. 0=AUTO int countersrc; // 0=off, 1=ch1, 2=ch2, 3=ch3, 4=ch4 double counterfreq; // Value of frequency counter @@ -273,6 +273,8 @@ struct device_settings int current_screen_sf; int show_fps; + + int wave_mem_view_sample_start; }; diff --git a/interface.cpp b/interface.cpp index ff48d83..9eaff5e 100644 --- a/interface.cpp +++ b/interface.cpp @@ -1486,15 +1486,28 @@ void UI_Mainwindow::saveButtonClicked() { QMenu menu; - menu.addAction("Save screen waveform", this, SLOT(save_screen_waveform())); - menu.addAction("Save memory waveform", this, SLOT(save_memory_waveform())); - menu.addAction("Save screenshot", this, SLOT(save_screenshot())); - menu.addAction("Factory", this, SLOT(set_to_factory())); + menu.addAction("Save screen waveform", this, SLOT(save_screen_waveform())); + menu.addAction("Save memory waveform", this, SLOT(save_mem_wav())); + menu.addAction("Analyze memory waveform", this, SLOT(analyze_mem_wav())); + menu.addAction("Save screenshot", this, SLOT(save_screenshot())); + menu.addAction("Factory", this, SLOT(set_to_factory())); menu.exec(saveButton->mapToGlobal(QPoint(0,0))); } +void UI_Mainwindow::save_mem_wav() +{ + save_memory_waveform(1); +} + + +void UI_Mainwindow::analyze_mem_wav() +{ + save_memory_waveform(0); +} + + void UI_Mainwindow::dispButtonClicked() { QMenu menu, diff --git a/mainwindow.h b/mainwindow.h index d59c15b..72a56f8 100644 --- a/mainwindow.h +++ b/mainwindow.h @@ -90,6 +90,7 @@ #include "save_data_thread.h" #include "decode_dialog.h" #include "tdial.h" +#include "wave_dialog.h" #include "third_party/kiss_fft/kiss_fftr.h" @@ -239,6 +240,7 @@ private: void serial_decoder(void); inline unsigned char reverse_bitorder_8(unsigned char); inline unsigned int reverse_bitorder_32(unsigned int); + void save_memory_waveform(int); private slots: @@ -260,7 +262,8 @@ private slots: void open_settings_dialog(); int get_device_settings(); void save_screen_waveform(); - void save_memory_waveform(); + void save_mem_wav(); + void analyze_mem_wav(); void save_screenshot(); void adjDialChanged(int); diff --git a/save_data.cpp b/save_data.cpp index 13f079a..b35f488 100644 --- a/save_data.cpp +++ b/save_data.cpp @@ -179,7 +179,7 @@ OUT_ERROR: } -void UI_Mainwindow::save_memory_waveform() +void UI_Mainwindow::save_memory_waveform(int job) { int i, j, k, n=0, @@ -269,7 +269,7 @@ void UI_Mainwindow::save_memory_waveform() rec_len = (EDFLIB_TIME_DIMENSION * (long long)mempnts) / devparms.samplerate; - if(rec_len < 100) + if((job == 1) && (rec_len < 100)) { strcpy(str, "Can not save waveforms shorter than 10 uSec.\n" "Set the horizontal timebase to 1 uSec or higher."); @@ -406,6 +406,12 @@ void UI_Mainwindow::save_memory_waveform() goto OUT_ERROR; } + if(n == 0) + { + sprintf(str, "No waveform data available."); + goto OUT_ERROR; + } + printf("received %i bytes, total %i bytes\n", n, n + bytes_rcvd); if(n > SAV_MEM_BSZ) @@ -426,14 +432,29 @@ void UI_Mainwindow::save_memory_waveform() empty_buf = 0; } - for(k=0; k= mempnts) + for(k=0; k= mempnts) + { + break; + } - wavbuf[chn][bytes_rcvd + k] = ((int)(((unsigned char *)device->buf)[k]) - yref[chn] - yor[chn]) << 5; + wavbuf[chn][bytes_rcvd + k] = ((int)(((unsigned char *)device->buf)[k]) - yref[chn] - yor[chn]) << 5; + } + } + else + { + for(k=0; k= mempnts) + { + break; + } + + wavbuf[chn][bytes_rcvd + k] = (int)(((unsigned char *)device->buf)[k]) - yref[chn] - yor[chn]; + } } bytes_rcvd += n; @@ -502,6 +523,13 @@ void UI_Mainwindow::save_memory_waveform() statusLabel->setText("Downloading finished"); } + if(job == 0) + { + new UI_wave_window(&devparms, wavbuf, this); + + goto OUT_NORMAL; + } + opath[0] = 0; if(recent_savedir[0]!=0) { @@ -597,15 +625,18 @@ OUT_NORMAL: disconnect(&get_data_thrd, 0, 0, 0); disconnect(&sav_data_thrd, 0, 0, 0); - if(hdl >= 0) + if(job == 1) { - edfclose_file(hdl); - } + if(hdl >= 0) + { + edfclose_file(hdl); + } - for(chn=0; chnstart(devparms.screentimerival); diff --git a/settings_dialog.h b/settings_dialog.h index 7d43b57..6691fc5 100644 --- a/settings_dialog.h +++ b/settings_dialog.h @@ -28,8 +28,8 @@ -#ifndef SELECT_DEVICE_FORM1_H -#define SELECT_DEVICE_FORM1_H +#ifndef SETTINGS_DIALOG_H +#define SETTINGS_DIALOG_H diff --git a/wave_dialog.cpp b/wave_dialog.cpp new file mode 100644 index 0000000..85052e1 --- /dev/null +++ b/wave_dialog.cpp @@ -0,0 +1,146 @@ +/* +*************************************************************************** +* +* Author: Teunis van Beelen +* +* Copyright (C) 2016 Teunis van Beelen +* +* Email: teuniz@gmail.com +* +*************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*************************************************************************** +*/ + + + + +#include "wave_dialog.h" + + + +UI_wave_window::UI_wave_window(struct device_settings *p_devparms, short *wbuf[MAX_CHNS], QWidget *parnt) +{ + int i, samples_per_div; + + mainwindow = (UI_Mainwindow *)parnt; + + setMinimumSize(840, 635); + setWindowTitle("Wave Memory"); + + devparms = (struct device_settings *)calloc(1, sizeof(struct device_settings)); + if(devparms == NULL) + { + printf("Malloc error! file: %s line: %i", __FILE__, __LINE__); + } + else + { + *devparms = *p_devparms; + } + + for(i=0; iwavebuf[i] = wbuf[i]; + } + + devparms->wavebufsz = devparms->acquirememdepth; + + if(devparms->timebasedelayenable) + { + samples_per_div = devparms->samplerate * devparms->timebasedelayscale; + } + else + { + samples_per_div = devparms->samplerate * devparms->timebasescale; + } + + devparms->timebasedelayenable = 0; + + wavcurve = new WaveCurve; + wavcurve->setBackgroundColor(Qt::black); + wavcurve->setSignalColor1(Qt::yellow); + wavcurve->setSignalColor2(Qt::cyan); + wavcurve->setSignalColor3(Qt::magenta); + wavcurve->setSignalColor4(QColor(0, 128, 255)); + wavcurve->setRasterColor(Qt::darkGray); + wavcurve->setBorderSize(40); + wavcurve->setDeviceParameters(devparms); + + wavslider = new QSlider; + wavslider->setOrientation(Qt::Horizontal); + wavslider->setRange(0, devparms->wavebufsz - (devparms->hordivisions * samples_per_div)); + wavslider->setValue((devparms->wavebufsz - (devparms->hordivisions * samples_per_div)) / 2); + + devparms->wave_mem_view_sample_start = wavslider->value(); + + g_layout = new QGridLayout(this); + g_layout->addWidget(wavcurve, 0, 0); + g_layout->addWidget(wavslider, 1, 0); + + connect(wavslider, SIGNAL(sliderMoved(int)), this, SLOT(wavslider_value_changed(int))); + + show(); +} + + +UI_wave_window::~UI_wave_window() +{ + int i; + + for(i=0; iwavebuf[i]); + } + + free(devparms); +} + + +void UI_wave_window::wavslider_value_changed(int val) +{ + devparms->wave_mem_view_sample_start = val; + + wavcurve->update(); +} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/wave_dialog.h b/wave_dialog.h new file mode 100644 index 0000000..92f15e3 --- /dev/null +++ b/wave_dialog.h @@ -0,0 +1,83 @@ +/* +*************************************************************************** +* +* Author: Teunis van Beelen +* +* Copyright (C) 2016 Teunis van Beelen +* +* Email: teuniz@gmail.com +* +*************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*************************************************************************** +*/ + + + + +#ifndef WAVE_DIALOG_H +#define WAVE_DIALOG_H + + + +#include +#include +#include +#include +#include + +#include "mainwindow.h" +#include "global.h" +#include "wave_view.h" + + +class UI_Mainwindow; + +class WaveCurve; + + +class UI_wave_window : public QDialog +{ + Q_OBJECT + +public: + + UI_wave_window(struct device_settings *, short *wbuf[MAX_CHNS], QWidget *parent=0); + ~UI_wave_window(); + +private: + +struct device_settings *devparms; + +UI_Mainwindow *mainwindow; + +QGridLayout *g_layout; + +WaveCurve *wavcurve; + +QSlider *wavslider; + +private slots: + +void wavslider_value_changed(int); + +}; + + + +#endif + + diff --git a/wave_view.cpp b/wave_view.cpp new file mode 100644 index 0000000..de7dbee --- /dev/null +++ b/wave_view.cpp @@ -0,0 +1,1573 @@ +/* +*************************************************************************** +* +* Author: Teunis van Beelen +* +* Copyright (C) 2016 Teunis van Beelen +* +* Email: teuniz@gmail.com +* +*************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*************************************************************************** +*/ + + + +#include "wave_view.h" + + + +WaveCurve::WaveCurve(QWidget *w_parent) : QWidget(w_parent) +{ + wavedialog = (UI_wave_window *)w_parent; + + setAttribute(Qt::WA_OpaquePaintEvent); + + SignalColor[0] = Qt::blue; + SignalColor[1] = Qt::blue; + SignalColor[2] = Qt::blue; + SignalColor[3] = Qt::blue; + tracewidth = 0; + BackgroundColor = Qt::gray; + RasterColor = Qt::darkGray; + TextColor = Qt::black; + + smallfont.setFamily("Arial"); + smallfont.setPixelSize(8); + + bufsize = 0; + bordersize = 60; + + v_sense = 1; + + mouse_x = 0; + mouse_y = 0; + mouse_old_x = 0; + mouse_old_y = 0; + + trig_pos_arrow_moving = 0; + + trig_pos_arrow_pos = 100; + + use_move_events = 0; + + old_w = 10000; + + devparms = NULL; +} + + +void WaveCurve::paintEvent(QPaintEvent *) +{ + int i, chn, + small_rulers, + w_trace_offset, + curve_w, + curve_h, + samples_per_div, + sample_range, + sample_start, + sample_end; + + + double h_step=0.0, + step, + step2; + + if(devparms == NULL) + { + return; + } + + QPainter paint(this); +#if QT_VERSION >= 0x050000 + paint.setRenderHint(QPainter::Qt4CompatiblePainting, true); +#endif + + QPainter *painter = &paint; + + curve_w = width(); + + curve_h = height(); + + bufsize = devparms->wavebufsz; + + small_rulers = 5 * devparms->hordivisions; + + painter->fillRect(0, 0, curve_w, curve_h, BackgroundColor); + + if((curve_w < ((bordersize * 2) + 5)) || (curve_h < ((bordersize * 2) + 5))) + { + return; + } + + painter->fillRect(0, 0, curve_w, 30, QColor(32, 32, 32)); + + samples_per_div = devparms->samplerate * devparms->timebasescale; + + devparms->timebaseoffset = (double)(((devparms->wavebufsz - (devparms->hordivisions * samples_per_div)) / 2) - devparms->wave_mem_view_sample_start) / + devparms->samplerate * -1.0; + + drawTopLabels(painter); + + drawSmallTriggerArrow(painter, 408, 16, 1, QColor(255, 128, 0)); + + painter->fillRect(0, curve_h - 30, curve_w, curve_h, QColor(32, 32, 32)); + +/////////////////////////////////// translate coordinates, draw and fill a rectangle /////////////////////////////////////////// + + painter->translate(bordersize, bordersize); + + curve_w -= (bordersize * 2); + + curve_h -= (bordersize * 2); + +/////////////////////////////////// draw the rasters /////////////////////////////////////////// + + painter->setPen(RasterColor); + + painter->drawRect (0, 0, curve_w - 1, curve_h - 1); + + if((devparms->math_fft == 0) || (devparms->math_fft_split == 0)) + { + if(devparms->displaygrid) + { + painter->setPen(QPen(QBrush(RasterColor, Qt::SolidPattern), tracewidth, Qt::DotLine, Qt::SquareCap, Qt::BevelJoin)); + + if(devparms->displaygrid == 2) + { + step = (double)curve_w / (double)devparms->hordivisions; + + for(i=1; ihordivisions; i++) + { + painter->drawLine(step * i, curve_h - 1, step * i, 0); + } + + step = curve_h / (double)devparms->vertdivisions; + + for(i=1; ivertdivisions; i++) + { + painter->drawLine(0, step * i, curve_w - 1, step * i); + } + } + else + { + painter->drawLine(curve_w / 2, curve_h - 1, curve_w / 2, 0); + + painter->drawLine(0, curve_h / 2, curve_w - 1, curve_h / 2); + } + } + + painter->setPen(RasterColor); + + step = (double)curve_w / (double)small_rulers; + + for(i=1; idisplaygrid) + { + painter->drawLine(step2, curve_h / 2 + 2, step2, curve_h / 2 - 2); + } + + if(i % 5) + { + painter->drawLine(step2, curve_h - 1, step2, curve_h - 5); + + painter->drawLine(step2, 0, step2, 4); + } + else + { + painter->drawLine(step2, curve_h - 1, step2, curve_h - 9); + + painter->drawLine(step2, 0, step2, 8); + } + } + + step = curve_h / (5.0 * devparms->vertdivisions); + + for(i=1; i<(5 * devparms->vertdivisions); i++) + { + step2 = step * i; + + if(devparms->displaygrid) + { + painter->drawLine(curve_w / 2 + 2, step2, curve_w / 2 - 2, step2); + } + + if(i % 5) + { + painter->drawLine(curve_w - 1, step2, curve_w - 5, step2); + + painter->drawLine(0, step2, 4, step2); + } + else + { + painter->drawLine(curve_w - 1, step2, curve_w - 9, step2); + + painter->drawLine(0, step2, 8, step2); + } + } + } + else + { + painter->drawLine(curve_w / 2, curve_h - 1, curve_w / 2, 0); + + painter->drawLine(0, curve_h / 2, curve_w - 1, curve_h / 2); + } + +/////////////////////////////////// draw the arrows /////////////////////////////////////////// + + if(devparms->modelserie == 6) + { + v_sense = -((double)curve_h / 256.0); + } + else + { + v_sense = -((double)curve_h / (25.0 * devparms->vertdivisions)); + } + + drawTrigCenterArrow(painter, curve_w / 2, 0); + + for(chn=0; chnchannel_cnt; chn++) + { + if(!devparms->chandisplay[chn]) + { + continue; + } + + chan_arrow_pos[chn] = (curve_h / 2) - (devparms->chanoffset[chn] / ((devparms->chanscale[chn] * devparms->vertdivisions) / curve_h)); + + if(chan_arrow_pos[chn] < 0) + { + chan_arrow_pos[chn] = -1; + + drawArrow(painter, -6, chan_arrow_pos[chn], 3, SignalColor[chn], '1' + chn); + } + else if(chan_arrow_pos[chn] > curve_h) + { + chan_arrow_pos[chn] = curve_h + 1; + + drawArrow(painter, -6, chan_arrow_pos[chn], 1, SignalColor[chn], '1' + chn); + } + else + { + drawArrow(painter, 0, chan_arrow_pos[chn], 0, SignalColor[chn], '1' + chn); + } + } + +/////////////////////////////////// draw the curve /////////////////////////////////////////// + + if(bufsize > 32) + { + painter->setClipping(true); + painter->setClipRegion(QRegion(0, 0, curve_w, curve_h), Qt::ReplaceClip); + + h_step = (double)curve_w / (devparms->hordivisions * samples_per_div); + + sample_start = devparms->wave_mem_view_sample_start; + + sample_end = devparms->hordivisions * samples_per_div + sample_start; + + if(sample_end > bufsize) + { + sample_end = bufsize; + } + + sample_range = sample_end - sample_start; + + w_trace_offset = 0; + +// if(bufsize != (devparms->hordivisions * samples_per_div)) +// { +// if(devparms->timebaseoffset < 0) +// { +// w_trace_offset = curve_w - ((double)curve_w * ((double)bufsize / (double)(devparms->hordivisions * samples_per_div))); +// } +// } + + for(chn=0; chnchannel_cnt; chn++) + { + if(!devparms->chandisplay[chn]) + { + continue; + } + + painter->setPen(QPen(QBrush(SignalColor[chn], Qt::SolidPattern), tracewidth, Qt::SolidLine, Qt::SquareCap, Qt::BevelJoin)); + + for(i=0; idrawLine(i * h_step + w_trace_offset, + (devparms->wavebuf[chn][i + sample_start] * v_sense) + (curve_h / 2), + (i + 1) * h_step + w_trace_offset, + (devparms->wavebuf[chn][i + sample_start] * v_sense) + (curve_h / 2)); + if(i) + { + painter->drawLine(i * h_step + w_trace_offset, + (devparms->wavebuf[chn][i - 1] * v_sense) + (curve_h / 2), + i * h_step + w_trace_offset, + (devparms->wavebuf[chn][i + sample_start] * v_sense) + (curve_h / 2)); + } + } + else + { + if(i < (bufsize - 1)) + { + if(devparms->displaytype) + { + painter->drawPoint(i * h_step + w_trace_offset, + (devparms->wavebuf[chn][i + sample_start] * v_sense) + (curve_h / 2)); + } + else + { + painter->drawLine(i * h_step + w_trace_offset, + (devparms->wavebuf[chn][i + sample_start] * v_sense) + (curve_h / 2), + (i + 1) * h_step + w_trace_offset, + (devparms->wavebuf[chn][i + 1 + sample_start] * v_sense) + (curve_h / 2)); + } + } + } + } + } + + painter->setClipping(false); + } + +/////////////////////////////////// draw the decoder /////////////////////////////////////////// + + if(devparms->math_decode_display) draw_decoder(painter, curve_w, curve_h); + +/////////////////////////////////// draw the trigger arrows /////////////////////////////////////////// + + if(devparms->triggeredgesource < 4) + { + trig_level_arrow_pos = (curve_h / 2) - ((devparms->triggeredgelevel[devparms->triggeredgesource] + devparms->chanoffset[devparms->triggeredgesource]) / ((devparms->chanscale[devparms->triggeredgesource] * devparms->vertdivisions) / curve_h)); + + if(trig_level_arrow_pos < 0) + { + trig_level_arrow_pos = -1; + + drawArrow(painter, curve_w + 6, trig_level_arrow_pos, 3, QColor(255, 128, 0), 'T'); + } + else if(trig_level_arrow_pos > curve_h) + { + trig_level_arrow_pos = curve_h + 1; + + drawArrow(painter, curve_w + 6, trig_level_arrow_pos, 1, QColor(255, 128, 0), 'T'); + } + else + { + drawArrow(painter, curve_w, trig_level_arrow_pos, 2, QColor(255, 128, 0), 'T'); + } + } + + if(trig_pos_arrow_moving) + { + drawArrow(painter, trig_pos_arrow_pos, 27, 1, QColor(255, 128, 0), 'T'); + } + else + { + if(devparms->timebasedelayenable) + { + trig_pos_arrow_pos = (curve_w / 2) - ((devparms->timebasedelayoffset / (devparms->timebasedelayscale * (double)devparms->hordivisions)) * curve_w); + } + else + { + trig_pos_arrow_pos = (curve_w / 2) - ((devparms->timebaseoffset / (devparms->timebasescale * (double)devparms->hordivisions)) * curve_w); + } + + if(trig_pos_arrow_pos < 0) + { + trig_pos_arrow_pos = -1; + + drawArrow(painter, trig_pos_arrow_pos, 18, 2, QColor(255, 128, 0), 'T'); + } + else if(trig_pos_arrow_pos > curve_w) + { + trig_pos_arrow_pos = curve_w + 1; + + drawArrow(painter, trig_pos_arrow_pos, 18, 0, QColor(255, 128, 0), 'T'); + } + else + { + drawArrow(painter, trig_pos_arrow_pos, 27, 1, QColor(255, 128, 0), 'T'); + } + } +} + + +void WaveCurve::setDeviceParameters(struct device_settings *devp) +{ + devparms = devp; +} + + +void WaveCurve::drawTopLabels(QPainter *painter) +{ + int i; + + char str[128]; + + double dtmp1, dtmp2; + + QPainterPath path; + + if(devparms == NULL) + { + return; + } + + path.addRoundedRect(5, 5, 70, 20, 3, 3); + + painter->fillPath(path, Qt::black); + + painter->setPen(Qt::white); + + painter->drawText(5, 5, 70, 20, Qt::AlignCenter, devparms->modelname); + +//////////////// triggerstatus /////////////////////////////// + + path = QPainterPath(); + + path.addRoundedRect(80, 5, 35, 20, 3, 3); + + painter->fillPath(path, Qt::black); + + painter->setPen(Qt::green); + + switch(devparms->triggerstatus) + { + case 0 : painter->drawText(80, 5, 35, 20, Qt::AlignCenter, "T'D"); + break; + case 1 : painter->drawText(80, 5, 35, 20, Qt::AlignCenter, "WAIT"); + break; + case 2 : painter->drawText(80, 5, 35, 20, Qt::AlignCenter, "RUN"); + break; + case 3 : painter->drawText(80, 5, 35, 20, Qt::AlignCenter, "AUTO"); + break; + case 4 : painter->drawText(80, 5, 35, 20, Qt::AlignCenter, "FIN"); + break; + case 5 : painter->setPen(Qt::red); + painter->drawText(80, 5, 35, 20, Qt::AlignCenter, "STOP"); + break; + } + +//////////////// horizontal /////////////////////////////// + + path = QPainterPath(); + + path.addRoundedRect(140, 5, 70, 20, 3, 3); + + painter->fillPath(path, Qt::black); + + painter->setPen(Qt::white); + + painter->drawText(125, 20, "H"); + + convert_to_metric_suffix(str, devparms->timebasescale, 1); + + remove_trailing_zeros(str); + + strcat(str, "s"); + + painter->drawText(140, 5, 70, 20, Qt::AlignCenter, str); + +//////////////// samplerate /////////////////////////////// + + painter->setPen(Qt::gray); + + convert_to_metric_suffix(str, devparms->samplerate, 0); + + strcat(str, "Sa/s"); + + painter->drawText(200, -1, 85, 20, Qt::AlignCenter, str); + + if(devparms->acquirememdepth) + { + convert_to_metric_suffix(str, devparms->acquirememdepth, 1); + + remove_trailing_zeros(str); + + strcat(str, "pts"); + + painter->drawText(200, 14, 85, 20, Qt::AlignCenter, str); + } + else + { + painter->drawText(200, 14, 85, 20, Qt::AlignCenter, "AUTO"); + } + +//////////////// memory position /////////////////////////////// + + path = QPainterPath(); + + path.addRoundedRect(285, 5, 240, 20, 3, 3); + + painter->fillPath(path, Qt::black); + + painter->setPen(Qt::gray); + + dtmp1 = (devparms->hordivisions * devparms->timebasescale) / (devparms->acquirememdepth / devparms->samplerate); + + dtmp2 = devparms->timebaseoffset / (devparms->acquirememdepth / devparms->samplerate); + + painter->fillRect(288, 16, 233, 8, QColor(64, 160, 255)); + + painter->fillRect(288 + 119 + ((233.0 * dtmp2) - (116.0 * dtmp1)), 16, 233 * dtmp1, 8, Qt::black); + + painter->drawRect(288, 16, 233, 8); + + painter->setPen(Qt::white); + + painter->drawLine(289, 20, 291, 22); + + for(i=0; i<19; i++) + { + painter->drawLine((i * 12) + 291, 22, (i * 12) + 293, 22); + + painter->drawLine((i * 12) + 297, 18, (i * 12) + 299, 18); + + painter->drawLine((i * 12) + 294, 21, (i * 12) + 296, 19); + + painter->drawLine((i * 12) + 300, 19, (i * 12) + 302, 21); + } + + painter->drawLine(519, 22, 520, 22); + +//////////////// delay /////////////////////////////// + + path = QPainterPath(); + + path.addRoundedRect(570, 5, 85, 20, 3, 3); + + painter->fillPath(path, Qt::black); + + painter->setPen(QColor(255, 128, 0)); + + painter->drawText(555, 20, "D"); + + convert_to_metric_suffix(str, devparms->timebaseoffset, 4); + + strcat(str, "s"); + + painter->drawText(570, 5, 85, 20, Qt::AlignCenter, str); + +//////////////// trigger /////////////////////////////// + + path = QPainterPath(); + + path.addRoundedRect(685, 5, 125, 20, 3, 3); + + painter->fillPath(path, Qt::black); + + painter->setPen(Qt::gray); + + painter->drawText(670, 20, "T"); + + convert_to_metric_suffix(str, devparms->triggeredgelevel[devparms->triggeredgesource], 2); + + strcat(str, "V"); + + if(devparms->triggeredgesource < 4) + { + painter->setPen(SignalColor[devparms->triggeredgesource]); + } + else + { + switch(devparms->triggeredgesource) + { + case 4: + case 5: painter->setPen(Qt::green); + break; + case 6: painter->setPen(QColor(255, 64, 0)); + break; + } + } + + if(devparms->triggeredgesource != 6) + { + painter->drawText(735, 5, 85, 20, Qt::AlignCenter, str); + } + + path = QPainterPath(); + + path.addRoundedRect(725, 7, 15, 15, 3, 3); + + if(devparms->triggeredgesource < 4) + { + painter->fillPath(path, SignalColor[devparms->triggeredgesource]); + + sprintf(str, "%i", devparms->triggeredgesource + 1); + } + else + { + switch(devparms->triggeredgesource) + { + case 4: + case 5: painter->fillPath(path, Qt::green); + strcpy(str, "E"); + break; + case 6: painter->fillPath(path, QColor(255, 64, 0)); + strcpy(str, "AC"); + break; + } + } + + if(devparms->triggeredgeslope == 0) + { + painter->drawLine(705, 8, 710, 8); + painter->drawLine(705, 8, 705, 20); + painter->drawLine(700, 20, 705, 20); + painter->drawLine(701, 15, 705, 11); + painter->drawLine(709, 15, 705, 11); + } + + if(devparms->triggeredgeslope == 1) + { + painter->drawLine(700, 8, 705, 8); + painter->drawLine(705, 8, 705, 20); + painter->drawLine(705, 20, 710, 20); + painter->drawLine(701, 12, 705, 16); + painter->drawLine(709, 12, 705, 16); + } + + if(devparms->triggeredgeslope == 2) + { + painter->drawLine(702, 8, 702, 18); + painter->drawLine(700, 10, 702, 8); + painter->drawLine(704, 10, 702, 8); + painter->drawLine(708, 8, 708, 18); + painter->drawLine(706, 16, 708, 18); + painter->drawLine(710, 16, 708, 18); + } + + painter->setPen(Qt::black); + + painter->drawText(725, 8, 15, 15, Qt::AlignCenter, str); +} + + +void WaveCurve::drawArrow(QPainter *painter, int xpos, int ypos, int rot, QColor color, char ch) +{ + QPainterPath path; + + char str[4]; + + str[0] = ch; + str[1] = 0; + + if(rot == 0) + { + path.moveTo(xpos - 20, ypos + 6); + path.lineTo(xpos - 7, ypos + 6); + path.lineTo(xpos, ypos); + path.lineTo(xpos - 7, ypos - 6); + path.lineTo(xpos - 20, ypos - 6); + path.lineTo(xpos - 20, ypos + 6); + painter->fillPath(path, color); + + painter->setPen(Qt::black); + + painter->drawText(xpos - 17, ypos + 4, str); + } + else if(rot == 1) + { + path.moveTo(xpos + 6, ypos - 20); + path.lineTo(xpos + 6, ypos - 7); + path.lineTo(xpos, ypos); + path.lineTo(xpos - 6, ypos - 7); + path.lineTo(xpos - 6, ypos - 20); + path.lineTo(xpos + 6, ypos - 20); + painter->fillPath(path, color); + + painter->setPen(Qt::black); + + painter->drawText(xpos - 3, ypos - 7, str); + } + else if(rot == 2) + { + path.moveTo(xpos + 20, ypos + 6); + path.lineTo(xpos + 7, ypos + 6); + path.lineTo(xpos, ypos); + path.lineTo(xpos + 7, ypos - 6); + path.lineTo(xpos + 20, ypos - 6); + path.lineTo(xpos + 20, ypos + 6); + painter->fillPath(path, color); + + painter->setPen(Qt::black); + + painter->drawText(xpos + 9, ypos + 4, str); + } + else if(rot == 3) + { + path.moveTo(xpos + 6, ypos + 20); + path.lineTo(xpos + 6, ypos + 7); + path.lineTo(xpos, ypos); + path.lineTo(xpos - 6, ypos + 7); + path.lineTo(xpos - 6, ypos + 20); + path.lineTo(xpos + 6, ypos + 20); + painter->fillPath(path, color); + + painter->setPen(Qt::black); + + painter->drawText(xpos - 3, ypos + 16, str); + } +} + + +void WaveCurve::drawSmallTriggerArrow(QPainter *painter, int xpos, int ypos, int rot, QColor color) +{ + QPainterPath path; + + if(rot == 0) + { + path.moveTo(xpos - 13, ypos - 5); + path.lineTo(xpos - 5, ypos - 5); + path.lineTo(xpos, ypos); + path.lineTo(xpos - 5, ypos + 5); + path.lineTo(xpos - 13, ypos + 5); + path.lineTo(xpos - 13, ypos - 5); + + painter->fillPath(path, color); + + painter->setPen(Qt::black); + + painter->drawLine(xpos - 10, ypos - 4, xpos - 6, ypos - 4); + + painter->drawLine(xpos - 8, ypos - 4, xpos - 8, ypos + 4); + } + else if(rot == 1) + { + path.moveTo(xpos + 5, ypos - 10); + path.lineTo(xpos + 5, ypos - 5); + path.lineTo(xpos, ypos); + path.lineTo(xpos - 4, ypos - 5); + path.lineTo(xpos - 4, ypos - 10); + path.lineTo(xpos + 5, ypos - 10); + + painter->fillPath(path, color); + + painter->setPen(Qt::black); + + painter->drawLine(xpos - 2, ypos - 8, xpos + 2, ypos - 8); + + painter->drawLine(xpos, ypos - 8, xpos, ypos - 3); + } + else if(rot == 2) + { + path.moveTo(xpos + 12, ypos - 5); + path.lineTo(xpos + 5, ypos - 5); + path.lineTo(xpos, ypos); + path.lineTo(xpos + 5, ypos + 5); + path.lineTo(xpos + 12, ypos + 5); + path.lineTo(xpos + 12, ypos - 5); + + painter->fillPath(path, color); + + painter->setPen(Qt::black); + + painter->drawLine(xpos + 9, ypos - 4, xpos + 5, ypos - 4); + + painter->drawLine(xpos + 7, ypos - 4, xpos + 7, ypos + 4); + } +} + + +void WaveCurve::drawTrigCenterArrow(QPainter *painter, int xpos, int ypos) +{ + QPainterPath path; + + path.moveTo(xpos + 7, ypos); + path.lineTo(xpos - 6, ypos); + path.lineTo(xpos, ypos + 7); + path.lineTo(xpos + 7, ypos); + painter->fillPath(path, QColor(255, 128, 0)); +} + + +void WaveCurve::setSignalColor1(QColor newColor) +{ + SignalColor[0] = newColor; + update(); +} + + +void WaveCurve::setSignalColor2(QColor newColor) +{ + SignalColor[1] = newColor; + update(); +} + + +void WaveCurve::setSignalColor3(QColor newColor) +{ + SignalColor[2] = newColor; + update(); +} + + +void WaveCurve::setSignalColor4(QColor newColor) +{ + SignalColor[3] = newColor; + update(); +} + + +void WaveCurve::setTraceWidth(int tr_width) +{ + tracewidth = tr_width; + if(tracewidth < 0) tracewidth = 0; + update(); +} + + +void WaveCurve::setBackgroundColor(QColor newColor) +{ + BackgroundColor = newColor; + update(); +} + + +void WaveCurve::setRasterColor(QColor newColor) +{ + RasterColor = newColor; + update(); +} + + +void WaveCurve::setBorderSize(int newsize) +{ + bordersize = newsize; + if(bordersize < 0) bordersize = 0; + update(); +} + + +void WaveCurve::mousePressEvent(QMouseEvent *press_event) +{ + int m_x, + m_y; + + setFocus(Qt::MouseFocusReason); + + w = width() - (2 * bordersize); + h = height() - (2 * bordersize); + + m_x = press_event->x() - bordersize; + m_y = press_event->y() - bordersize; + + if(devparms == NULL) + { + return; + } + + if(!devparms->connected) + { + return; + } + + if(press_event->button() == Qt::LeftButton) + { + if(((m_x > (trig_pos_arrow_pos - 8)) && (m_x < (trig_pos_arrow_pos + 8)) && (m_y > 5) && (m_y < 24)) || + ((trig_pos_arrow_pos > w) && (m_x > (trig_pos_arrow_pos - 24)) && (m_x <= trig_pos_arrow_pos) && (m_y > 9) && (m_y < 26)) || + ((trig_pos_arrow_pos < 0) && (m_x < 24) && (m_x >= 0) && (m_y > 9) && (m_y < 26))) + { + trig_pos_arrow_moving = 1; + use_move_events = 1; + setMouseTracking(true); + mouse_old_x = m_x; + mouse_old_y = m_y; + } + } +} + + +void WaveCurve::mouseReleaseEvent(QMouseEvent *release_event) +{ + int tmp; + + w = width() - (2 * bordersize); + h = height() - (2 * bordersize); + + mouse_x = release_event->x() - bordersize; + mouse_y = release_event->y() - bordersize; + + if(devparms == NULL) + { + return; + } + + if(trig_pos_arrow_moving) + { + trig_pos_arrow_pos = mouse_x; + + if(trig_pos_arrow_pos < 0) + { + trig_pos_arrow_pos = 0; + } + + if(trig_pos_arrow_pos > w) + { + trig_pos_arrow_pos = w; + } + +// printf("w is %i trig_pos_arrow_pos is %i\n", w, trig_pos_arrow_pos); + + devparms->timebaseoffset = ((devparms->timebasescale * (double)devparms->hordivisions) / w) * ((w / 2) - trig_pos_arrow_pos); + + tmp = devparms->timebaseoffset / (devparms->timebasescale / 50); + + devparms->timebaseoffset = (devparms->timebasescale / 50) * tmp; + } + + trig_pos_arrow_moving = 0; + use_move_events = 0; + setMouseTracking(false); + + update(); +} + + +void WaveCurve::mouseMoveEvent(QMouseEvent *move_event) +{ + if(!use_move_events) + { + return; + } + + mouse_x = move_event->x() - bordersize; + mouse_y = move_event->y() - bordersize; + + if(devparms == NULL) + { + return; + } + + if(!devparms->connected) + { + return; + } + + if(trig_pos_arrow_moving) + { + trig_pos_arrow_pos = mouse_x; + + if(trig_pos_arrow_pos < 0) + { + trig_pos_arrow_pos = 0; + } + + if(trig_pos_arrow_pos > w) + { + trig_pos_arrow_pos = w; + } + } + + update(); +} + + +void WaveCurve::paintLabel(QPainter *painter, int xpos, int ypos, int xw, int yh, const char *str, QColor color) +{ + QPainterPath path; + + path.addRoundedRect(xpos, ypos, xw, yh, 3, 3); + + painter->fillPath(path, Qt::black); + + painter->setPen(color); + + painter->drawRoundedRect(xpos, ypos, xw, yh, 3, 3); + + painter->drawText(xpos, ypos, xw, yh, Qt::AlignCenter, str); +} + + +void WaveCurve::draw_decoder(QPainter *painter, int dw, int dh) +{ + int i, j, k, + cell_width, + base_line, + line_h_uart_tx=0, + line_h_uart_rx=0, + line_h_spi_mosi=0, + line_h_spi_miso=0, + spi_chars=1, + pixel_per_bit=1, + samples_per_div; + + double pix_per_smpl; + + char str[256]; + + + samples_per_div = devparms->samplerate * devparms->timebasescale; + + if(devparms->modelserie == 6) + { + base_line = (dh / 2) - (((double)dh / 400.0) * devparms->math_decode_pos); + } + else + { + base_line = ((double)dh / 400.0) * devparms->math_decode_pos; + } + + pix_per_smpl = (double)dw / (devparms->hordivisions * samples_per_div); + + switch(devparms->math_decode_format) + { + case 0: cell_width = 40; // hex + break; + case 1: cell_width = 30; // ASCII + break; + case 2: cell_width = 30; // decimal; + break; + case 3: cell_width = 70; // binary + break; + default: cell_width = 70; // line + break; + } + + if(devparms->math_decode_mode == DECODE_MODE_UART) + { + pixel_per_bit = ((double)dw / 12.0 / devparms->timebasescale) / (double)devparms->math_decode_uart_baud; + + cell_width = pixel_per_bit * devparms->math_decode_uart_width; + + painter->setPen(Qt::green); + + if(devparms->math_decode_uart_tx && devparms->math_decode_uart_rx) + { + line_h_uart_tx = base_line - 5; + + line_h_uart_rx = base_line + 45; + + painter->drawLine(0, line_h_uart_tx, dw, line_h_uart_tx); + + painter->drawLine(0, line_h_uart_rx, dw, line_h_uart_rx); + } + else if(devparms->math_decode_uart_tx) + { + line_h_uart_tx = base_line; + + painter->drawLine(0, line_h_uart_tx, dw, line_h_uart_tx); + } + else if(devparms->math_decode_uart_rx) + { + line_h_uart_rx = base_line; + + painter->drawLine(0, line_h_uart_rx, dw, line_h_uart_rx); + } + + if(devparms->math_decode_uart_tx) + { + for(i=0; imath_decode_uart_tx_nval; i++) + { + painter->fillRect(devparms->math_decode_uart_tx_val_pos[i] * pix_per_smpl, line_h_uart_tx - 13, cell_width, 26, Qt::black); + + painter->drawRect(devparms->math_decode_uart_tx_val_pos[i] * pix_per_smpl, line_h_uart_tx - 13, cell_width, 26); + } + } + + if(devparms->math_decode_uart_rx) + { + for(i=0; imath_decode_uart_rx_nval; i++) + { + painter->fillRect(devparms->math_decode_uart_rx_val_pos[i] * pix_per_smpl, line_h_uart_rx - 13, cell_width, 26, Qt::black); + + painter->drawRect(devparms->math_decode_uart_rx_val_pos[i] * pix_per_smpl, line_h_uart_rx - 13, cell_width, 26); + } + } + + painter->setPen(Qt::white); + + if(devparms->math_decode_uart_tx) + { + switch(devparms->math_decode_format) + { + case 0: painter->drawText(5, line_h_uart_tx - 35, 65, 30, Qt::AlignCenter, "Tx[HEX]"); + break; + case 1: painter->drawText(5, line_h_uart_tx - 35, 65, 30, Qt::AlignCenter, "Tx[ASC]"); + break; + case 2: painter->drawText(5, line_h_uart_tx - 35, 65, 30, Qt::AlignCenter, "Tx[DEC]"); + break; + case 3: painter->drawText(5, line_h_uart_tx - 35, 65, 30, Qt::AlignCenter, "Tx[BIN]"); + break; + case 4: painter->drawText(5, line_h_uart_tx - 35, 65, 30, Qt::AlignCenter, "Tx[LINE]"); + break; + default: painter->drawText(5, line_h_uart_tx - 35, 65, 30, Qt::AlignCenter, "Tx[\?\?\?]"); + break; + } + + for(i=0; imath_decode_uart_tx_nval; i++) + { + if(devparms->math_decode_format == 0) // hex + { + sprintf(str, "%02X", devparms->math_decode_uart_tx_val[i]); + + painter->drawText(devparms->math_decode_uart_tx_val_pos[i] * pix_per_smpl, line_h_uart_tx - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 1) // ASCII + { + ascii_decode_control_char(devparms->math_decode_uart_tx_val[i], str); + + painter->drawText(devparms->math_decode_uart_tx_val_pos[i] * pix_per_smpl, line_h_uart_tx - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 2) // decimal + { + sprintf(str, "%u", (unsigned int)devparms->math_decode_uart_tx_val[i]); + + painter->drawText(devparms->math_decode_uart_tx_val_pos[i] * pix_per_smpl, line_h_uart_tx - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 3) // binary + { + for(j=0; jmath_decode_uart_width; j++) + { + str[devparms->math_decode_uart_width - 1 - j] = ((devparms->math_decode_uart_tx_val[i] >> j) & 1) + '0'; + } + + str[j] = 0; + + painter->drawText(devparms->math_decode_uart_tx_val_pos[i] * pix_per_smpl, line_h_uart_tx - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 4) // line + { + for(j=0; jmath_decode_uart_width; j++) + { + str[j] = ((devparms->math_decode_uart_tx_val[i] >> j) & 1) + '0'; + } + + str[j] = 0; + + painter->drawText(devparms->math_decode_uart_tx_val_pos[i] * pix_per_smpl, line_h_uart_tx - 13, cell_width, 30, Qt::AlignCenter, str); + } + + if(devparms->math_decode_uart_tx_err[i]) + { + painter->setPen(Qt::red); + + painter->drawText(devparms->math_decode_uart_tx_val_pos[i] * pix_per_smpl + cell_width, line_h_uart_tx - 13, 25, 25, Qt::AlignCenter, "?"); + + painter->setPen(Qt::white); + } + } + } + + if(devparms->math_decode_uart_rx) + { + switch(devparms->math_decode_format) + { + case 0: painter->drawText(5, line_h_uart_rx - 35, 65, 30, Qt::AlignCenter, "Rx[HEX]"); + break; + case 1: painter->drawText(5, line_h_uart_rx - 35, 65, 30, Qt::AlignCenter, "Rx[ASC]"); + break; + case 2: painter->drawText(5, line_h_uart_rx - 35, 65, 30, Qt::AlignCenter, "Rx[DEC]"); + break; + case 3: painter->drawText(5, line_h_uart_rx - 35, 65, 30, Qt::AlignCenter, "Rx[BIN]"); + break; + case 4: painter->drawText(5, line_h_uart_rx - 35, 65, 30, Qt::AlignCenter, "Rx[LINE]"); + break; + default: painter->drawText(5, line_h_uart_rx - 35, 65, 30, Qt::AlignCenter, "Rx[\?\?\?]"); + break; + } + + for(i=0; imath_decode_uart_rx_nval; i++) + { + if(devparms->math_decode_format == 0) // hex + { + sprintf(str, "%02X", devparms->math_decode_uart_rx_val[i]); + + painter->drawText(devparms->math_decode_uart_rx_val_pos[i] * pix_per_smpl, line_h_uart_rx - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 1) // ASCII + { + ascii_decode_control_char(devparms->math_decode_uart_rx_val[i], str); + + painter->drawText(devparms->math_decode_uart_rx_val_pos[i] * pix_per_smpl, line_h_uart_rx - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 2) // decimal + { + sprintf(str, "%u", (unsigned int)devparms->math_decode_uart_rx_val[i]); + + painter->drawText(devparms->math_decode_uart_rx_val_pos[i] * pix_per_smpl, line_h_uart_rx - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 3) // binary + { + for(j=0; jmath_decode_uart_width; j++) + { + str[devparms->math_decode_uart_width - 1 - j] = ((devparms->math_decode_uart_rx_val[i] >> j) & 1) + '0'; + } + + str[j] = 0; + + painter->drawText(devparms->math_decode_uart_rx_val_pos[i] * pix_per_smpl, line_h_uart_rx - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 4) // line + { + for(j=0; jmath_decode_uart_width; j++) + { + str[j] = ((devparms->math_decode_uart_rx_val[i] >> j) & 1) + '0'; + } + + str[j] = 0; + + painter->drawText(devparms->math_decode_uart_rx_val_pos[i] * pix_per_smpl, line_h_uart_rx - 13, cell_width, 30, Qt::AlignCenter, str); + } + + if(devparms->math_decode_uart_rx_err[i]) + { + painter->setPen(Qt::red); + + painter->drawText(devparms->math_decode_uart_rx_val_pos[i] * pix_per_smpl + cell_width, line_h_uart_rx - 13, 25, 25, Qt::AlignCenter, "?"); + + painter->setPen(Qt::white); + } + } + } + } + + if(devparms->math_decode_mode == DECODE_MODE_SPI) + { + painter->setPen(Qt::green); + + if(devparms->math_decode_spi_width > 24) + { + spi_chars = 4; + } + else if(devparms->math_decode_spi_width > 16) + { + spi_chars = 3; + } + else if(devparms->math_decode_spi_width > 8) + { + spi_chars = 2; + } + else + { + spi_chars = 1; + } + + cell_width *= spi_chars; + + if(devparms->math_decode_spi_mosi && devparms->math_decode_spi_miso) + { + line_h_spi_mosi = base_line - 5; + + line_h_spi_miso = base_line + 45; + + painter->drawLine(0, line_h_spi_mosi, dw, line_h_spi_mosi); + + painter->drawLine(0, line_h_spi_miso, dw, line_h_spi_miso); + } + else if(devparms->math_decode_spi_mosi) + { + line_h_spi_mosi = base_line; + + painter->drawLine(0, line_h_spi_mosi, dw, line_h_spi_mosi); + } + else if(devparms->math_decode_spi_miso) + { + line_h_spi_miso = base_line; + + painter->drawLine(0, line_h_spi_miso, dw, line_h_spi_miso); + } + + if(devparms->math_decode_spi_mosi) + { + for(i=0; imath_decode_spi_mosi_nval; i++) + { + cell_width = (devparms->math_decode_spi_mosi_val_pos_end[i] - devparms->math_decode_spi_mosi_val_pos[i]) * + pix_per_smpl; + + painter->fillRect(devparms->math_decode_spi_mosi_val_pos[i] * pix_per_smpl, line_h_spi_mosi - 13, cell_width, 26, Qt::black); + + painter->drawRect(devparms->math_decode_spi_mosi_val_pos[i] * pix_per_smpl, line_h_spi_mosi - 13, cell_width, 26); + } + } + + if(devparms->math_decode_spi_miso) + { + for(i=0; imath_decode_spi_miso_nval; i++) + { + cell_width = (devparms->math_decode_spi_miso_val_pos_end[i] - devparms->math_decode_spi_miso_val_pos[i]) * + pix_per_smpl; + + painter->fillRect(devparms->math_decode_spi_miso_val_pos[i] * pix_per_smpl, line_h_spi_miso - 13, cell_width, 26, Qt::black); + + painter->drawRect(devparms->math_decode_spi_miso_val_pos[i] * pix_per_smpl, line_h_spi_miso - 13, cell_width, 26); + } + } + + painter->setPen(Qt::white); + + if(devparms->math_decode_spi_mosi) + { + switch(devparms->math_decode_format) + { + case 0: painter->drawText(5, line_h_spi_mosi - 35, 80, 30, Qt::AlignCenter, "Mosi[HEX]"); + break; + case 1: painter->drawText(5, line_h_spi_mosi - 35, 80, 30, Qt::AlignCenter, "Mosi[ASC]"); + break; + case 2: painter->drawText(5, line_h_spi_mosi - 35, 80, 30, Qt::AlignCenter, "Mosi[DEC]"); + break; + case 3: painter->drawText(5, line_h_spi_mosi - 35, 80, 30, Qt::AlignCenter, "Mosi[BIN]"); + break; + case 4: painter->drawText(5, line_h_spi_mosi - 35, 80, 30, Qt::AlignCenter, "Mosi[LINE]"); + break; + default: painter->drawText(5, line_h_spi_mosi - 35, 80, 30, Qt::AlignCenter, "Mosi[\?\?\?]"); + break; + } + + for(i=0; imath_decode_spi_mosi_nval; i++) + { + if(devparms->math_decode_format == 0) // hex + { + switch(spi_chars) + { + case 1: sprintf(str, "%02X", devparms->math_decode_spi_mosi_val[i]); + break; + case 2: sprintf(str, "%04X", devparms->math_decode_spi_mosi_val[i]); + break; + case 3: sprintf(str, "%06X", devparms->math_decode_spi_mosi_val[i]); + break; + case 4: sprintf(str, "%08X", devparms->math_decode_spi_mosi_val[i]); + break; + } + + painter->drawText(devparms->math_decode_spi_mosi_val_pos[i] * pix_per_smpl, line_h_spi_mosi - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 1) // ASCII + { + for(k=0, j=0; kmath_decode_spi_mosi_val[i] >> (k * 8), str + j); + } + + painter->drawText(devparms->math_decode_spi_mosi_val_pos[i] * pix_per_smpl, line_h_spi_mosi - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 2) // decimal + { + sprintf(str, "%u", devparms->math_decode_spi_mosi_val[i]); + + painter->drawText(devparms->math_decode_spi_mosi_val_pos[i] * pix_per_smpl, line_h_spi_mosi - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 3) // binary + { + for(j=0; jmath_decode_spi_width; j++) + { + str[devparms->math_decode_spi_width - 1 - j] = ((devparms->math_decode_spi_mosi_val[i] >> j) & 1) + '0'; + } + + str[j] = 0; + + painter->drawText(devparms->math_decode_spi_mosi_val_pos[i] * pix_per_smpl, line_h_spi_mosi - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 4) // line + { + for(j=0; jmath_decode_spi_width; j++) + { + str[j] = ((devparms->math_decode_spi_mosi_val[i] >> j) & 1) + '0'; + } + + str[devparms->math_decode_spi_width] = 0; + + painter->drawText(devparms->math_decode_spi_mosi_val_pos[i] * pix_per_smpl, line_h_spi_mosi - 13, cell_width, 30, Qt::AlignCenter, str); + } + } + } + + if(devparms->math_decode_spi_miso) + { + switch(devparms->math_decode_format) + { + case 0: painter->drawText(5, line_h_spi_miso - 35, 80, 30, Qt::AlignCenter, "Miso[HEX]"); + break; + case 1: painter->drawText(5, line_h_spi_miso - 35, 80, 30, Qt::AlignCenter, "Miso[HEX]"); + break; + case 2: painter->drawText(5, line_h_spi_miso - 35, 80, 30, Qt::AlignCenter, "Miso[DEC]"); + break; + case 3: painter->drawText(5, line_h_spi_miso - 35, 80, 30, Qt::AlignCenter, "Miso[BIN]"); + break; + case 4: painter->drawText(5, line_h_spi_miso - 35, 80, 30, Qt::AlignCenter, "Miso[LINE]"); + break; + default: painter->drawText(5, line_h_spi_miso - 35, 80, 30, Qt::AlignCenter, "Miso[\?\?\?]"); + break; + } + + for(i=0; imath_decode_spi_miso_nval; i++) + { + if(devparms->math_decode_format == 0) // hex + { + switch(spi_chars) + { + case 1: sprintf(str, "%02X", devparms->math_decode_spi_miso_val[i]); + break; + case 2: sprintf(str, "%04X", devparms->math_decode_spi_miso_val[i]); + break; + case 3: sprintf(str, "%06X", devparms->math_decode_spi_miso_val[i]); + break; + case 4: sprintf(str, "%08X", devparms->math_decode_spi_miso_val[i]); + break; + } + + painter->drawText(devparms->math_decode_spi_miso_val_pos[i] * pix_per_smpl, line_h_spi_miso - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 1) // ASCII + { + for(k=0, j=0; kmath_decode_spi_miso_val[i] >> (k * 8), str + j); + } + + painter->drawText(devparms->math_decode_spi_miso_val_pos[i] * pix_per_smpl, line_h_spi_miso - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 2) // decimal + { + sprintf(str, "%u", devparms->math_decode_spi_miso_val[i]); + + painter->drawText(devparms->math_decode_spi_miso_val_pos[i] * pix_per_smpl, line_h_spi_miso - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 3) // binary + { + for(j=0; jmath_decode_spi_width; j++) + { + str[devparms->math_decode_spi_width - 1 - j] = ((devparms->math_decode_spi_miso_val[i] >> j) & 1) + '0'; + } + + str[j] = 0; + + painter->drawText(devparms->math_decode_spi_miso_val_pos[i] * pix_per_smpl, line_h_spi_miso - 13, cell_width, 30, Qt::AlignCenter, str); + } + else if(devparms->math_decode_format == 4) // line + { + for(j=0; jmath_decode_spi_width; j++) + { + str[j] = ((devparms->math_decode_spi_miso_val[i] >> j) & 1) + '0'; + } + + str[devparms->math_decode_spi_width] = 0; + + painter->drawText(devparms->math_decode_spi_miso_val_pos[i] * pix_per_smpl, line_h_spi_miso - 13, cell_width, 30, Qt::AlignCenter, str); + } + } + } + } +} + + +int WaveCurve::ascii_decode_control_char(char ch, char *str) +{ + if((ch > 32) && (ch < 127)) + { + str[0] = ch; + + str[1] = 0; + + return 1; + } + + switch(ch) + { + case 0: strcpy(str, "NULL"); + break; + case 1: strcpy(str, "SOH"); + break; + case 2: strcpy(str, "STX"); + break; + case 3: strcpy(str, "ETX"); + break; + case 4: strcpy(str, "EOT"); + break; + case 5: strcpy(str, "ENQ"); + break; + case 6: strcpy(str, "ACK"); + break; + case 7: strcpy(str, "BEL"); + break; + case 8: strcpy(str, "BS"); + break; + case 9: strcpy(str, "HT"); + break; + case 10: strcpy(str, "LF"); + break; + case 11: strcpy(str, "VT"); + break; + case 12: strcpy(str, "FF"); + break; + case 13: strcpy(str, "CR"); + break; + case 14: strcpy(str, "SO"); + break; + case 15: strcpy(str, "SI"); + break; + case 16: strcpy(str, "DLE"); + break; + case 17: strcpy(str, "DC1"); + break; + case 18: strcpy(str, "DC2"); + break; + case 19: strcpy(str, "DC3"); + break; + case 20: strcpy(str, "DC4"); + break; + case 21: strcpy(str, "NAK"); + break; + case 22: strcpy(str, "SYN"); + break; + case 23: strcpy(str, "ETB"); + break; + case 24: strcpy(str, "CAN"); + break; + case 25: strcpy(str, "EM"); + break; + case 26: strcpy(str, "SUB"); + break; + case 27: strcpy(str, "ESC"); + break; + case 28: strcpy(str, "FS"); + break; + case 29: strcpy(str, "GS"); + break; + case 30: strcpy(str, "RS"); + break; + case 31: strcpy(str, "US"); + break; + case 32: strcpy(str, "SP"); + break; + case 127: strcpy(str, "DEL"); + break; + default: strcpy(str, "."); + break; + } + + return strlen(str); +} + + + + + + + + + + + + diff --git a/wave_view.h b/wave_view.h new file mode 100644 index 0000000..e399754 --- /dev/null +++ b/wave_view.h @@ -0,0 +1,131 @@ +/* +*************************************************************************** +* +* Author: Teunis van Beelen +* +* Copyright (C) 2016 Teunis van Beelen +* +* Email: teuniz@gmail.com +* +*************************************************************************** +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program. If not, see . +* +*************************************************************************** +*/ + + + +#ifndef WAVECURVE_H +#define WAVECURVE_H + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "global.h" +#include "utils.h" +#include "wave_dialog.h" + + +class UI_wave_window; + + +class WaveCurve: public QWidget +{ + Q_OBJECT + +public: + WaveCurve(QWidget *parent=0); + + QSize sizeHint() const {return minimumSizeHint(); } + QSize minimumSizeHint() const {return QSize(30,10); } + + void setSignalColor1(QColor); + void setSignalColor2(QColor); + void setSignalColor3(QColor); + void setSignalColor4(QColor); + void setTraceWidth(int); + void setBackgroundColor(QColor); + void setRasterColor(QColor); + void setTextColor(QColor); + void setBorderSize(int); + void setDeviceParameters(struct device_settings *); + + +private slots: + +private: + + QColor SignalColor[MAX_CHNS], + BackgroundColor, + RasterColor, + TextColor; + + QFont smallfont; + + double v_sense; + + int bufsize, + bordersize, + tracewidth, + w, + h, + old_w, + chan_arrow_pos[MAX_CHNS], + trig_level_arrow_pos, + trig_pos_arrow_pos, + trig_pos_arrow_moving, + use_move_events, + mouse_x, + mouse_y, + mouse_old_x, + mouse_old_y; + + void drawArrow(QPainter *, int, int, int, QColor, char); + void drawSmallTriggerArrow(QPainter *, int, int, int, QColor); + void drawTrigCenterArrow(QPainter *, int, int); + void drawTopLabels(QPainter *); + void paintLabel(QPainter *, int, int, int, int, const char *, QColor); + void draw_decoder(QPainter *, int, int); + int ascii_decode_control_char(char, char *); + + struct device_settings *devparms; + + UI_wave_window *wavedialog; + +protected: + void paintEvent(QPaintEvent *); + void mousePressEvent(QMouseEvent *); + void mouseReleaseEvent(QMouseEvent *); + void mouseMoveEvent(QMouseEvent *); + +}; + + +#endif + +