mirror of https://github.com/EspoTek/Labrador.git
Revert "Simplify the waveform reading code (#194)"
This reverts commit591940b225
. Revert "Whitespace cleanup (#192)" This reverts commit1b45b0d112
.
This commit is contained in:
parent
90bc17a2f0
commit
8cc740c6e1
|
@ -159,7 +159,7 @@ unix:!android:!macx{
|
|||
unix:!android:!macx:LIBS += -L$$PWD/build_linux/libdfuprog/lib/x64 -ldfuprog-0.9
|
||||
unix:!android:!macx:INCLUDEPATH += $$PWD/build_linux/libdfuprog/include
|
||||
unix:!android:!macx:DEPENDPATH += $$PWD/build_linux/libdfuprog/include
|
||||
lib_deploy.files = $$PWD/build_linux/libdfuprog/lib/x64/libdfuprog-0.9.so
|
||||
lib_deploy.files = $$PWD/build_linux/libdfuprog/lib/x64/libdfuprog-0.9.so
|
||||
lib_deploy.path = /usr/lib
|
||||
}
|
||||
}
|
||||
|
|
|
@ -295,3 +295,4 @@ int androidUsbDriver::flashFirmware(void){
|
|||
mainActivity.callMethod<void>("closeDevice");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -81,3 +81,4 @@ void daqForm::updateValues(){
|
|||
void daqForm::trigger_saveButtonPressed(){
|
||||
saveButtonPressed();
|
||||
}
|
||||
|
||||
|
|
|
@ -25,3 +25,4 @@ unsigned char expected_variant;
|
|||
#ifndef PLATFORM_WINDOWS
|
||||
struct timeval tv;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -47,3 +47,4 @@ extern unsigned char expected_variant;
|
|||
#define NUM_BYTES_STORED_PER_DAQ_SAMPLE 9
|
||||
|
||||
#endif // DESKTOP_SETTINGS_H
|
||||
|
||||
|
|
|
@ -4,101 +4,156 @@
|
|||
namespace functionGen {
|
||||
|
||||
ChannelData const& SingleChannelController::getData() const {
|
||||
return m_data;
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void SingleChannelController::waveformName(QString newName)
|
||||
{
|
||||
qDebug() << "newName = " << newName;
|
||||
newName.append(".tlw");
|
||||
|
||||
int length;
|
||||
|
||||
#ifdef PLATFORM_ANDROID
|
||||
QString path("assets:/waveforms/");
|
||||
QFile file(path.append(newName).append(".tlw"));
|
||||
#else
|
||||
QString path = QCoreApplication::applicationDirPath();
|
||||
QFile file(path.append("/waveforms/").append(newName).append(".tlw"));
|
||||
#endif
|
||||
QString waveformFilePath("assets:/waveforms/");
|
||||
waveformFilePath.append(newName);
|
||||
|
||||
qDebug() << "opening" << file.fileName();
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
qFatal("could not open %s", qUtf8Printable(file.fileName()));
|
||||
QFile fptr(waveformFilePath);
|
||||
bool success = fptr.open(QIODevice::ReadOnly);
|
||||
|
||||
int length = file.readLine().toInt();
|
||||
m_data.divisibility = file.readLine().toInt();
|
||||
QByteArray data = file.readLine().trimmed();
|
||||
file.close();
|
||||
QByteArray line;
|
||||
char lengthString[16];
|
||||
char divisibilityString[16];
|
||||
|
||||
line = fptr.readLine();
|
||||
strcpy(lengthString, line.data());
|
||||
sscanf(lengthString, "%d", &length);
|
||||
qDebug() << "lengthString" << lengthString;
|
||||
|
||||
line = fptr.readLine();
|
||||
strcpy(divisibilityString, line.data());
|
||||
sscanf(divisibilityString, "%d", &m_data.divisibility);
|
||||
qDebug() << "divisibilityString" << divisibilityString;
|
||||
|
||||
qDebug() << "Length = " << length;
|
||||
qDebug() << "Divisibility = " << m_data.divisibility;
|
||||
|
||||
// Length is redundant, could be derived from the sample list.
|
||||
if (length != data.count('\t') + 1)
|
||||
qFatal("%s: sample count mismatch", qUtf8Printable(file.fileName()));
|
||||
m_data.samples.resize(length);
|
||||
QByteArray remainingData = fptr.readAll();
|
||||
char *dataString = remainingData.data();
|
||||
|
||||
data.replace('\t', '\0');
|
||||
const char *dataString = data.constData();
|
||||
QByteArray dataElem;
|
||||
for (auto &sample : m_data.samples) {
|
||||
dataElem.setRawData(dataString, strlen(dataString));
|
||||
sample = static_cast<uint8_t>(dataElem.toInt());
|
||||
dataString += dataElem.size() + 1;
|
||||
m_data.samples.resize(length);
|
||||
|
||||
int dummy;
|
||||
char *dataStringCurrent = dataString;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
sscanf(dataStringCurrent, "%d", &dummy);
|
||||
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
||||
m_data.samples[i] = static_cast<uint8_t>(dummy);
|
||||
}
|
||||
|
||||
double newMaxFreq = DAC_SPS / (length >> (m_data.divisibility - 1));
|
||||
double newMinFreq = double(CLOCK_FREQ) / 1024.0 / 65535.0 / static_cast<double>(length);
|
||||
#else
|
||||
|
||||
setMaxFreq(newMaxFreq);
|
||||
setMinFreq(newMinFreq);
|
||||
QByteArray filePath = QCoreApplication::applicationDirPath()
|
||||
.append("/waveforms/").append(newName).toLocal8Bit();
|
||||
|
||||
qDebug() << "opening" << filePath;
|
||||
|
||||
FILE *fptr = fopen(filePath.constData(), "r");
|
||||
if (fptr == NULL)
|
||||
qFatal("%s could not be opened!", filePath.constData());
|
||||
|
||||
char lengthString[16];
|
||||
fgets(lengthString, 5, fptr);
|
||||
sscanf(lengthString, "%d", &length);
|
||||
|
||||
char divisibilityString[16];
|
||||
//Bit of bullshit to deal with CRLF line endings on Mac.
|
||||
do
|
||||
{
|
||||
fgets(divisibilityString, 5, fptr);
|
||||
}
|
||||
while ((divisibilityString[0] == '\r') || (divisibilityString[0] == '\n'));
|
||||
|
||||
sscanf(divisibilityString, "%d", &m_data.divisibility);
|
||||
|
||||
qDebug() << "Length = " << length;
|
||||
qDebug() << "Divisibility = " << m_data.divisibility;
|
||||
|
||||
m_data.samples.resize(length);
|
||||
|
||||
char *dataString = (char *) malloc(length*5+1);
|
||||
fgets(dataString, length*5+1, fptr);
|
||||
|
||||
int dummy;
|
||||
char *dataStringCurrent = dataString;
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
sscanf(dataStringCurrent, "%d", &dummy);
|
||||
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
||||
m_data.samples[i] = static_cast<uint8_t>(dummy);
|
||||
}
|
||||
|
||||
free(dataString);
|
||||
fclose(fptr);
|
||||
#endif
|
||||
|
||||
double newMaxFreq = DAC_SPS / (length >> (m_data.divisibility - 1));
|
||||
double newMinFreq = double(CLOCK_FREQ) / 1024.0 / 65535.0 / static_cast<double>(length);
|
||||
|
||||
setMaxFreq(newMaxFreq);
|
||||
setMinFreq(newMinFreq);
|
||||
|
||||
notifyUpdate(this);
|
||||
}
|
||||
|
||||
void SingleChannelController::freqUpdate(double newFreq)
|
||||
{
|
||||
qDebug() << "newFreq = " << newFreq;
|
||||
m_data.freq = newFreq;
|
||||
notifyUpdate(this);
|
||||
qDebug() << "newFreq = " << newFreq;
|
||||
m_data.freq = newFreq;
|
||||
notifyUpdate(this);
|
||||
}
|
||||
|
||||
void SingleChannelController::amplitudeUpdate(double newAmplitude)
|
||||
{
|
||||
qDebug() << "newAmplitude = " << newAmplitude;
|
||||
m_data.amplitude = newAmplitude;
|
||||
notifyUpdate(this);
|
||||
qDebug() << "newAmplitude = " << newAmplitude;
|
||||
m_data.amplitude = newAmplitude;
|
||||
notifyUpdate(this);
|
||||
}
|
||||
|
||||
void SingleChannelController::offsetUpdate(double newOffset)
|
||||
{
|
||||
qDebug() << "newOffset = " << newOffset;
|
||||
m_data.offset = newOffset;
|
||||
notifyUpdate(this);
|
||||
qDebug() << "newOffset = " << newOffset;
|
||||
m_data.offset = newOffset;
|
||||
notifyUpdate(this);
|
||||
}
|
||||
|
||||
|
||||
DualChannelController::DualChannelController(QWidget *parent) : QLabel(parent)
|
||||
{
|
||||
// A bunch of plumbing to forward the SingleChannelController's signals
|
||||
// A bunch of plumbing to forward the SingleChannelController's signals
|
||||
|
||||
SingleChannelController* controller1 = getChannelController(ChannelID::CH1);
|
||||
SingleChannelController* controller2 = getChannelController(ChannelID::CH2);
|
||||
SingleChannelController* controller1 = getChannelController(ChannelID::CH1);
|
||||
SingleChannelController* controller2 = getChannelController(ChannelID::CH2);
|
||||
|
||||
connect(controller1, &SingleChannelController::notifyUpdate,
|
||||
this, [=](SingleChannelController* ptr){ this->functionGenToUpdate(ChannelID::CH1, ptr); });
|
||||
connect(controller1, &SingleChannelController::notifyUpdate,
|
||||
this, [=](SingleChannelController* ptr){ this->functionGenToUpdate(ChannelID::CH1, ptr); });
|
||||
|
||||
connect(controller1, &SingleChannelController::setMaxFreq,
|
||||
this, &DualChannelController::setMaxFreq_CH1);
|
||||
connect(controller1, &SingleChannelController::setMaxFreq,
|
||||
this, &DualChannelController::setMaxFreq_CH1);
|
||||
|
||||
connect(controller1, &SingleChannelController::setMinFreq,
|
||||
this, &DualChannelController::setMinFreq_CH1);
|
||||
connect(controller1, &SingleChannelController::setMinFreq,
|
||||
this, &DualChannelController::setMinFreq_CH1);
|
||||
|
||||
|
||||
connect(controller2, &SingleChannelController::notifyUpdate,
|
||||
this, [=](SingleChannelController* ptr){ this->functionGenToUpdate(ChannelID::CH2, ptr); });
|
||||
connect(controller2, &SingleChannelController::notifyUpdate,
|
||||
this, [=](SingleChannelController* ptr){ this->functionGenToUpdate(ChannelID::CH2, ptr); });
|
||||
|
||||
connect(controller1, &SingleChannelController::setMaxFreq,
|
||||
this, &DualChannelController::setMaxFreq_CH2);
|
||||
connect(controller1, &SingleChannelController::setMaxFreq,
|
||||
this, &DualChannelController::setMaxFreq_CH2);
|
||||
|
||||
connect(controller1, &SingleChannelController::setMinFreq,
|
||||
this, &DualChannelController::setMinFreq_CH2);
|
||||
connect(controller1, &SingleChannelController::setMinFreq,
|
||||
this, &DualChannelController::setMinFreq_CH2);
|
||||
|
||||
this->hide();
|
||||
}
|
||||
|
@ -106,71 +161,72 @@ DualChannelController::DualChannelController(QWidget *parent) : QLabel(parent)
|
|||
|
||||
SingleChannelController* DualChannelController::getChannelController(ChannelID channelID)
|
||||
{
|
||||
return &m_channels[(int)channelID];
|
||||
return &m_channels[(int)channelID];
|
||||
}
|
||||
|
||||
// The rest of this file is just plumbing to forward slot calls to SingleChannelController's
|
||||
// Hopefuly it can be mostly removed eventually
|
||||
void DualChannelController::waveformName(ChannelID channelID, QString newName)
|
||||
{
|
||||
getChannelController(channelID)->waveformName(newName);
|
||||
getChannelController(channelID)->waveformName(newName);
|
||||
}
|
||||
|
||||
void DualChannelController::freqUpdate(ChannelID channelID, double newFreq)
|
||||
{
|
||||
getChannelController(channelID)->freqUpdate(newFreq);
|
||||
getChannelController(channelID)->freqUpdate(newFreq);
|
||||
}
|
||||
|
||||
void DualChannelController::amplitudeUpdate(ChannelID channelID, double newAmplitude)
|
||||
{
|
||||
getChannelController(channelID)->amplitudeUpdate(newAmplitude);
|
||||
getChannelController(channelID)->amplitudeUpdate(newAmplitude);
|
||||
}
|
||||
|
||||
void DualChannelController::offsetUpdate(ChannelID channelID, double newOffset)
|
||||
{
|
||||
getChannelController(channelID)->offsetUpdate(newOffset);
|
||||
getChannelController(channelID)->offsetUpdate(newOffset);
|
||||
}
|
||||
|
||||
|
||||
void DualChannelController::waveformName_CH1(QString newName)
|
||||
{
|
||||
waveformName(ChannelID::CH1, newName);
|
||||
waveformName(ChannelID::CH1, newName);
|
||||
}
|
||||
|
||||
void DualChannelController::freqUpdate_CH1(double newFreq)
|
||||
{
|
||||
freqUpdate(ChannelID::CH1, newFreq);
|
||||
freqUpdate(ChannelID::CH1, newFreq);
|
||||
}
|
||||
|
||||
void DualChannelController::amplitudeUpdate_CH1(double newAmplitude)
|
||||
{
|
||||
amplitudeUpdate(ChannelID::CH1, newAmplitude);
|
||||
amplitudeUpdate(ChannelID::CH1, newAmplitude);
|
||||
}
|
||||
|
||||
void DualChannelController::offsetUpdate_CH1(double newOffset)
|
||||
{
|
||||
offsetUpdate(ChannelID::CH1, newOffset);
|
||||
offsetUpdate(ChannelID::CH1, newOffset);
|
||||
}
|
||||
|
||||
|
||||
void DualChannelController::waveformName_CH2(QString newName)
|
||||
{
|
||||
waveformName(ChannelID::CH2, newName);
|
||||
waveformName(ChannelID::CH2, newName);
|
||||
}
|
||||
|
||||
void DualChannelController::freqUpdate_CH2(double newFreq)
|
||||
{
|
||||
freqUpdate(ChannelID::CH2, newFreq);
|
||||
freqUpdate(ChannelID::CH2, newFreq);
|
||||
}
|
||||
|
||||
void DualChannelController::amplitudeUpdate_CH2(double newAmplitude)
|
||||
{
|
||||
amplitudeUpdate(ChannelID::CH2, newAmplitude);
|
||||
amplitudeUpdate(ChannelID::CH2, newAmplitude);
|
||||
}
|
||||
|
||||
void DualChannelController::offsetUpdate_CH2(double newOffset)
|
||||
{
|
||||
offsetUpdate(ChannelID::CH2, newOffset);
|
||||
offsetUpdate(ChannelID::CH2, newOffset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -17,29 +17,29 @@ namespace functionGen {
|
|||
|
||||
enum class ChannelID
|
||||
{
|
||||
CH1 = 0,
|
||||
CH2 = 1
|
||||
CH1 = 0,
|
||||
CH2 = 1
|
||||
};
|
||||
|
||||
struct ChannelData
|
||||
{
|
||||
std::vector<uint8_t> samples;
|
||||
int divisibility;
|
||||
double freq = 1000.0;
|
||||
double amplitude = 0.0;
|
||||
double offset = 0.0;
|
||||
std::vector<uint8_t> samples;
|
||||
int divisibility;
|
||||
double freq = 1000.0;
|
||||
double amplitude = 0.0;
|
||||
double offset = 0.0;
|
||||
};
|
||||
|
||||
class SingleChannelController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChannelData const& getData() const;
|
||||
ChannelData const& getData() const;
|
||||
|
||||
signals:
|
||||
void notifyUpdate(SingleChannelController* controller);
|
||||
void setMaxFreq(double maxFreq);
|
||||
void setMaxFreq(double maxFreq);
|
||||
void setMinFreq(double minFreq);
|
||||
|
||||
public slots:
|
||||
|
@ -49,7 +49,7 @@ public slots:
|
|||
void offsetUpdate(double newOffset);
|
||||
|
||||
private:
|
||||
ChannelData m_data;
|
||||
ChannelData m_data;
|
||||
};
|
||||
|
||||
class DualChannelController : public QLabel
|
||||
|
@ -59,7 +59,7 @@ public:
|
|||
explicit DualChannelController(QWidget *parent = 0);
|
||||
|
||||
public:
|
||||
SingleChannelController* getChannelController(ChannelID channelID);
|
||||
SingleChannelController* getChannelController(ChannelID channelID);
|
||||
|
||||
signals:
|
||||
void functionGenToUpdate(ChannelID channel, SingleChannelController* fGenControl);
|
||||
|
@ -85,7 +85,7 @@ public slots:
|
|||
void offsetUpdate_CH2(double newOffset);
|
||||
|
||||
private:
|
||||
SingleChannelController m_channels[2];
|
||||
SingleChannelController m_channels[2];
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -81,29 +81,29 @@ genericUsbDriver::genericUsbDriver(QWidget *parent) : QLabel(parent)
|
|||
connectTimer->start(USB_RECONNECT_PERIOD);
|
||||
connect(connectTimer, SIGNAL(timeout()), this, SLOT(checkConnection()));
|
||||
qDebug()<< "Generic Usb Driver setup complete";
|
||||
messageBox = new QMessageBox();
|
||||
messageBox = new QMessageBox();
|
||||
}
|
||||
|
||||
genericUsbDriver::~genericUsbDriver(void){
|
||||
qDebug() << "genericUsbDriver dectructor entering";
|
||||
if(connected){
|
||||
if (psuTimer)
|
||||
{
|
||||
psuTimer->stop();
|
||||
delete(psuTimer);
|
||||
}
|
||||
if (psuTimer)
|
||||
{
|
||||
psuTimer->stop();
|
||||
delete(psuTimer);
|
||||
}
|
||||
|
||||
if (recoveryTimer)
|
||||
{
|
||||
recoveryTimer->stop();
|
||||
delete(recoveryTimer);
|
||||
}
|
||||
if (recoveryTimer)
|
||||
{
|
||||
recoveryTimer->stop();
|
||||
delete(recoveryTimer);
|
||||
}
|
||||
|
||||
if (isoTimer)
|
||||
{
|
||||
isoTimer->stop();
|
||||
delete(isoTimer);
|
||||
}
|
||||
if (isoTimer)
|
||||
{
|
||||
isoTimer->stop();
|
||||
delete(isoTimer);
|
||||
}
|
||||
}
|
||||
qDebug() << "genericUsbDriver dectructor completed";
|
||||
}
|
||||
|
@ -136,33 +136,33 @@ void genericUsbDriver::setFunctionGen(functionGen::ChannelID channelID, function
|
|||
//////////////////////////////////////
|
||||
|
||||
//For recalling on crash.
|
||||
fGenPtrData[(int)channelID] = fGenControl;
|
||||
fGenPtrData[(int)channelID] = fGenControl;
|
||||
|
||||
sendFunctionGenData(channelID);
|
||||
sendFunctionGenData(channelID);
|
||||
}
|
||||
|
||||
void genericUsbDriver::sendFunctionGenData(functionGen::ChannelID channelID)
|
||||
{
|
||||
//Reading in data
|
||||
functionGen::ChannelData channelData = fGenPtrData[(int)channelID]->getData();
|
||||
functionGen::ChannelData channelData = fGenPtrData[(int)channelID]->getData();
|
||||
|
||||
//Triple mode
|
||||
if ((channelData.amplitude + channelData.offset) > FGEN_LIMIT)
|
||||
{
|
||||
{
|
||||
channelData.amplitude /= 3.0;
|
||||
channelData.offset /= 3.0;
|
||||
fGenTriple |= static_cast<uint8_t>(!static_cast<uint8_t>(channelID) + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fGenTriple &= static_cast<uint8_t>(254 - !static_cast<uint8_t>(channelID));
|
||||
}
|
||||
{
|
||||
fGenTriple &= static_cast<uint8_t>(254 - !static_cast<uint8_t>(channelID));
|
||||
}
|
||||
|
||||
//Waveform scaling in V
|
||||
channelData.amplitude = (channelData.amplitude * 255) / FGEN_LIMIT;
|
||||
channelData.offset = (channelData.offset * 255) / FGEN_LIMIT;
|
||||
if (channelData.offset < FGEN_OFFSET)
|
||||
{
|
||||
{
|
||||
if (channelData.amplitude > 5)
|
||||
channelData.amplitude -= FGEN_OFFSET;
|
||||
else
|
||||
|
@ -179,61 +179,62 @@ void genericUsbDriver::sendFunctionGenData(functionGen::ChannelID channelID)
|
|||
usbSendControl(0x40, 0xa4, fGenTriple, 0, 0, NULL);
|
||||
#endif
|
||||
|
||||
auto applyAmplitudeAndOffset = [&](unsigned char sample) -> unsigned char
|
||||
{
|
||||
return sample / 255.0 * channelData.amplitude + channelData.offset;
|
||||
};
|
||||
auto applyAmplitudeAndOffset = [&](unsigned char sample) -> unsigned char
|
||||
{
|
||||
return sample / 255.0 * channelData.amplitude + channelData.offset;
|
||||
};
|
||||
|
||||
std::transform(channelData.samples.begin(), channelData.samples.end(),
|
||||
channelData.samples.begin(), // transform in place
|
||||
applyAmplitudeAndOffset);
|
||||
std::transform(channelData.samples.begin(), channelData.samples.end(),
|
||||
channelData.samples.begin(), // transform in place
|
||||
applyAmplitudeAndOffset);
|
||||
|
||||
//Need to increase size of wave if its freq too high, or too low!
|
||||
{
|
||||
int shift = 0;
|
||||
int newLength = channelData.samples.size();
|
||||
{
|
||||
int shift = 0;
|
||||
int newLength = channelData.samples.size();
|
||||
|
||||
while ((newLength >> shift) * channelData.freq > DAC_SPS)
|
||||
shift++;
|
||||
while ((newLength >> shift) * channelData.freq > DAC_SPS)
|
||||
shift++;
|
||||
|
||||
if (shift != 0)
|
||||
{
|
||||
channelData.divisibility -= shift;
|
||||
newLength >>= shift;
|
||||
if (shift != 0)
|
||||
{
|
||||
channelData.divisibility -= shift;
|
||||
newLength >>= shift;
|
||||
|
||||
for (int i = 0; i < newLength; ++i)
|
||||
channelData.samples[i] = channelData.samples[i << shift];
|
||||
for (int i = 0; i < newLength; ++i)
|
||||
channelData.samples[i] = channelData.samples[i << shift];
|
||||
|
||||
channelData.samples.resize(newLength);
|
||||
channelData.samples.shrink_to_fit();
|
||||
channelData.samples.resize(newLength);
|
||||
channelData.samples.shrink_to_fit();
|
||||
|
||||
if (channelData.divisibility <= 0)
|
||||
qDebug("genericUsbDriver::setFunctionGen: channel divisibility <= 0 after T-stretching");
|
||||
}
|
||||
}
|
||||
if (channelData.divisibility <= 0)
|
||||
qDebug("genericUsbDriver::setFunctionGen: channel divisibility <= 0 after T-stretching");
|
||||
}
|
||||
}
|
||||
|
||||
// Timer Setup
|
||||
int validClockDivs[7] = {1, 2, 4, 8, 64, 256, 1024};
|
||||
auto period = [&](int division) -> int
|
||||
{
|
||||
return CLOCK_FREQ / (division * channelData.samples.size() * channelData.freq);
|
||||
};
|
||||
auto period = [&](int division) -> int
|
||||
{
|
||||
return CLOCK_FREQ / (division * channelData.samples.size() * channelData.freq);
|
||||
};
|
||||
|
||||
int* clkSettingIt = std::find_if(std::begin(validClockDivs), std::end(validClockDivs),
|
||||
[&](int division) -> bool { return period(division) < 65535; });
|
||||
int* clkSettingIt = std::find_if(std::begin(validClockDivs), std::end(validClockDivs),
|
||||
[&](int division) -> bool { return period(division) < 65535; });
|
||||
|
||||
int timerPeriod = period(*clkSettingIt);
|
||||
|
||||
// +1 to change from [0:n) to [1:n]
|
||||
// +1 to change from [0:n) to [1:n]
|
||||
int clkSetting = std::distance(std::begin(validClockDivs), clkSettingIt) + 1;
|
||||
|
||||
if(deviceMode == 5)
|
||||
qDebug("DEVICE IS IN MODE 5");
|
||||
|
||||
|
||||
if (channelID == functionGen::ChannelID::CH2)
|
||||
usbSendControl(0x40, 0xa1, timerPeriod, clkSetting, channelData.samples.size(), channelData.samples.data());
|
||||
usbSendControl(0x40, 0xa1, timerPeriod, clkSetting, channelData.samples.size(), channelData.samples.data());
|
||||
else
|
||||
usbSendControl(0x40, 0xa2, timerPeriod, clkSetting, channelData.samples.size(), channelData.samples.data());
|
||||
usbSendControl(0x40, 0xa2, timerPeriod, clkSetting, channelData.samples.size(), channelData.samples.data());
|
||||
|
||||
return;
|
||||
|
||||
|
@ -257,10 +258,10 @@ void genericUsbDriver::setDeviceMode(int mode){
|
|||
usbSendControl(0x40, 0xa5, (mode == 5 ? 0 : mode), gainMask, 0, NULL);
|
||||
|
||||
if (fGenPtrData[(int)functionGen::ChannelID::CH1] != NULL)
|
||||
sendFunctionGenData(functionGen::ChannelID::CH1);
|
||||
sendFunctionGenData(functionGen::ChannelID::CH1);
|
||||
|
||||
if (fGenPtrData[(int)functionGen::ChannelID::CH2] != NULL)
|
||||
sendFunctionGenData(functionGen::ChannelID::CH2);
|
||||
if (fGenPtrData[(int)functionGen::ChannelID::CH2] != NULL)
|
||||
sendFunctionGenData(functionGen::ChannelID::CH2);
|
||||
|
||||
//switch on new deviceMode!!
|
||||
switch(deviceMode){
|
||||
|
@ -486,11 +487,11 @@ void genericUsbDriver::checkConnection(){
|
|||
newDig(digitalPinState);
|
||||
|
||||
int ret = usbIsoInit();
|
||||
if (ret != 0)
|
||||
{
|
||||
if (ret != 0)
|
||||
{
|
||||
messageBox->setText("A USB connection was established, but isochronous communications could not be initialised.<br>This is usually due to bandwidth limitations on the current USB host and can be fixed by moving to a different port.<br>Please see <a href = 'https://github.com/EspoTek/Labrador/wiki/Troubleshooting-Guide#usb-connection-issues-other-platforms'>https://github.com/EspoTek/Labrador/wiki/Troubleshooting-Guide#usb-connection-issues-other-platforms</a>");
|
||||
messageBox->exec();
|
||||
}
|
||||
}
|
||||
|
||||
psuTimer = new QTimer();
|
||||
psuTimer->setTimerType(Qt::PreciseTimer);
|
||||
|
@ -513,3 +514,4 @@ void genericUsbDriver::checkConnection(){
|
|||
void genericUsbDriver::bootloaderJump(){
|
||||
usbSendControl(0x40, 0xa7, 1, 0, 0, NULL);
|
||||
}
|
||||
|
||||
|
|
|
@ -83,7 +83,7 @@ protected:
|
|||
//State Vars
|
||||
unsigned char fGenTriple=0;
|
||||
unsigned short gainMask = 2056;
|
||||
functionGen::SingleChannelController* fGenPtrData[2] = {NULL, NULL};
|
||||
functionGen::SingleChannelController* fGenPtrData[2] = {NULL, NULL};
|
||||
int dutyPsu = 0;
|
||||
double currentPsuVoltage;
|
||||
int digitalPinState = 0;
|
||||
|
@ -124,7 +124,7 @@ signals:
|
|||
public slots:
|
||||
void setPsu(double voltage);
|
||||
void setFunctionGen(functionGen::ChannelID channelID, functionGen::SingleChannelController *fGenControl);
|
||||
void sendFunctionGenData(functionGen::ChannelID channelID);
|
||||
void sendFunctionGenData(functionGen::ChannelID channelID);
|
||||
void setDeviceMode(int mode);
|
||||
void newDig(int digState);
|
||||
void psuTick(void);
|
||||
|
|
|
@ -48,13 +48,13 @@ void i2cDecoder::run()
|
|||
{
|
||||
// qDebug() << "i2cDecoder::run()";
|
||||
while (serialDistance(sda) > SERIAL_DELAY * sda->m_sampleRate_bit)
|
||||
{
|
||||
updateBitValues();
|
||||
runStateMachine();
|
||||
serialPtr_bit ++;
|
||||
{
|
||||
updateBitValues();
|
||||
runStateMachine();
|
||||
serialPtr_bit ++;
|
||||
if (serialPtr_bit >= (sda->m_bufferLen * 8))
|
||||
serialPtr_bit -= (sda->m_bufferLen * 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int i2cDecoder::serialDistance(isoBuffer* buffer)
|
||||
|
@ -64,7 +64,7 @@ int i2cDecoder::serialDistance(isoBuffer* buffer)
|
|||
if (back_bit >= serialPtr_bit)
|
||||
return back_bit - serialPtr_bit;
|
||||
else
|
||||
return bufferEnd_bit - serialPtr_bit + back_bit;
|
||||
return bufferEnd_bit - serialPtr_bit + back_bit;
|
||||
}
|
||||
|
||||
void i2cDecoder::updateBitValues(){
|
||||
|
@ -77,66 +77,66 @@ void i2cDecoder::updateBitValues(){
|
|||
unsigned char dataByteScl = scl->m_buffer[coord_byte];
|
||||
unsigned char mask = (0x01 << coord_bit);
|
||||
currentSdaValue = dataByteSda & mask;
|
||||
currentSclValue = dataByteScl & mask;
|
||||
currentSclValue = dataByteScl & mask;
|
||||
}
|
||||
|
||||
void i2cDecoder::runStateMachine()
|
||||
{
|
||||
edge sdaEdge = edgeDetection(currentSdaValue, previousSdaValue);
|
||||
edge sclEdge = edgeDetection(currentSclValue, previousSclValue);
|
||||
edge sclEdge = edgeDetection(currentSclValue, previousSclValue);
|
||||
|
||||
if ((sdaEdge == edge::rising) && (sclEdge == edge::falling)) // INVALID STATE TRANSITION
|
||||
{
|
||||
if ((sdaEdge == edge::rising) && (sclEdge == edge::falling)) // INVALID STATE TRANSITION
|
||||
{
|
||||
state = transmissionState::unknown;
|
||||
qDebug() << "Dumping I2C state and aborting...";
|
||||
for (int i=31; i>=0; i--)
|
||||
qDebug("%02x\t%02x", sda->m_buffer[serialPtr_bit/8 - i] & 0xFF, scl->m_buffer[serialPtr_bit/8 - i] & 0xFF);
|
||||
throw std::runtime_error("unknown i2c transmission state");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if ((sdaEdge == edge::rising) && (sclEdge == edge::held_high)) // START
|
||||
{
|
||||
if ((sdaEdge == edge::rising) && (sclEdge == edge::held_high)) // START
|
||||
{
|
||||
stopCondition();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sdaEdge == edge::falling) && (sclEdge == edge::held_high)) // STOP
|
||||
{
|
||||
if ((sdaEdge == edge::falling) && (sclEdge == edge::held_high)) // STOP
|
||||
{
|
||||
startCondition();
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case transmissionState::idle:
|
||||
return;
|
||||
case transmissionState::address:
|
||||
decodeAddress(sdaEdge, sclEdge);
|
||||
break;
|
||||
case transmissionState::data:
|
||||
decodeData(sdaEdge, sclEdge);
|
||||
break;
|
||||
}
|
||||
switch (state)
|
||||
{
|
||||
case transmissionState::idle:
|
||||
return;
|
||||
case transmissionState::address:
|
||||
decodeAddress(sdaEdge, sclEdge);
|
||||
break;
|
||||
case transmissionState::data:
|
||||
decodeData(sdaEdge, sclEdge);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
edge i2cDecoder::edgeDetection(uint8_t current, uint8_t prev)
|
||||
{
|
||||
if (current && prev)
|
||||
return edge::held_high;
|
||||
if (!current && !prev)
|
||||
return edge::held_low;
|
||||
if (current && !prev)
|
||||
return edge::rising;
|
||||
if (current && prev)
|
||||
return edge::held_high;
|
||||
if (!current && !prev)
|
||||
return edge::held_low;
|
||||
if (current && !prev)
|
||||
return edge::rising;
|
||||
if (!current && prev)
|
||||
return edge::falling;
|
||||
return edge::falling;
|
||||
|
||||
throw std::runtime_error("i2c Edge Detection critical failure");
|
||||
}
|
||||
|
||||
void i2cDecoder::decodeAddress(edge sdaEdge, edge sclEdge)
|
||||
{
|
||||
// Read in the next bit.
|
||||
// Read in the next bit.
|
||||
if (sclEdge == edge::rising && sdaEdge == edge::held_high && currentBitIndex++ < addressBitStreamLength)
|
||||
currentBitStream = (currentBitStream << 1) | 0x0001;
|
||||
else if (sclEdge == edge::rising && sdaEdge == edge::held_low && currentBitIndex++ < addressBitStreamLength)
|
||||
|
@ -197,9 +197,9 @@ void i2cDecoder::decodeData(edge sdaEdge, edge sclEdge)
|
|||
|
||||
void i2cDecoder::startCondition()
|
||||
{
|
||||
currentBitIndex = 0;
|
||||
currentBitIndex = 0;
|
||||
currentBitStream = 0x0000;
|
||||
state = transmissionState::address;
|
||||
state = transmissionState::address;
|
||||
qDebug() << "I2C START";
|
||||
}
|
||||
|
||||
|
|
|
@ -13,18 +13,18 @@ namespace i2c
|
|||
|
||||
enum class transmissionState: uint8_t
|
||||
{
|
||||
unknown,
|
||||
idle,
|
||||
address,
|
||||
data
|
||||
unknown,
|
||||
idle,
|
||||
address,
|
||||
data
|
||||
};
|
||||
|
||||
enum class edge: uint8_t
|
||||
{
|
||||
rising,
|
||||
falling,
|
||||
held_high,
|
||||
held_low
|
||||
rising,
|
||||
falling,
|
||||
held_high,
|
||||
held_low
|
||||
};
|
||||
|
||||
constexpr uint8_t addressBitStreamLength = 9;
|
||||
|
@ -37,37 +37,37 @@ class i2cDecoder : public QObject
|
|||
public:
|
||||
explicit i2cDecoder(isoBuffer* sda_in, isoBuffer* scl_in, QPlainTextEdit* console_in);
|
||||
~i2cDecoder();
|
||||
// misc
|
||||
// misc
|
||||
isoBuffer* sda;
|
||||
isoBuffer* scl;
|
||||
isoBuffer* scl;
|
||||
QPlainTextEdit* console;
|
||||
isoBufferBuffer* serialBuffer = nullptr;
|
||||
std::mutex mutex;
|
||||
QTimer *updateTimer;
|
||||
|
||||
// State vars
|
||||
uint8_t currentSdaValue = 0;
|
||||
uint8_t previousSdaValue = 0;
|
||||
uint8_t currentSclValue = 0;
|
||||
uint8_t previousSclValue = 0;
|
||||
// State vars
|
||||
uint8_t currentSdaValue = 0;
|
||||
uint8_t previousSdaValue = 0;
|
||||
uint8_t currentSclValue = 0;
|
||||
uint8_t previousSclValue = 0;
|
||||
uint64_t serialPtr_bit = 0;
|
||||
transmissionState state = transmissionState::unknown;
|
||||
transmissionState state = transmissionState::unknown;
|
||||
bool consoleStateInvalid;
|
||||
|
||||
// Data Transmission
|
||||
uint8_t currentBitIndex = 0;
|
||||
// Data Transmission
|
||||
uint8_t currentBitIndex = 0;
|
||||
uint16_t currentBitStream;
|
||||
|
||||
// Member functions
|
||||
void updateBitValues();
|
||||
void runStateMachine();
|
||||
// Member functions
|
||||
void updateBitValues();
|
||||
void runStateMachine();
|
||||
void run();
|
||||
int serialDistance(isoBuffer* buffer);
|
||||
edge edgeDetection(uint8_t current, uint8_t prev);
|
||||
void decodeAddress(edge sdaEdge, edge sclEdge);
|
||||
void decodeData(edge sdaEdge, edge sclEdge);
|
||||
void startCondition();
|
||||
void stopCondition();
|
||||
edge edgeDetection(uint8_t current, uint8_t prev);
|
||||
void decodeAddress(edge sdaEdge, edge sclEdge);
|
||||
void decodeData(edge sdaEdge, edge sclEdge);
|
||||
void startCondition();
|
||||
void stopCondition();
|
||||
void reset();
|
||||
signals:
|
||||
public slots:
|
||||
|
|
|
@ -350,7 +350,7 @@ void isoBuffer::serialManage(double baudRate, UartParity parity, bool hexDisplay
|
|||
m_isDecoding = true;
|
||||
}
|
||||
|
||||
m_decoder->m_baudRate = baudRate;
|
||||
m_decoder->m_baudRate = baudRate;
|
||||
m_decoder->setParityMode(parity);
|
||||
m_decoder->setHexDisplay(hexDisplay);
|
||||
m_decoder->serialDecode();
|
||||
|
|
|
@ -46,43 +46,43 @@ constexpr uint32_t CONSOLE_UPDATE_TIMER_PERIOD = ISO_PACKETS_PER_CTX * 4;
|
|||
// TODO: Change integer types to cstdint types
|
||||
class isoBuffer : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_OBJECT
|
||||
public:
|
||||
isoBuffer(QWidget* parent = 0, int bufferLen = 0, isoDriver* caller = 0, unsigned char channel_value = 0);
|
||||
~isoBuffer() = default;
|
||||
isoBuffer(QWidget* parent = 0, int bufferLen = 0, isoDriver* caller = 0, unsigned char channel_value = 0);
|
||||
~isoBuffer() = default;
|
||||
|
||||
// Basic buffer operations
|
||||
short bufferAt(uint32_t idx) const;
|
||||
void insertIntoBuffer(short item);
|
||||
void clearBuffer();
|
||||
void gainBuffer(int gain_log);
|
||||
// Basic buffer operations
|
||||
short bufferAt(uint32_t idx) const;
|
||||
void insertIntoBuffer(short item);
|
||||
void clearBuffer();
|
||||
void gainBuffer(int gain_log);
|
||||
|
||||
// Advanced buffer operations
|
||||
private:
|
||||
template<typename T, typename Function>
|
||||
void writeBuffer(T* data, int len, int TOP, Function transform);
|
||||
public:
|
||||
void writeBuffer_char(char* data, int len);
|
||||
void writeBuffer_short(short* data, int len);
|
||||
void writeBuffer_char(char* data, int len);
|
||||
void writeBuffer_short(short* data, int len);
|
||||
|
||||
std::unique_ptr<short[]> readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset);
|
||||
// file I/O
|
||||
std::unique_ptr<short[]> readBuffer(double sampleWindow, int numSamples, bool singleBit, double delayOffset);
|
||||
// file I/O
|
||||
private:
|
||||
void outputSampleToFile(double averageSample);
|
||||
void maybeOutputSampleToFile(double convertedSample);
|
||||
void outputSampleToFile(double averageSample);
|
||||
void maybeOutputSampleToFile(double convertedSample);
|
||||
public:
|
||||
double sampleConvert(short sample, int TOP, bool AC) const;
|
||||
short inverseSampleConvert(double voltageLevel, int TOP, bool AC) const;
|
||||
double sampleConvert(short sample, int TOP, bool AC) const;
|
||||
short inverseSampleConvert(double voltageLevel, int TOP, bool AC) const;
|
||||
|
||||
private:
|
||||
template<typename Function>
|
||||
int capSample(int offset, int target, double seconds, double value, Function comp);
|
||||
template<typename Function>
|
||||
int capSample(int offset, int target, double seconds, double value, Function comp);
|
||||
void checkTriggered();
|
||||
public:
|
||||
int cap_x0fromLast(double seconds, double vbot);
|
||||
int cap_x1fromLast(double seconds, int x0, double vbot);
|
||||
int cap_x2fromLast(double seconds, int x1, double vtop);
|
||||
void serialManage(double baudRate, UartParity parity, bool hexDisplay);
|
||||
int cap_x0fromLast(double seconds, double vbot);
|
||||
int cap_x1fromLast(double seconds, int x0, double vbot);
|
||||
int cap_x2fromLast(double seconds, int x1, double vtop);
|
||||
void serialManage(double baudRate, UartParity parity, bool hexDisplay);
|
||||
void setTriggerType(TriggerType newType);
|
||||
void setTriggerLevel(double voltageLevel, uint16_t top, bool acCoupled);
|
||||
double getDelayedTriggerPoint(double delay);
|
||||
|
@ -90,56 +90,56 @@ public:
|
|||
|
||||
// ---- MEMBER VARIABLES ----
|
||||
|
||||
// Presentation?
|
||||
// Presentation?
|
||||
// TODO: Add consoles as constructor arguments
|
||||
// NOTE: These are initialized in mainwindow.cpp
|
||||
QPlainTextEdit* m_console1;
|
||||
QPlainTextEdit* m_console2;
|
||||
unsigned char m_channel = 255;
|
||||
bool m_serialAutoScroll = true;
|
||||
QPlainTextEdit* m_console1;
|
||||
QPlainTextEdit* m_console2;
|
||||
unsigned char m_channel = 255;
|
||||
bool m_serialAutoScroll = true;
|
||||
|
||||
// Internal Storage
|
||||
// Internal Storage
|
||||
std::unique_ptr<short[]> m_bufferPtr;
|
||||
short* m_buffer;
|
||||
uint32_t m_back = 0;
|
||||
uint32_t m_insertedCount = 0;
|
||||
uint32_t m_bufferLen;
|
||||
uint32_t m_back = 0;
|
||||
uint32_t m_insertedCount = 0;
|
||||
uint32_t m_bufferLen;
|
||||
|
||||
// Conversion And Sampling
|
||||
double m_voltage_ref = 1.65;
|
||||
double m_frontendGain = (R4 / (R3 + R4));
|
||||
int m_samplesPerSecond;
|
||||
int m_sampleRate_bit;
|
||||
double m_voltage_ref = 1.65;
|
||||
double m_frontendGain = (R4 / (R3 + R4));
|
||||
int m_samplesPerSecond;
|
||||
int m_sampleRate_bit;
|
||||
TriggerType m_triggerType = TriggerType::Disabled;
|
||||
TriggerSeekState m_triggerSeekState = TriggerSeekState::BelowTriggerLevel;
|
||||
short m_triggerLevel = 0;
|
||||
short m_triggerSensitivity = 0;
|
||||
std::vector<uint32_t> m_triggerPositionList = {};
|
||||
// UARTS decoding
|
||||
uartStyleDecoder* m_decoder = NULL;
|
||||
bool m_isDecoding = true;
|
||||
// DFT
|
||||
// UARTS decoding
|
||||
uartStyleDecoder* m_decoder = NULL;
|
||||
bool m_isDecoding = true;
|
||||
//DFT
|
||||
AsyncDFT async_dft;
|
||||
private:
|
||||
// File I/O
|
||||
bool m_fileIOEnabled = false;
|
||||
QFile* m_currentFile;
|
||||
int m_fileIO_sampleCountPerWrite;
|
||||
int m_fileIO_sampleCount;
|
||||
double m_fileIO_sampleAccumulator;
|
||||
qulonglong m_fileIO_maxFileSize;
|
||||
qulonglong m_fileIO_numBytesWritten;
|
||||
unsigned int m_currentColumn = 0;
|
||||
// File I/O
|
||||
bool m_fileIOEnabled = false;
|
||||
QFile* m_currentFile;
|
||||
int m_fileIO_sampleCountPerWrite;
|
||||
int m_fileIO_sampleCount;
|
||||
double m_fileIO_sampleAccumulator;
|
||||
qulonglong m_fileIO_maxFileSize;
|
||||
qulonglong m_fileIO_numBytesWritten;
|
||||
unsigned int m_currentColumn = 0;
|
||||
uint32_t m_lastTriggerDetlaT = 0;
|
||||
|
||||
isoDriver* m_virtualParent;
|
||||
isoDriver* m_virtualParent;
|
||||
|
||||
void addTriggerPosition(uint32_t position);
|
||||
signals:
|
||||
void fileIOinternalDisable();
|
||||
void fileIOinternalDisable();
|
||||
public slots:
|
||||
void enableFileIO(QFile* file, int samplesToAverage, qulonglong max_file_size);
|
||||
void disableFileIO();
|
||||
void enableFileIO(QFile* file, int samplesToAverage, qulonglong max_file_size);
|
||||
void disableFileIO();
|
||||
};
|
||||
|
||||
#endif // ISOBUFFER_H
|
||||
|
|
|
@ -79,3 +79,4 @@ void isoBuffer_file::clearBuffer()
|
|||
|
||||
back = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -23,78 +23,80 @@
|
|||
*/
|
||||
|
||||
isoBufferBuffer::isoBufferBuffer(uint32_t length)
|
||||
: m_data(std::make_unique<char[]>(length*2))
|
||||
, m_capacity(length)
|
||||
: m_data(std::make_unique<char[]>(length*2))
|
||||
, m_capacity(length)
|
||||
{
|
||||
}
|
||||
|
||||
// Adds a character to the end of the buffer
|
||||
void isoBufferBuffer::insert(char c)
|
||||
{
|
||||
char* dataPtr = m_data.get();
|
||||
char* dataPtr = m_data.get();
|
||||
|
||||
// Add character to first half of the buffer
|
||||
dataPtr[m_top] = c;
|
||||
// Then to the second
|
||||
dataPtr[m_top+m_capacity] = c;
|
||||
// Add character to first half of the buffer
|
||||
dataPtr[m_top] = c;
|
||||
// Then to the second
|
||||
dataPtr[m_top+m_capacity] = c;
|
||||
|
||||
// Loop the buffer index if necessary and update size accordingly
|
||||
m_top = (m_top + 1) % m_capacity;
|
||||
m_size = std::min(m_size + 1, m_capacity);
|
||||
// Loop the buffer index if necessary and update size accordingly
|
||||
m_top = (m_top + 1) % m_capacity;
|
||||
m_size = std::min(m_size + 1, m_capacity);
|
||||
}
|
||||
|
||||
void isoBufferBuffer::insert(char const * s)
|
||||
{
|
||||
while (*s != '\0')
|
||||
insert(*s++);
|
||||
while (*s != '\0')
|
||||
insert(*s++);
|
||||
}
|
||||
|
||||
void isoBufferBuffer::insert(std::string const & s)
|
||||
{
|
||||
for (char c : s)
|
||||
insert(c);
|
||||
for (char c : s)
|
||||
insert(c);
|
||||
}
|
||||
|
||||
void isoBufferBuffer::insert_hex(uint8_t x)
|
||||
{
|
||||
char str[5];
|
||||
sprintf(str, "0x%02hhx", x);
|
||||
insert((char const *)str);
|
||||
char str[5];
|
||||
sprintf(str, "0x%02hhx", x);
|
||||
insert((char const *)str);
|
||||
}
|
||||
|
||||
char const* isoBufferBuffer::query(uint32_t count) const
|
||||
{
|
||||
if (count > m_capacity)
|
||||
qFatal("isoBufferBuffer::query : you may not request more items than the capacity of the buffer");
|
||||
if (count > m_capacity)
|
||||
qFatal("isoBufferBuffer::query : you may not request more items than the capacity of the buffer");
|
||||
|
||||
if (count > m_size)
|
||||
qFatal("isoBufferBuffer::query : you may not request more items than inserted");
|
||||
if (count > m_size)
|
||||
qFatal("isoBufferBuffer::query : you may not request more items than inserted");
|
||||
|
||||
return end() - count;
|
||||
return end() - count;
|
||||
}
|
||||
|
||||
void isoBufferBuffer::clear()
|
||||
{
|
||||
m_top = 0;
|
||||
m_size = 0;
|
||||
m_top = 0;
|
||||
m_size = 0;
|
||||
}
|
||||
|
||||
char const * isoBufferBuffer::begin() const
|
||||
{
|
||||
return m_data.get() + m_top - m_size + m_capacity;
|
||||
return m_data.get() + m_top - m_size + m_capacity;
|
||||
}
|
||||
|
||||
char const * isoBufferBuffer::end() const
|
||||
{
|
||||
return m_data.get() + m_top + m_capacity;
|
||||
return m_data.get() + m_top + m_capacity;
|
||||
}
|
||||
|
||||
uint32_t isoBufferBuffer::size() const
|
||||
{
|
||||
return m_size;
|
||||
return m_size;
|
||||
}
|
||||
|
||||
uint32_t isoBufferBuffer::capacity() const
|
||||
{
|
||||
return m_capacity;
|
||||
return m_capacity;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,30 +24,30 @@
|
|||
class isoBufferBuffer
|
||||
{
|
||||
public:
|
||||
isoBufferBuffer(uint32_t length);
|
||||
~isoBufferBuffer() = default;
|
||||
isoBufferBuffer(uint32_t length);
|
||||
~isoBufferBuffer() = default;
|
||||
|
||||
void insert(char c);
|
||||
void insert(char const * s);
|
||||
void insert(std::string const & s);
|
||||
void insert_hex(uint8_t x);
|
||||
void insert(char c);
|
||||
void insert(char const * s);
|
||||
void insert(std::string const & s);
|
||||
void insert_hex(uint8_t x);
|
||||
|
||||
char const * query(uint32_t length) const;
|
||||
// TODO?: add ability to get a copy of the content
|
||||
// (e.g. return std::string or Qstring)
|
||||
char const * query(uint32_t length) const;
|
||||
// TODO?: add ability to get a copy of the content
|
||||
// (e.g. return std::string or Qstring)
|
||||
|
||||
void clear();
|
||||
void clear();
|
||||
|
||||
char const * begin() const;
|
||||
char const * end() const;
|
||||
char const * begin() const;
|
||||
char const * end() const;
|
||||
|
||||
uint32_t size() const;
|
||||
uint32_t capacity() const;
|
||||
uint32_t size() const;
|
||||
uint32_t capacity() const;
|
||||
private:
|
||||
std::unique_ptr<char[]> m_data;
|
||||
uint32_t m_capacity;
|
||||
uint32_t m_size = 0;
|
||||
uint32_t m_top = 0;
|
||||
std::unique_ptr<char[]> m_data;
|
||||
uint32_t m_capacity;
|
||||
uint32_t m_size = 0;
|
||||
uint32_t m_top = 0;
|
||||
};
|
||||
|
||||
#endif // ISOBUFFERBUFFER_H
|
||||
|
|
|
@ -668,7 +668,7 @@ void isoDriver::frameActionGeneric(char CH1_mode, char CH2_mode)
|
|||
double triggerDelay = 0;
|
||||
if (triggerEnabled)
|
||||
{
|
||||
isoBuffer* internalBuffer_CH1 = (CH1_mode == -1) ? internalBuffer750 : internalBuffer375_CH1;
|
||||
isoBuffer* internalBuffer_CH1 = (CH1_mode == -1) ? internalBuffer750 : internalBuffer375_CH1;
|
||||
triggerDelay = (triggerMode < 2) ? internalBuffer_CH1->getDelayedTriggerPoint(display.window) - display.window : internalBuffer375_CH2->getDelayedTriggerPoint(display.window) - display.window;
|
||||
|
||||
if (triggerDelay < 0)
|
||||
|
@ -1316,7 +1316,7 @@ double isoDriver::meanVoltageLast(double seconds, unsigned char channel, int TOP
|
|||
break;
|
||||
}
|
||||
|
||||
std::unique_ptr<short[]> tempBuffer = currentBuffer->readBuffer(seconds, 1024, 0, 0);
|
||||
std::unique_ptr<short[]> tempBuffer = currentBuffer->readBuffer(seconds, 1024, 0, 0);
|
||||
double sum = 0;
|
||||
double temp;
|
||||
for(int i = 0; i<1024; i++){
|
||||
|
@ -1540,12 +1540,12 @@ void isoDriver::setSerialType(unsigned char type)
|
|||
|
||||
void isoDriver::hideCH1(bool enable)
|
||||
{
|
||||
axes->graph(0)->setVisible(!enable);
|
||||
axes->graph(0)->setVisible(!enable);
|
||||
}
|
||||
|
||||
void isoDriver::hideCH2(bool enable)
|
||||
{
|
||||
axes->graph(1)->setVisible(!enable);
|
||||
axes->graph(1)->setVisible(!enable);
|
||||
}
|
||||
|
||||
void isoDriver::triggerStateChanged()
|
||||
|
@ -1658,3 +1658,4 @@ void isoDriver::setMaxSpectrum(int maxSpectrum)
|
|||
{
|
||||
m_spectrumMaxX = static_cast<double>(maxSpectrum);
|
||||
}
|
||||
|
||||
|
|
|
@ -140,9 +140,9 @@ private:
|
|||
void triggerStateChanged();
|
||||
//Variables that are just pointers to other classes/vars
|
||||
QCustomPlot *axes; // TODO: move into DisplayControl
|
||||
std::unique_ptr<short[]> readData375_CH1;
|
||||
std::unique_ptr<short[]> readData375_CH2;
|
||||
std::unique_ptr<short[]> readData750;
|
||||
std::unique_ptr<short[]> readData375_CH1;
|
||||
std::unique_ptr<short[]> readData375_CH2;
|
||||
std::unique_ptr<short[]> readData750;
|
||||
float *readDataFile;
|
||||
char *isoTemp = NULL;
|
||||
short *isoTemp_short = NULL;
|
||||
|
@ -280,8 +280,8 @@ public slots:
|
|||
void fileTimerTick();
|
||||
void enableFileMode();
|
||||
void disableFileMode();
|
||||
void hideCH1(bool enable);
|
||||
void hideCH2(bool enable);
|
||||
void hideCH1(bool enable);
|
||||
void hideCH2(bool enable);
|
||||
void offsetChanged_CH1(double newOffset);
|
||||
void offsetChanged_CH2(double newOffset);
|
||||
void attenuationChanged_CH1(int attenuationIndex);
|
||||
|
|
|
@ -151,10 +151,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
connect(ui->controller_iso, SIGNAL(setGain(double)), ui->controller_iso->driver, SLOT(setGain(double)));
|
||||
connect(ui->controller_fg, &functionGenControl::functionGenToUpdate, ui->controller_iso->driver, &genericUsbDriver::setFunctionGen);
|
||||
connect(ui->bufferDisplay, SIGNAL(modeChange(int)), ui->controller_iso->driver, SLOT(setDeviceMode(int)));
|
||||
connect(ui->bufferDisplay, &bufferControl::modeChange, this, [this](){
|
||||
// Force a trigger refresh
|
||||
ui->controller_iso->setTriggerLevel(ui->triggerLevelValue->value());
|
||||
});
|
||||
connect(ui->bufferDisplay, &bufferControl::modeChange, this, [this](){
|
||||
// Force a trigger refresh
|
||||
ui->controller_iso->setTriggerLevel(ui->triggerLevelValue->value());
|
||||
});
|
||||
connect(ui->bufferDisplay, SIGNAL(updateDig(int)), ui->controller_iso->driver, SLOT(newDig(int)));
|
||||
|
||||
//Set the settings again!
|
||||
|
@ -223,8 +223,8 @@ MainWindow::MainWindow(QWidget *parent) :
|
|||
connect(ui->actionHexDisplay, &QAction::toggled, ui->controller_iso, &isoDriver::setHexDisplay_CH1);
|
||||
connect(ui->actionHexDisplay_2, &QAction::toggled, ui->controller_iso, &isoDriver::setHexDisplay_CH2);
|
||||
|
||||
ui->hideCH1Box->setVisible(false);
|
||||
ui->hideCH2Box->setVisible(false);
|
||||
ui->hideCH1Box->setVisible(false);
|
||||
ui->hideCH2Box->setVisible(false);
|
||||
#endif
|
||||
ui->realTimeButton->setVisible(false);
|
||||
|
||||
|
@ -1380,10 +1380,10 @@ void MainWindow::reinitUsbStage2(void){
|
|||
connect(ui->controller_iso, SIGNAL(setGain(double)), ui->controller_iso->driver, SLOT(setGain(double)));
|
||||
connect(ui->controller_fg, &functionGenControl::functionGenToUpdate, ui->controller_iso->driver, &genericUsbDriver::setFunctionGen);
|
||||
connect(ui->bufferDisplay, SIGNAL(modeChange(int)), ui->controller_iso->driver, SLOT(setDeviceMode(int)));
|
||||
connect(ui->bufferDisplay, &bufferControl::modeChange, this, [this](){
|
||||
// Force a trigger refresh
|
||||
ui->controller_iso->setTriggerLevel(ui->triggerLevelValue->value());
|
||||
});
|
||||
connect(ui->bufferDisplay, &bufferControl::modeChange, this, [this](){
|
||||
// Force a trigger refresh
|
||||
ui->controller_iso->setTriggerLevel(ui->triggerLevelValue->value());
|
||||
});
|
||||
connect(ui->bufferDisplay, SIGNAL(updateDig(int)), ui->controller_iso->driver, SLOT(newDig(int)));
|
||||
|
||||
//Set the settings again!
|
||||
|
@ -1411,7 +1411,7 @@ void MainWindow::reinitUsbStage2(void){
|
|||
}
|
||||
|
||||
void MainWindow::resetUsbState(void){
|
||||
using functionGen::ChannelID;
|
||||
using functionGen::ChannelID;
|
||||
//ui->controller_iso->driver->setDeviceMode(deviceMode);
|
||||
//ui->controller_iso->driver->setPsu(currentPsuVoltage);
|
||||
ui->psuSlider->poke();
|
||||
|
@ -2402,15 +2402,15 @@ void MainWindow::on_actionShow_Range_Dialog_on_Main_Page_triggered(bool checked)
|
|||
void MainWindow::paused(bool enabled)
|
||||
{
|
||||
#ifndef PLATFORM_ANDROID
|
||||
qDebug() << "MainWindow::paused(" << enabled << ")";
|
||||
ui->hideCH1Box->setVisible(enabled);
|
||||
ui->hideCH2Box->setVisible(enabled);
|
||||
qDebug() << "MainWindow::paused(" << enabled << ")";
|
||||
ui->hideCH1Box->setVisible(enabled);
|
||||
ui->hideCH2Box->setVisible(enabled);
|
||||
|
||||
if (! enabled)
|
||||
{
|
||||
ui->hideCH1Box->setChecked(false);
|
||||
ui->hideCH2Box->setChecked(false);
|
||||
}
|
||||
if (! enabled)
|
||||
{
|
||||
ui->hideCH1Box->setChecked(false);
|
||||
ui->hideCH2Box->setChecked(false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -2473,6 +2473,7 @@ void MainWindow::cursorGroupEnabled(bool enabled)
|
|||
ui->makeCursorsNicer->setTurnedOn(false);
|
||||
ui->cursorGroup->setEnabled(false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MainWindow::on_actionHide_Widget_Oscilloscope_triggered(bool checked)
|
||||
|
|
|
@ -193,7 +193,7 @@ private slots:
|
|||
|
||||
void on_actionShow_Range_Dialog_on_Main_Page_triggered(bool checked);
|
||||
|
||||
void paused(bool enabled);
|
||||
void paused(bool enabled);
|
||||
|
||||
void on_actionNone_triggered();
|
||||
|
||||
|
@ -246,7 +246,7 @@ private:
|
|||
int reinitDigitalPinState;
|
||||
|
||||
QSettings *settings;
|
||||
bool calibrationCanceled = false;
|
||||
bool calibrationCanceled = false;
|
||||
|
||||
QPalette defaultPalette;
|
||||
QString defaultStyleName;
|
||||
|
|
|
@ -16,10 +16,10 @@ scopeRangeEnterDialog::scopeRangeEnterDialog(QWidget *parent, bool buttonVisible
|
|||
ui->buttonBox->setVisible(buttonVisible);
|
||||
|
||||
for (espoSpinBox* spinBox : {ui->vMaxBox, ui->vMinBox, ui->timeWindowBox, ui->delayBox})
|
||||
{
|
||||
spinBox->changeStepping(spinBox->value());
|
||||
{
|
||||
spinBox->changeStepping(spinBox->value());
|
||||
connect(spinBox, SIGNAL(valueChanged(double)), spinBox, SLOT(changeStepping(double)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
scopeRangeEnterDialog::~scopeRangeEnterDialog()
|
||||
|
@ -90,3 +90,4 @@ void scopeRangeEnterDialog::delayChanged(double val)
|
|||
{
|
||||
ui->delayBox->setValue(val);
|
||||
}
|
||||
|
||||
|
|
|
@ -3,37 +3,37 @@
|
|||
#include <cassert>
|
||||
|
||||
uartStyleDecoder::uartStyleDecoder(double baudRate, QObject *parent)
|
||||
: QObject(parent)
|
||||
, m_parent{static_cast<isoBuffer*>(parent)}
|
||||
, m_serialBuffer{SERIAL_BUFFER_LENGTH}
|
||||
, m_baudRate{baudRate}
|
||||
: QObject(parent)
|
||||
, m_parent{static_cast<isoBuffer*>(parent)}
|
||||
, m_serialBuffer{SERIAL_BUFFER_LENGTH}
|
||||
, m_baudRate{baudRate}
|
||||
{
|
||||
|
||||
// Begin decoding SAMPLE_DELAY seconds in the past.
|
||||
serialPtr_bit = (int)(m_parent->m_back * 8 - SERIAL_DELAY * m_parent->m_sampleRate_bit + m_parent->m_bufferLen * 8) % (m_parent->m_bufferLen*8);
|
||||
// Begin decoding SAMPLE_DELAY seconds in the past.
|
||||
serialPtr_bit = (int)(m_parent->m_back * 8 - SERIAL_DELAY * m_parent->m_sampleRate_bit + m_parent->m_bufferLen * 8) % (m_parent->m_bufferLen*8);
|
||||
|
||||
m_updateTimer.setTimerType(Qt::PreciseTimer);
|
||||
m_updateTimer.start(CONSOLE_UPDATE_TIMER_PERIOD);
|
||||
connect(&m_updateTimer, &QTimer::timeout, this, &uartStyleDecoder::updateConsole);
|
||||
|
||||
if (m_parent->m_channel == 1)
|
||||
console = m_parent->m_console1;
|
||||
console = m_parent->m_console1;
|
||||
else if (m_parent->m_channel == 2)
|
||||
console = m_parent->m_console2;
|
||||
console = m_parent->m_console2;
|
||||
else
|
||||
qFatal("Nonexistant console requested in uartStyleDecoder::serialDecode");
|
||||
qFatal("Nonexistant console requested in uartStyleDecoder::serialDecode");
|
||||
}
|
||||
|
||||
void uartStyleDecoder::updateConsole()
|
||||
{
|
||||
if (!newUartSymbol)
|
||||
return;
|
||||
if (!newUartSymbol)
|
||||
return;
|
||||
|
||||
std::lock_guard<std::mutex> lock(mutex);
|
||||
|
||||
console->setPlainText(QString::fromLocal8Bit(m_serialBuffer.begin(), m_serialBuffer.size()));
|
||||
if (m_parent->m_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);
|
||||
|
@ -53,7 +53,7 @@ void uartStyleDecoder::serialDecode()
|
|||
bool allZeroes = true;
|
||||
|
||||
while(dist_seconds > (bitPeriod_seconds + SERIAL_DELAY))
|
||||
{
|
||||
{
|
||||
// Read next uart bit
|
||||
bool uart_bit = getNextUartBit();
|
||||
|
||||
|
@ -67,7 +67,7 @@ void uartStyleDecoder::serialDecode()
|
|||
}
|
||||
else
|
||||
{
|
||||
// Uart starts transmitting after start bit (logic low).
|
||||
// Uart starts transmitting after start bit (logic low).
|
||||
uartTransmitting = uart_bit == false;
|
||||
jitterCompensationNeeded = true;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ void uartStyleDecoder::serialDecode()
|
|||
|
||||
//Not a single stop bit, or idle bit, in the whole stream. Wire must be disconnected.
|
||||
if (allZeroes)
|
||||
{
|
||||
{
|
||||
qDebug() << "Wire Disconnect detected!";
|
||||
wireDisconnected(m_parent->m_channel);
|
||||
m_parent->m_isDecoding = false;
|
||||
|
@ -95,7 +95,7 @@ int uartStyleDecoder::serialDistance() const
|
|||
if (back_bit >= serialPtr_bit)
|
||||
return back_bit - serialPtr_bit;
|
||||
else
|
||||
return bufferEnd_bit - serialPtr_bit + back_bit;
|
||||
return bufferEnd_bit - serialPtr_bit + back_bit;
|
||||
}
|
||||
|
||||
void uartStyleDecoder::updateSerialPtr(bool current_bit)
|
||||
|
@ -106,8 +106,8 @@ void uartStyleDecoder::updateSerialPtr(bool current_bit)
|
|||
int distance_between_bits = (m_parent->m_sampleRate_bit)/ m_baudRate;
|
||||
if (uartTransmitting)
|
||||
serialPtr_bit += distance_between_bits;
|
||||
else
|
||||
serialPtr_bit += (distance_between_bits - 1); //Less than one baud period so that it will always see that start bit.
|
||||
else
|
||||
serialPtr_bit += (distance_between_bits - 1); //Less than one baud period so that it will always see that start bit.
|
||||
|
||||
if (serialPtr_bit >= (m_parent->m_bufferLen * 8))
|
||||
serialPtr_bit -= (m_parent->m_bufferLen * 8);
|
||||
|
@ -115,7 +115,7 @@ void uartStyleDecoder::updateSerialPtr(bool current_bit)
|
|||
|
||||
bool uartStyleDecoder::getNextUartBit() const
|
||||
{
|
||||
int bitIndex = serialPtr_bit;
|
||||
int bitIndex = serialPtr_bit;
|
||||
|
||||
int coord_byte = bitIndex/8;
|
||||
int coord_bit = bitIndex - (8*coord_byte);
|
||||
|
@ -140,11 +140,11 @@ void uartStyleDecoder::decodeNextUartBit(bool bitValue)
|
|||
{
|
||||
char decodedDatabit = decodeDatabit(dataBit_max + 1, currentUartSymbol);
|
||||
|
||||
if (parityCheckFailed)
|
||||
{
|
||||
m_serialBuffer.insert("\n<ERROR: Following character contains parity error>\n");
|
||||
parityCheckFailed = false;
|
||||
}
|
||||
if (parityCheckFailed)
|
||||
{
|
||||
m_serialBuffer.insert("\n<ERROR: Following character contains parity error>\n");
|
||||
parityCheckFailed = false;
|
||||
}
|
||||
|
||||
if (m_hexDisplay)
|
||||
{
|
||||
|
@ -183,11 +183,11 @@ bool uartStyleDecoder::jitterCompensationProcedure(bool current_bit)
|
|||
uint8_t left_byte = (m_parent->m_buffer[left_coord/8] & 0xff);
|
||||
//Only run when a zero is detected in the leftmost symbol.
|
||||
if (left_byte != 0xff)
|
||||
{
|
||||
{
|
||||
//Step back, one sample at a time, to the 0->1 transition point
|
||||
bool temp_bit = 1;
|
||||
while(temp_bit)
|
||||
{
|
||||
{
|
||||
temp_bit = getNextUartBit();
|
||||
serialPtr_bit--;
|
||||
}
|
||||
|
@ -203,7 +203,7 @@ bool uartStyleDecoder::jitterCompensationProcedure(bool current_bit)
|
|||
char uartStyleDecoder::decodeDatabit(int mode, short symbol) const
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
{
|
||||
case 5:
|
||||
return decodeBaudot(symbol);
|
||||
break;
|
||||
|
@ -212,7 +212,7 @@ char uartStyleDecoder::decodeDatabit(int mode, short symbol) const
|
|||
break;
|
||||
default:
|
||||
qDebug() << "uartStyleDecoder::decodeDatabit is failing...";
|
||||
return -1; // Garbage
|
||||
return -1; // Garbage
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -243,17 +243,18 @@ void uartStyleDecoder::setHexDisplay(bool enabled)
|
|||
|
||||
bool uartStyleDecoder::isParityCorrect(uint32_t bitField) const
|
||||
{
|
||||
assert(parity != UartParity::None);
|
||||
assert(parity != UartParity::None);
|
||||
|
||||
return parityOf(bitField) == parity;
|
||||
return parityOf(bitField) == parity;
|
||||
}
|
||||
|
||||
UartParity uartStyleDecoder::parityOf(uint32_t bitField) const
|
||||
{
|
||||
bool result = false;
|
||||
bool result = false;
|
||||
|
||||
for (uint32_t mask = 1 << (dataBit_max-1); mask != 0; mask >>= 1)
|
||||
result ^= static_cast<bool>(bitField & mask);
|
||||
for (uint32_t mask = 1 << (dataBit_max-1); mask != 0; mask >>= 1)
|
||||
result ^= static_cast<bool>(bitField & mask);
|
||||
|
||||
return result ? UartParity::Odd : UartParity::Even;
|
||||
return result ? UartParity::Odd : UartParity::Even;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,13 +20,13 @@ class uartStyleDecoder : public QObject
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit uartStyleDecoder(double baudRate, QObject *parent = NULL);
|
||||
~uartStyleDecoder() = default;
|
||||
~uartStyleDecoder() = default;
|
||||
|
||||
|
||||
private:
|
||||
isoBuffer *m_parent;
|
||||
|
||||
// Indicates the current bit being decoded.
|
||||
// Indicates the current bit being decoded.
|
||||
int serialPtr_bit;
|
||||
|
||||
bool uartTransmitting = false;
|
||||
|
@ -47,7 +47,7 @@ private:
|
|||
QPlainTextEdit *console;
|
||||
isoBufferBuffer m_serialBuffer;
|
||||
public:
|
||||
double m_baudRate;
|
||||
double m_baudRate;
|
||||
QTimer m_updateTimer; // IMPORTANT: must be after m_serialBuffer. construction / destruction order matters
|
||||
void serialDecode();
|
||||
int serialDistance() const;
|
||||
|
@ -64,11 +64,11 @@ private:
|
|||
char decodeDatabit(int mode, short symbol) const;
|
||||
char decodeBaudot(short symbol) const;
|
||||
|
||||
std::mutex mutex;
|
||||
std::mutex mutex;
|
||||
UartParity parity = UartParity::None;
|
||||
|
||||
bool isParityCorrect(uint32_t bitField) const;
|
||||
UartParity parityOf(uint32_t bitField) const;
|
||||
UartParity parityOf(uint32_t bitField) const;
|
||||
|
||||
bool parityCheckFailed = false;
|
||||
|
||||
|
|
|
@ -254,3 +254,4 @@ void bufferControl::poke(void){
|
|||
updateMode();
|
||||
updateBuffer(0,0);
|
||||
}
|
||||
|
||||
|
|
|
@ -5,22 +5,59 @@ espoComboBox::espoComboBox(QWidget *parent) : QComboBox(parent)
|
|||
|
||||
}
|
||||
|
||||
|
||||
void espoComboBox::readWaveformList(void)
|
||||
{
|
||||
//This code gets the name of the current directory, regardless of platform.
|
||||
//This is so the interface knows where to find the waveform data
|
||||
//QDir *dir = new QDir();
|
||||
//qDebug() << dir->currentPath();
|
||||
#ifdef PLATFORM_ANDROID
|
||||
QFile file("assets:/waveforms/_list.wfl");
|
||||
QFile qt_list("assets:/waveforms/_list.wfl");
|
||||
bool success = qt_list.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
if(!success){
|
||||
qFatal("Could not load _list.wfl");
|
||||
}
|
||||
|
||||
char nameBuffer[255];
|
||||
QStringList *newNames = new QStringList();
|
||||
|
||||
while (!qt_list.atEnd()) {
|
||||
QByteArray line = qt_list.readLine();
|
||||
strcpy(nameBuffer, line.data());
|
||||
strtok(nameBuffer, "\n\r");
|
||||
newNames->append(nameBuffer);
|
||||
qDebug() << nameBuffer;
|
||||
}
|
||||
this->addItems(*(newNames));
|
||||
delete newNames;
|
||||
qt_list.close();
|
||||
#else
|
||||
QString path = QCoreApplication::applicationDirPath();
|
||||
QFile file(path.append("/waveforms/_list.wfl"));
|
||||
QString dirString = QCoreApplication::applicationDirPath();
|
||||
dirString.append("/waveforms/_list.wfl");
|
||||
QByteArray array = dirString.toLocal8Bit();
|
||||
char* buffer = array.data();
|
||||
//qDebug() << buffer;
|
||||
|
||||
qDebug() << "Attempting to open" << dirString;
|
||||
|
||||
FILE *listPtr = fopen(buffer, "r");
|
||||
QStringList *newNames = new QStringList();
|
||||
char nameBuffer[255];
|
||||
|
||||
if(listPtr == NULL){
|
||||
qFatal("Could not load _list.wfl");
|
||||
}
|
||||
|
||||
while (fgets(nameBuffer, sizeof(nameBuffer), listPtr) != NULL){
|
||||
qDebug() << "nameBuffer = " << nameBuffer;
|
||||
strtok(nameBuffer, "\n\r");
|
||||
newNames->append(nameBuffer);
|
||||
}
|
||||
this->addItems(*(newNames));
|
||||
delete newNames;
|
||||
|
||||
fclose(listPtr);
|
||||
#endif
|
||||
|
||||
qDebug() << "opening" << file.fileName();
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
qFatal("could not open %s", qUtf8Printable(file.fileName()));
|
||||
|
||||
QStringList newNames;
|
||||
while (!file.atEnd())
|
||||
newNames.append(file.readLine().trimmed());
|
||||
this->addItems(newNames);
|
||||
file.close();
|
||||
qDebug() << "List loaded!!";
|
||||
}
|
||||
|
|
|
@ -103,3 +103,4 @@ void espoSlider::poke(void){
|
|||
//qDebug() << "Refreshing to voltage" << ((double) (this->value())) / 20;
|
||||
voltageChanged(((double) (this->value())) / 20);
|
||||
}
|
||||
|
||||
|
|
|
@ -2,43 +2,43 @@
|
|||
|
||||
espoSpinBox::espoSpinBox(QWidget *parent) : QDoubleSpinBox(parent)
|
||||
{
|
||||
setKeyboardTracking(false);
|
||||
setKeyboardTracking(false);
|
||||
//connect(this, SIGNAL(valueChanged(double)), this, SLOT(changeStepping(double)));
|
||||
}
|
||||
|
||||
QString espoSpinBox::textFromValue(double value) const{
|
||||
QString windowText;
|
||||
|
||||
double approximatelyZero = pow(10, -1 * (decimals() + 1));
|
||||
double approximatelyZero = pow(10, -1 * (decimals() + 1));
|
||||
|
||||
if (abs(value) <= approximatelyZero){
|
||||
QTextStream(&windowText) << 0;
|
||||
lastValidValue = 0;
|
||||
lastValidValue = 0;
|
||||
return windowText;
|
||||
}
|
||||
if (abs(value) >= 1000000){
|
||||
QTextStream(&windowText) << value/1000000 << "M";
|
||||
lastValidValue = value;
|
||||
lastValidValue = value;
|
||||
return windowText;
|
||||
}
|
||||
if (abs(value) >= 1000){
|
||||
QTextStream(&windowText) << value/1000 << "k";
|
||||
lastValidValue = value;
|
||||
lastValidValue = value;
|
||||
return windowText;
|
||||
}
|
||||
if (abs(value) >= 1){
|
||||
QTextStream(&windowText) << value;
|
||||
lastValidValue = value;
|
||||
lastValidValue = value;
|
||||
return windowText;
|
||||
}
|
||||
if (abs(value) >= 1/1000){
|
||||
QTextStream(&windowText) << value * 1000 << "m";
|
||||
lastValidValue = value;
|
||||
lastValidValue = value;
|
||||
return windowText;
|
||||
}
|
||||
if (abs(value) >= 1/1000000){
|
||||
QTextStream(&windowText) << value * 1000000 << "u";
|
||||
lastValidValue = value;
|
||||
lastValidValue = value;
|
||||
return windowText;
|
||||
}
|
||||
return "invalid";
|
||||
|
@ -58,53 +58,53 @@ void espoSpinBox::setMin(double newMin){
|
|||
|
||||
void espoSpinBox::changeStepping(double value){
|
||||
double roundval = pow(10.0, floor(log10(abs(value)))); //http://stackoverflow.com/questions/22491505/how-to-round-down-to-the-nearest-power-of-10
|
||||
double minimumStepSize = pow(10, -1 * decimals());
|
||||
double minimumStepSize = pow(10, -1 * decimals());
|
||||
setSingleStep(std::max(minimumStepSize, roundval/10));
|
||||
}
|
||||
|
||||
QValidator::State espoSpinBox::validate(QString& text, int& pos) const
|
||||
{
|
||||
return QValidator::State::Acceptable;
|
||||
return QValidator::State::Acceptable;
|
||||
}
|
||||
|
||||
double espoSpinBox::valueFromText(const QString &text) const
|
||||
{
|
||||
double ret;
|
||||
bool isValid;
|
||||
double ret;
|
||||
bool isValid;
|
||||
|
||||
uint32_t prefixLength = text.length() - suffix().length();
|
||||
uint32_t prefixLength = text.length() - suffix().length();
|
||||
|
||||
qDebug() << text.mid(0, prefixLength - 1) << text.at(prefixLength - 1).toLatin1();
|
||||
qDebug() << text.mid(0, prefixLength - 1) << text.at(prefixLength - 1).toLatin1();
|
||||
|
||||
switch (text.at(prefixLength - 1).toLatin1())
|
||||
{
|
||||
case 'M':
|
||||
ret = text.mid(0, prefixLength - 1).toDouble(&isValid) * 1000000;
|
||||
break;
|
||||
switch (text.at(prefixLength - 1).toLatin1())
|
||||
{
|
||||
case 'M':
|
||||
ret = text.mid(0, prefixLength - 1).toDouble(&isValid) * 1000000;
|
||||
break;
|
||||
|
||||
case 'k':
|
||||
ret = text.mid(0, prefixLength - 1).toDouble(&isValid) * 1000;
|
||||
break;
|
||||
case 'k':
|
||||
ret = text.mid(0, prefixLength - 1).toDouble(&isValid) * 1000;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
ret = text.mid(0, prefixLength - 1).toDouble(&isValid) / 1000;
|
||||
break;
|
||||
case 'm':
|
||||
ret = text.mid(0, prefixLength - 1).toDouble(&isValid) / 1000;
|
||||
break;
|
||||
|
||||
case 'u':
|
||||
ret = text.mid(0, prefixLength - 1).toDouble(&isValid) / 1000000;
|
||||
break;
|
||||
case 'u':
|
||||
ret = text.mid(0, prefixLength - 1).toDouble(&isValid) / 1000000;
|
||||
break;
|
||||
|
||||
default:
|
||||
ret = text.mid(0, prefixLength).toDouble(&isValid);
|
||||
}
|
||||
default:
|
||||
ret = text.mid(0, prefixLength).toDouble(&isValid);
|
||||
}
|
||||
|
||||
if (isValid)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "espoSpinBox: warning: invalid text input." << "Defaulting to last known good value of" << lastValidValue;
|
||||
return lastValidValue;
|
||||
}
|
||||
if (isValid)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
qDebug() << "espoSpinBox: warning: invalid text input." << "Defaulting to last known good value of" << lastValidValue;
|
||||
return lastValidValue;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,11 +15,11 @@ class espoSpinBox : public QDoubleSpinBox
|
|||
Q_OBJECT
|
||||
public:
|
||||
explicit espoSpinBox(QWidget *parent = 0);
|
||||
QValidator::State validate(QString& text, int& pos) const override;
|
||||
QValidator::State validate(QString& text, int& pos) const override;
|
||||
private:
|
||||
QString textFromValue(double value) const override;
|
||||
double valueFromText(const QString &text) const override;
|
||||
mutable double lastValidValue = -1;
|
||||
double valueFromText(const QString &text) const override;
|
||||
mutable double lastValidValue = -1;
|
||||
signals:
|
||||
|
||||
public slots:
|
||||
|
|
|
@ -57,3 +57,4 @@ void swipeyStack::cycleStack(int delta){
|
|||
void swipeyStack::enableWrapping(bool enabled){
|
||||
wrapEnabled = enabled;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,24 +20,24 @@ unixUsbDriver::~unixUsbDriver(void){
|
|||
qDebug() << "\n\nunixUsbDriver destructor ran!";
|
||||
//unixDriverDeleteMutex.lock();
|
||||
if(connected){
|
||||
if (workerThread)
|
||||
{
|
||||
workerThread->deleteLater();
|
||||
while(workerThread->isRunning()){
|
||||
workerThread->quit();
|
||||
qDebug() << "isRunning?" << workerThread->isFinished();
|
||||
QThread::msleep(100);
|
||||
}
|
||||
}
|
||||
if (isoHandler)
|
||||
delete(isoHandler);
|
||||
if (workerThread)
|
||||
{
|
||||
workerThread->deleteLater();
|
||||
while(workerThread->isRunning()){
|
||||
workerThread->quit();
|
||||
qDebug() << "isRunning?" << workerThread->isFinished();
|
||||
QThread::msleep(100);
|
||||
}
|
||||
}
|
||||
if (isoHandler)
|
||||
delete(isoHandler);
|
||||
//delete(workerThread);
|
||||
qDebug() << "THREAD Gone!";
|
||||
|
||||
for (int i=0; i<NUM_FUTURE_CTX; i++){
|
||||
for (int k=0; k<NUM_ISO_ENDPOINTS; k++){
|
||||
if (isoCtx[k][i])
|
||||
libusb_free_transfer(isoCtx[k][i]);
|
||||
if (isoCtx[k][i])
|
||||
libusb_free_transfer(isoCtx[k][i]);
|
||||
}
|
||||
}
|
||||
qDebug() << "Transfers freed.";
|
||||
|
@ -160,7 +160,7 @@ int unixUsbDriver::usbIsoInit(void){
|
|||
if(error){
|
||||
qDebug() << "libusb_submit_transfer FAILED";
|
||||
qDebug() << "ERROR" << libusb_error_name(error);
|
||||
return -1;
|
||||
return -1;
|
||||
} else {
|
||||
if(n == 0){
|
||||
qint64 t0;
|
||||
|
@ -334,8 +334,8 @@ void unixUsbDriver::shutdownProcedure(){
|
|||
|
||||
//On physical disconnect, isoTimerTick will not assert stopTime. Hence this duct-tape function.
|
||||
void unixUsbDriver::backupCleanup(){
|
||||
if (isoHandler)
|
||||
isoHandler->stopTime = true;
|
||||
if (isoHandler)
|
||||
isoHandler->stopTime = true;
|
||||
}
|
||||
|
||||
int unixUsbDriver::flashFirmware(void){
|
||||
|
|
|
@ -42,7 +42,7 @@ unsigned char winUsbDriver::usbInit(unsigned long VIDin, unsigned long PIDin){
|
|||
KLST_HANDLE deviceList = NULL;
|
||||
|
||||
//List libusbk devices connected
|
||||
if (!LstK_Init(&deviceList, (KLST_FLAG) 0)) {
|
||||
if (!LstK_Init(&deviceList, (KLST_FLAG) 0)) {
|
||||
qDebug("Error initializing device list");
|
||||
return 1;
|
||||
} //else qDebug() << "Device List initialised!";
|
||||
|
@ -51,7 +51,7 @@ unsigned char winUsbDriver::usbInit(unsigned long VIDin, unsigned long PIDin){
|
|||
LstK_Count(deviceList, &deviceCount);
|
||||
if (!deviceCount) {
|
||||
qDebug("Device list empty");
|
||||
LstK_Free(deviceList); // If LstK_Init returns TRUE, the list must be freed.
|
||||
LstK_Free(deviceList); // If LstK_Init returns TRUE, the list must be freed.
|
||||
return 0;
|
||||
} //else qDebug() << "Device Count initialised!";
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue