mirror of https://github.com/EspoTek/Labrador.git
Sped up serial decode dramatically
Swapped an append to a replace with an ADT designed to return fast pointers to char[] blocks. Worked out that the one-corrupt-sample-per-packet bug was definitely not fixed. I must have been looking at a 1kHz wave before.
This commit is contained in:
parent
644359d1a2
commit
d3054d9707
|
@ -20,7 +20,8 @@ SOURCES += main.cpp\
|
|||
isobuffer.cpp \
|
||||
desktop_settings.cpp \
|
||||
scoperangeenterdialog.cpp \
|
||||
genericusbdriver.cpp
|
||||
genericusbdriver.cpp \
|
||||
isobufferbuffer.cpp
|
||||
|
||||
HEADERS += mainwindow.h \
|
||||
functiongencontrol.h \
|
||||
|
@ -29,7 +30,8 @@ HEADERS += mainwindow.h \
|
|||
isobuffer.h \
|
||||
desktop_settings.h \
|
||||
scoperangeenterdialog.h \
|
||||
genericusbdriver.h
|
||||
genericusbdriver.h \
|
||||
isobufferbuffer.h
|
||||
|
||||
FORMS += mainwindow.ui \
|
||||
scoperangeenterdialog.ui
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.1.0, 2016-11-28T18:20:47. -->
|
||||
<!-- Written by QtCreator 4.1.0, 2016-12-05T19:42:35. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Binary file not shown.
|
@ -25,11 +25,14 @@ extern double SERIAL_DELAY;
|
|||
|
||||
#define USB_RECONNECT_PERIOD 250
|
||||
|
||||
#define VALID_DATA_PER_375 375
|
||||
#define VALID_DATA_PER_375 374
|
||||
|
||||
#define VALID_DATA_PER_750 750
|
||||
|
||||
#define COLUMN_BREAK VALID_DATA_PER_750
|
||||
|
||||
//#define MAX_CONSOLE_BLOCK_COUNT 512
|
||||
#define SERIAL_BUFFER_LENGTH 8192
|
||||
|
||||
#endif // DESKTOP_SETTINGS_H
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "isodriver.h"
|
||||
|
||||
|
||||
isoBuffer::isoBuffer(int bufferLen, isoDriver *caller, unsigned char channel_value)
|
||||
isoBuffer::isoBuffer(QWidget *parent, int bufferLen, isoDriver *caller, unsigned char channel_value) : QWidget(parent)
|
||||
{
|
||||
buffer = (short *) calloc(bufferLen*2, sizeof(short));
|
||||
bufferEnd = bufferLen-1;
|
||||
|
@ -10,6 +10,14 @@ isoBuffer::isoBuffer(int bufferLen, isoDriver *caller, unsigned char channel_val
|
|||
samplesPerSecond = samplesPerSecond/375*VALID_DATA_PER_375;
|
||||
parent = caller;
|
||||
channel = channel_value;
|
||||
|
||||
updateTimer = new QTimer();
|
||||
updateTimer->setTimerType(Qt::PreciseTimer);
|
||||
updateTimer->start(CONSOLE_UPDATE_TIMER_PERIOD);
|
||||
connect(updateTimer, SIGNAL(timeout()), this, SLOT(updateConsole()));
|
||||
|
||||
serialBuffer = new isoBufferBuffer(SERIAL_BUFFER_LENGTH*2);
|
||||
|
||||
}
|
||||
void isoBuffer::openFile(QString newFile)
|
||||
{
|
||||
|
@ -179,7 +187,7 @@ void isoBuffer::serialDecode(double baudRate)
|
|||
tempChar = tempShort & (1 << serialPhase) ? 0 : 1;
|
||||
if(serialDecodingSymbol){
|
||||
//if((tempShort != 0) && (tempShort!= 255)) qDebug() << "tempShort = " << tempShort;
|
||||
qDebug() << numOnes(tempShort);
|
||||
//qDebug() << numOnes(tempShort);
|
||||
decodeSymbol(numOnes(tempShort) > 4);
|
||||
}
|
||||
else serialDecodingSymbol = (numOnes(tempShort) < 8);
|
||||
|
@ -204,15 +212,11 @@ void isoBuffer::serialBegin()
|
|||
void isoBuffer::decodeSymbol(unsigned char newBit) //Slow but works.
|
||||
{
|
||||
if(symbolCurrent == symbolMax){ //Last bit in symbol
|
||||
console -> insertPlainText(QString(QChar((char)symbol)));
|
||||
if(serialAutoScroll){
|
||||
//http://stackoverflow.com/questions/21059678/how-can-i-set-auto-scroll-for-a-qtgui-qtextedit-in-pyqt4 DANKON
|
||||
QTextCursor c = console->textCursor();
|
||||
c.movePosition(QTextCursor::End);
|
||||
console->setTextCursor(c);
|
||||
// txtedit.ensureCursorVisible(); // you might need this also
|
||||
}
|
||||
//charBuffer[charPos] = symbol;
|
||||
if(charPos<SERIAL_BUFFER_LENGTH) charPos++;
|
||||
serialBuffer->add(symbol);
|
||||
symbolCurrent++;
|
||||
symbolUpdated = true;
|
||||
return;
|
||||
}
|
||||
if(symbolCurrent > symbolMax){ //Wait for stop bit. Stops over the top calculation when you get a string of zeroes...
|
||||
|
@ -302,3 +306,19 @@ double isoBuffer::sampleConvert(short sample, int TOP, bool AC){
|
|||
return voltageLevel;
|
||||
}
|
||||
|
||||
void isoBuffer::updateConsole(){
|
||||
if(!symbolUpdated) return;
|
||||
qDebug() << charPos;
|
||||
|
||||
console -> setPlainText(QString::fromLocal8Bit(serialBuffer->get(charPos), charPos));
|
||||
if(serialAutoScroll){
|
||||
//http://stackoverflow.com/questions/21059678/how-can-i-set-auto-scroll-for-a-qtgui-qtextedit-in-pyqt4 DANKON
|
||||
QTextCursor c = console->textCursor();
|
||||
c.movePosition(QTextCursor::End);
|
||||
console->setTextCursor(c);
|
||||
// txtedit.ensureCursorVisible(); // you might need this also
|
||||
}
|
||||
symbolUpdated = false;
|
||||
//charPos = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef ISOBUFFER_H
|
||||
#define ISOBUFFER_H
|
||||
|
||||
#include <QWidget>
|
||||
#include <QString>
|
||||
#include <QByteArray>
|
||||
#include <QDebug>
|
||||
|
@ -11,16 +12,20 @@
|
|||
|
||||
#include "xmega.h"
|
||||
#include "desktop_settings.h"
|
||||
#include "isobufferbuffer.h"
|
||||
|
||||
class isoDriver;
|
||||
|
||||
//isoBuffer is a generic class that enables O(1) read times (!!!) on all read/write operations, while maintaining a huge buffer size.
|
||||
//Imagine it as a circular buffer, but with access functions specifically designed for isochronous data from an Xmega.
|
||||
|
||||
class isoBuffer
|
||||
#define CONSOLE_UPDATE_TIMER_PERIOD 60
|
||||
|
||||
class isoBuffer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
isoBuffer(int bufferLen, isoDriver *caller, unsigned char channel_value);
|
||||
isoBuffer(QWidget *parent = 0, int bufferLen = 0, isoDriver *caller = 0, unsigned char channel_value = 0);
|
||||
//Generic Functions
|
||||
void openFile(QString newFile);
|
||||
void writeBuffer_char(char *data, int len);
|
||||
|
@ -36,6 +41,7 @@ public:
|
|||
QPlainTextEdit *console, *console1, *console2;
|
||||
bool serialAutoScroll = true;
|
||||
unsigned char channel = 255;
|
||||
QTimer *updateTimer;
|
||||
private:
|
||||
//Generic Vars
|
||||
short *buffer, *readData = NULL;
|
||||
|
@ -50,10 +56,14 @@ private:
|
|||
unsigned int currentColumn = 0;
|
||||
//Serial Decode
|
||||
bool serialDecodingSymbol = false;
|
||||
char charBuffer[4096];
|
||||
unsigned int charPos = 0;
|
||||
unsigned char symbolMax = 7;
|
||||
unsigned char symbolCurrent = 0;
|
||||
unsigned short symbol = 0;
|
||||
char serialPhase = 0;
|
||||
isoBufferBuffer *serialBuffer;
|
||||
bool symbolUpdated = false;
|
||||
//Generic Functions
|
||||
void decodeSymbol(unsigned char newBit);
|
||||
void marchSerialPtr(int bitPeriod_samples);
|
||||
|
@ -62,7 +72,7 @@ private:
|
|||
public slots:
|
||||
void enableFileIO(QFile *file);
|
||||
void disableFileIO();
|
||||
|
||||
void updateConsole();
|
||||
};
|
||||
|
||||
#endif // ISOBUFFER_H
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#include "isobufferbuffer.h"
|
||||
|
||||
isoBufferBuffer::isoBufferBuffer(int length)
|
||||
{
|
||||
bufferLength = length;
|
||||
mid = length/2;
|
||||
buffer = (char *) malloc((length * 3) / 2);
|
||||
}
|
||||
|
||||
void isoBufferBuffer::add(char newChar){
|
||||
buffer[ptr] = newChar;
|
||||
if(ptr<mid){
|
||||
buffer[ptr+bufferLength] = newChar;
|
||||
}
|
||||
if (ptr >= bufferLength){
|
||||
ptr = 0;
|
||||
}
|
||||
else ptr++;
|
||||
}
|
||||
|
||||
char *isoBufferBuffer::get(int length){
|
||||
if (length>mid) qFatal("isoBuffer::get; length requested is too high.");
|
||||
if(ptr<mid) return &buffer[ptr+bufferLength - length];
|
||||
else return &buffer[ptr - length];
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef ISOBUFFERBUFFER_H
|
||||
#define ISOBUFFERBUFFER_H
|
||||
|
||||
//isobufferbuffer is a buffer designed for getting the last n things added in reverse order, in O(1) time.
|
||||
|
||||
#include <QDebug>
|
||||
#include <stdlib.h>
|
||||
|
||||
class isoBufferBuffer
|
||||
{
|
||||
public:
|
||||
isoBufferBuffer(int length);
|
||||
void add(char newChar);
|
||||
char *get(int length);
|
||||
private:
|
||||
int bufferLength;
|
||||
int mid;
|
||||
int ptr;
|
||||
char *buffer;
|
||||
};
|
||||
|
||||
#endif // ISOBUFFERBUFFER_H
|
|
@ -4,9 +4,9 @@
|
|||
isoDriver::isoDriver(QWidget *parent) : QLabel(parent)
|
||||
{
|
||||
this->hide();
|
||||
internalBuffer375_CH1 = new isoBuffer(MAX_WINDOW_SIZE*ADC_SPS/20*21, this, 1);
|
||||
internalBuffer375_CH2 = new isoBuffer(MAX_WINDOW_SIZE*ADC_SPS/20*21, this, 1);
|
||||
internalBuffer750 = new isoBuffer(MAX_WINDOW_SIZE*ADC_SPS/10*21, this, 1);
|
||||
internalBuffer375_CH1 = new isoBuffer(this, MAX_WINDOW_SIZE*ADC_SPS/20*21, this, 1);
|
||||
internalBuffer375_CH2 = new isoBuffer(this, MAX_WINDOW_SIZE*ADC_SPS/20*21, this, 1);
|
||||
internalBuffer750 = new isoBuffer(this, MAX_WINDOW_SIZE*ADC_SPS/10*21, this, 1);
|
||||
|
||||
isoTemp = (char *) malloc(TIMER_PERIOD*ADC_SPF + 8); //8-byte header contains (unsigned long) length
|
||||
|
||||
|
@ -47,7 +47,7 @@ void isoDriver::setWindow(int newWindow){
|
|||
}
|
||||
|
||||
void isoDriver::timerTick(void){
|
||||
qDebug() << "isoDriver SEZ Tick!";
|
||||
//qDebug() << "isoDriver SEZ Tick!";
|
||||
if(firstFrame){
|
||||
autoGain();
|
||||
firstFrame = false;
|
||||
|
|
|
@ -77,6 +77,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
connect(ui->controller_iso->driver, SIGNAL(killMe()), this, SLOT(reinitUsb()));
|
||||
#endif
|
||||
connect(ui->controller_iso->driver, SIGNAL(killMe()), this, SLOT(reinitUsb()));
|
||||
//ui->console1->setMaximumBlockCount(MAX_CONSOLE_BLOCK_COUNT);
|
||||
//ui->console2->setMaximumBlockCount(MAX_CONSOLE_BLOCK_COUNT);
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,132 @@
|
|||
/****************************************************************************
|
||||
** Meta object code from reading C++ file 'isobuffer.h'
|
||||
**
|
||||
** Created by: The Qt Meta Object Compiler version 67 (Qt 5.7.0)
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost!
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../isobuffer.h"
|
||||
#include <QtCore/qbytearray.h>
|
||||
#include <QtCore/qmetatype.h>
|
||||
#if !defined(Q_MOC_OUTPUT_REVISION)
|
||||
#error "The header file 'isobuffer.h' doesn't include <QObject>."
|
||||
#elif Q_MOC_OUTPUT_REVISION != 67
|
||||
#error "This file was generated using the moc from 5.7.0. It"
|
||||
#error "cannot be used with the include files from this version of Qt."
|
||||
#error "(The moc has changed too much.)"
|
||||
#endif
|
||||
|
||||
QT_BEGIN_MOC_NAMESPACE
|
||||
struct qt_meta_stringdata_isoBuffer_t {
|
||||
QByteArrayData data[7];
|
||||
char stringdata0[64];
|
||||
};
|
||||
#define QT_MOC_LITERAL(idx, ofs, len) \
|
||||
Q_STATIC_BYTE_ARRAY_DATA_HEADER_INITIALIZER_WITH_OFFSET(len, \
|
||||
qptrdiff(offsetof(qt_meta_stringdata_isoBuffer_t, stringdata0) + ofs \
|
||||
- idx * sizeof(QByteArrayData)) \
|
||||
)
|
||||
static const qt_meta_stringdata_isoBuffer_t qt_meta_stringdata_isoBuffer = {
|
||||
{
|
||||
QT_MOC_LITERAL(0, 0, 9), // "isoBuffer"
|
||||
QT_MOC_LITERAL(1, 10, 12), // "enableFileIO"
|
||||
QT_MOC_LITERAL(2, 23, 0), // ""
|
||||
QT_MOC_LITERAL(3, 24, 6), // "QFile*"
|
||||
QT_MOC_LITERAL(4, 31, 4), // "file"
|
||||
QT_MOC_LITERAL(5, 36, 13), // "disableFileIO"
|
||||
QT_MOC_LITERAL(6, 50, 13) // "updateConsole"
|
||||
|
||||
},
|
||||
"isoBuffer\0enableFileIO\0\0QFile*\0file\0"
|
||||
"disableFileIO\0updateConsole"
|
||||
};
|
||||
#undef QT_MOC_LITERAL
|
||||
|
||||
static const uint qt_meta_data_isoBuffer[] = {
|
||||
|
||||
// content:
|
||||
7, // revision
|
||||
0, // classname
|
||||
0, 0, // classinfo
|
||||
3, 14, // methods
|
||||
0, 0, // properties
|
||||
0, 0, // enums/sets
|
||||
0, 0, // constructors
|
||||
0, // flags
|
||||
0, // signalCount
|
||||
|
||||
// slots: name, argc, parameters, tag, flags
|
||||
1, 1, 29, 2, 0x0a /* Public */,
|
||||
5, 0, 32, 2, 0x0a /* Public */,
|
||||
6, 0, 33, 2, 0x0a /* Public */,
|
||||
|
||||
// slots: parameters
|
||||
QMetaType::Void, 0x80000000 | 3, 4,
|
||||
QMetaType::Void,
|
||||
QMetaType::Void,
|
||||
|
||||
0 // eod
|
||||
};
|
||||
|
||||
void isoBuffer::qt_static_metacall(QObject *_o, QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
isoBuffer *_t = static_cast<isoBuffer *>(_o);
|
||||
Q_UNUSED(_t)
|
||||
switch (_id) {
|
||||
case 0: _t->enableFileIO((*reinterpret_cast< QFile*(*)>(_a[1]))); break;
|
||||
case 1: _t->disableFileIO(); break;
|
||||
case 2: _t->updateConsole(); break;
|
||||
default: ;
|
||||
}
|
||||
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
|
||||
switch (_id) {
|
||||
default: *reinterpret_cast<int*>(_a[0]) = -1; break;
|
||||
case 0:
|
||||
switch (*reinterpret_cast<int*>(_a[1])) {
|
||||
default: *reinterpret_cast<int*>(_a[0]) = -1; break;
|
||||
case 0:
|
||||
*reinterpret_cast<int*>(_a[0]) = qRegisterMetaType< QFile* >(); break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const QMetaObject isoBuffer::staticMetaObject = {
|
||||
{ &QWidget::staticMetaObject, qt_meta_stringdata_isoBuffer.data,
|
||||
qt_meta_data_isoBuffer, qt_static_metacall, Q_NULLPTR, Q_NULLPTR}
|
||||
};
|
||||
|
||||
|
||||
const QMetaObject *isoBuffer::metaObject() const
|
||||
{
|
||||
return QObject::d_ptr->metaObject ? QObject::d_ptr->dynamicMetaObject() : &staticMetaObject;
|
||||
}
|
||||
|
||||
void *isoBuffer::qt_metacast(const char *_clname)
|
||||
{
|
||||
if (!_clname) return Q_NULLPTR;
|
||||
if (!strcmp(_clname, qt_meta_stringdata_isoBuffer.stringdata0))
|
||||
return static_cast<void*>(const_cast< isoBuffer*>(this));
|
||||
return QWidget::qt_metacast(_clname);
|
||||
}
|
||||
|
||||
int isoBuffer::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
|
||||
{
|
||||
_id = QWidget::qt_metacall(_c, _id, _a);
|
||||
if (_id < 0)
|
||||
return _id;
|
||||
if (_c == QMetaObject::InvokeMetaMethod) {
|
||||
if (_id < 3)
|
||||
qt_static_metacall(this, _c, _id, _a);
|
||||
_id -= 3;
|
||||
} else if (_c == QMetaObject::RegisterMethodArgumentMetaType) {
|
||||
if (_id < 3)
|
||||
qt_static_metacall(this, _c, _id, _a);
|
||||
_id -= 3;
|
||||
}
|
||||
return _id;
|
||||
}
|
||||
QT_END_MOC_NAMESPACE
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue