mirror of https://github.com/EspoTek/Labrador.git
Functiongencontrol refactor (#68)
* Add struct definition for functionGenControl channel data * Add member variables for channel data to functionGenControl, deprecate old variables * fix a typo * Transition to new functionGenControl cahnnel data variables. Remove old ones. * refactor genericUsbDriver::setFunctionGen to use the new ChannelData struct. * functionGenControl: free(NULL) is safe * Eliminate duplication of functionGenControl::waveformName_CH* fuctions by putting common things into a private template function * get rid of comments added during refactor * Move function gen channel data to use std::vector. algorithmify some code on genericUsbDriver::setFunctionGen * various formatting changes, remove irrelevant comments * functionGenControl::waveformName: always use utf8 and 16 byte buffers. Remove template * fix typo introduced by last-second indentation change * genericUsbDrive::setFunctionGen: shrink samples to fit * functionGenControl::waveformName: clean up file path manipulation, clean up formatting * change the two channel objects to an array of two elements. Add common implementations for all methods of functionGenControl. Fix a massive bug introduced earlier in the refactor. Formatting.
This commit is contained in:
parent
4cd2a03b01
commit
a144105b23
|
@ -5,127 +5,54 @@
|
||||||
functionGenControl::functionGenControl(QWidget *parent) : QLabel(parent)
|
functionGenControl::functionGenControl(QWidget *parent) : QLabel(parent)
|
||||||
{
|
{
|
||||||
this->hide();
|
this->hide();
|
||||||
samples_CH1 = (unsigned char *) malloc(0);
|
|
||||||
samples_CH2 = (unsigned char *) malloc(0);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void functionGenControl::waveformName_CH1(QString newName)
|
void functionGenControl::waveformName_CH1(QString newName)
|
||||||
{
|
{
|
||||||
qDebug() << "newName = " << newName;
|
waveformName(newName, 0);
|
||||||
newName.append(".tlw");
|
|
||||||
|
|
||||||
//QDir *dir = new QDir();
|
|
||||||
//QString directory = dir->currentPath();
|
|
||||||
|
|
||||||
#ifdef PLATFORM_ANDROID
|
|
||||||
QString waveformFilePath("assets:/waveforms/");
|
|
||||||
waveformFilePath.append(newName);
|
|
||||||
|
|
||||||
QFile fptr(waveformFilePath);
|
|
||||||
bool success = fptr.open(QIODevice::ReadOnly);
|
|
||||||
|
|
||||||
QByteArray line;
|
|
||||||
char lengthString[16];
|
|
||||||
char divisibilityString[16];
|
|
||||||
|
|
||||||
line = fptr.readLine();
|
|
||||||
strcpy(lengthString, line.data());
|
|
||||||
sscanf(lengthString, "%d", &length_CH1);
|
|
||||||
qDebug() << "lengthString" << lengthString;
|
|
||||||
|
|
||||||
line = fptr.readLine();
|
|
||||||
strcpy(divisibilityString, line.data());
|
|
||||||
sscanf(divisibilityString, "%d", &divisibility_CH1);
|
|
||||||
qDebug() << "divisibilityString" << divisibilityString;
|
|
||||||
|
|
||||||
qDebug() << "Length = " << length_CH1;
|
|
||||||
qDebug() << "Divisibility = " << divisibility_CH1;
|
|
||||||
|
|
||||||
QByteArray remainingData = fptr.readAll();
|
|
||||||
char *dataString = remainingData.data();
|
|
||||||
|
|
||||||
free(samples_CH1);
|
|
||||||
samples_CH1 = (unsigned char *) malloc(length_CH1);
|
|
||||||
|
|
||||||
int dummy;
|
|
||||||
char *dataStringCurrent = dataString;
|
|
||||||
for (int i=0;i<length_CH1;i++){
|
|
||||||
sscanf(dataStringCurrent, "%d", &dummy);
|
|
||||||
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
|
||||||
samples_CH1[i] = (unsigned char) dummy;
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
QString directory = QCoreApplication::applicationDirPath();
|
|
||||||
|
|
||||||
directory.append("/waveforms/");
|
|
||||||
directory.append(newName);
|
|
||||||
QByteArray temp = directory.toLocal8Bit();
|
|
||||||
char *fileName = temp.data();
|
|
||||||
|
|
||||||
qDebug() << "opening" << fileName;
|
|
||||||
FILE *fptr = fopen(fileName, "r");
|
|
||||||
if (fptr==NULL){
|
|
||||||
qFatal("%s could not be opened!", fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
char lengthString[6];
|
|
||||||
fgets(lengthString, 5, fptr);
|
|
||||||
qDebug() << lengthString;
|
|
||||||
sscanf(lengthString, "%d", &length_CH1);
|
|
||||||
|
|
||||||
char divisibilityString[6];
|
|
||||||
//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", &divisibility_CH1);
|
|
||||||
|
|
||||||
qDebug() << "Length = " << length_CH1;
|
|
||||||
qDebug() << "Divisibility = " << divisibility_CH1;
|
|
||||||
|
|
||||||
free(samples_CH1);
|
|
||||||
samples_CH1 = (unsigned char *) malloc(length_CH1);
|
|
||||||
|
|
||||||
char *dataString = (char *) malloc(length_CH1*5+1);
|
|
||||||
fgets(dataString, length_CH1*5+1, fptr);
|
|
||||||
|
|
||||||
int dummy;
|
|
||||||
char *dataStringCurrent = dataString;
|
|
||||||
for (int i=0;i<length_CH1;i++){
|
|
||||||
sscanf(dataStringCurrent, "%d", &dummy);
|
|
||||||
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
|
||||||
samples_CH1[i] = (unsigned char) dummy;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(dataString);
|
|
||||||
fclose(fptr);
|
|
||||||
#endif
|
|
||||||
setMaxFreq_CH1(DAC_SPS/(length_CH1>>(divisibility_CH1-1)));
|
|
||||||
setMinFreq_CH1((double) CLOCK_FREQ/1024/65535/length_CH1);
|
|
||||||
functionGenToUpdate(0, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void functionGenControl::freqUpdate_CH1(double newFreq){
|
void functionGenControl::freqUpdate_CH1(double newFreq)
|
||||||
qDebug() << "newFreq = " << newFreq;
|
{
|
||||||
freq_CH1 = newFreq;
|
freqUpdate(newFreq, 0);
|
||||||
functionGenToUpdate(0, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void functionGenControl::amplitudeUpdate_CH1(double newAmplitude){
|
void functionGenControl::amplitudeUpdate_CH1(double newAmplitude)
|
||||||
qDebug() << "newAmplitude = " << newAmplitude;
|
{
|
||||||
amplitude_CH1 = newAmplitude;
|
amplitudeUpdate(newAmplitude, 0);
|
||||||
functionGenToUpdate(0, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void functionGenControl::offsetUpdate_CH1(double newOffset){
|
void functionGenControl::offsetUpdate_CH1(double newOffset)
|
||||||
qDebug() << "newOffset = " << newOffset;
|
{
|
||||||
offset_CH1 = newOffset;
|
offsetUpdate(newOffset, 0);
|
||||||
functionGenToUpdate(0, this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void functionGenControl::waveformName_CH2(QString newName)
|
void functionGenControl::waveformName_CH2(QString newName)
|
||||||
{
|
{
|
||||||
|
waveformName(newName, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void functionGenControl::freqUpdate_CH2(double newFreq)
|
||||||
|
{
|
||||||
|
freqUpdate(newFreq, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void functionGenControl::amplitudeUpdate_CH2(double newAmplitude)
|
||||||
|
{
|
||||||
|
amplitudeUpdate(newAmplitude, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void functionGenControl::offsetUpdate_CH2(double newOffset)
|
||||||
|
{
|
||||||
|
offsetUpdate(newOffset, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void functionGenControl::waveformName(QString newName, int channelID)
|
||||||
|
{
|
||||||
|
ChannelData& channel = channels[channelID];
|
||||||
|
|
||||||
qDebug() << "newName = " << newName;
|
qDebug() << "newName = " << newName;
|
||||||
newName.append(".tlw");
|
newName.append(".tlw");
|
||||||
|
|
||||||
|
@ -142,93 +69,117 @@ void functionGenControl::waveformName_CH2(QString newName)
|
||||||
|
|
||||||
line = fptr.readLine();
|
line = fptr.readLine();
|
||||||
strcpy(lengthString, line.data());
|
strcpy(lengthString, line.data());
|
||||||
sscanf(lengthString, "%d", &length_CH2);
|
sscanf(lengthString, "%d", &channel.length);
|
||||||
qDebug() << "lengthString" << lengthString;
|
qDebug() << "lengthString" << lengthString;
|
||||||
|
|
||||||
line = fptr.readLine();
|
line = fptr.readLine();
|
||||||
strcpy(divisibilityString, line.data());
|
strcpy(divisibilityString, line.data());
|
||||||
sscanf(divisibilityString, "%d", &divisibility_CH2);
|
sscanf(divisibilityString, "%d", &channel.divisibility);
|
||||||
qDebug() << "divisibilityString" << divisibilityString;
|
qDebug() << "divisibilityString" << divisibilityString;
|
||||||
|
|
||||||
qDebug() << "Length = " << length_CH2;
|
qDebug() << "Length = " << channel.length;
|
||||||
qDebug() << "Divisibility = " << divisibility_CH2;
|
qDebug() << "Divisibility = " << channel.divisibility;
|
||||||
|
|
||||||
QByteArray remainingData = fptr.readAll();
|
QByteArray remainingData = fptr.readAll();
|
||||||
char *dataString = remainingData.data();
|
char *dataString = remainingData.data();
|
||||||
|
|
||||||
free(samples_CH2);
|
channel.samples.resize(channel.length);
|
||||||
samples_CH2 = (unsigned char *) malloc(length_CH2);
|
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
char *dataStringCurrent = dataString;
|
char *dataStringCurrent = dataString;
|
||||||
for (int i=0;i<length_CH2;i++){
|
for (int i = 0; i < channel.length; i++)
|
||||||
|
{
|
||||||
sscanf(dataStringCurrent, "%d", &dummy);
|
sscanf(dataStringCurrent, "%d", &dummy);
|
||||||
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
||||||
samples_CH2[i] = (unsigned char) dummy;
|
channel.samples[i] = uint8_t(dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
QString directory = QCoreApplication::applicationDirPath();
|
|
||||||
|
|
||||||
directory.append("/waveforms/");
|
QByteArray filePath = QCoreApplication::applicationDirPath()
|
||||||
directory.append(newName);
|
.append("/waveforms/").append(newName).toUtf8();
|
||||||
QByteArray temp = directory.toLatin1();
|
|
||||||
char *fileName = temp.data();
|
|
||||||
|
|
||||||
qDebug() << "opening" << fileName;
|
qDebug() << "opening" << filePath;
|
||||||
FILE *fptr = fopen(fileName, "r");
|
|
||||||
if (fptr==NULL){
|
|
||||||
qFatal("%s could not be opened!", fileName);
|
|
||||||
}
|
|
||||||
|
|
||||||
char lengthString[5];
|
FILE *fptr = fopen(filePath.constData(), "r");
|
||||||
|
if (fptr == NULL)
|
||||||
|
qFatal("%s could not be opened!", filePath.constData());
|
||||||
|
|
||||||
|
char lengthString[16];
|
||||||
fgets(lengthString, 5, fptr);
|
fgets(lengthString, 5, fptr);
|
||||||
sscanf(lengthString, "%d", &length_CH2);
|
sscanf(lengthString, "%d", &channel.length);
|
||||||
|
|
||||||
char divisibilityString[5];
|
char divisibilityString[16];
|
||||||
//Bit of bullshit to deal with CRLF line endings on Mac.
|
//Bit of bullshit to deal with CRLF line endings on Mac.
|
||||||
do fgets(divisibilityString, 5, fptr);
|
do
|
||||||
while ((divisibilityString[0] == '\r') || (divisibilityString[0] == '\n'));
|
{
|
||||||
sscanf(divisibilityString, "%d", &divisibility_CH2);
|
fgets(divisibilityString, 5, fptr);
|
||||||
|
}
|
||||||
|
while ((divisibilityString[0] == '\r') || (divisibilityString[0] == '\n'));
|
||||||
|
|
||||||
qDebug() << "Length = " << length_CH2;
|
sscanf(divisibilityString, "%d", &channel.divisibility);
|
||||||
qDebug() << "Divisibility = " << divisibility_CH2;
|
|
||||||
|
|
||||||
free(samples_CH2);
|
qDebug() << "Length = " << channel.length;
|
||||||
samples_CH2 = (unsigned char *) malloc(length_CH2);
|
qDebug() << "Divisibility = " << channel.divisibility;
|
||||||
|
|
||||||
char *dataString = (char *) malloc(length_CH2*5+1);
|
channel.samples.resize(channel.length);
|
||||||
fgets(dataString, length_CH2*5+1, fptr);
|
|
||||||
|
char *dataString = (char *) malloc(channel.length*5+1);
|
||||||
|
fgets(dataString, channel.length*5+1, fptr);
|
||||||
|
|
||||||
int dummy;
|
int dummy;
|
||||||
char *dataStringCurrent = dataString;
|
char *dataStringCurrent = dataString;
|
||||||
for (int i=0;i<length_CH2;i++){
|
for (int i = 0; i < channel.length; i++)
|
||||||
|
{
|
||||||
sscanf(dataStringCurrent, "%d", &dummy);
|
sscanf(dataStringCurrent, "%d", &dummy);
|
||||||
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
||||||
samples_CH2[i] = (unsigned char) dummy;
|
channel.samples[i] = uint8_t(dummy);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(dataString);
|
free(dataString);
|
||||||
fclose(fptr);
|
fclose(fptr);
|
||||||
#endif
|
#endif
|
||||||
setMaxFreq_CH2(DAC_SPS/(length_CH2>>(divisibility_CH2-1)));
|
|
||||||
setMinFreq_CH2((double) CLOCK_FREQ/1024/65535/length_CH2);
|
double newMaxFreq = DAC_SPS / (channel.length >> (channel.divisibility - 1));
|
||||||
functionGenToUpdate(1, this);
|
double newMinFreq = double(CLOCK_FREQ) / 1024.0 / 65535.0 / channel.length;
|
||||||
|
|
||||||
|
// NOTE: Not very clean... Not sure what to do about it.
|
||||||
|
// I guess the "right thing" would be to have a Channel QObject class with its
|
||||||
|
// own signals and slots, or have a single setMaxFreq signal with channelID as
|
||||||
|
// an argument. Either solution would require changes in other places in the
|
||||||
|
// codebase so this will have to do for now.
|
||||||
|
if (channelID == 0)
|
||||||
|
{
|
||||||
|
setMaxFreq_CH1(newMaxFreq);
|
||||||
|
setMinFreq_CH1(newMinFreq);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setMaxFreq_CH2(newMaxFreq);
|
||||||
|
setMinFreq_CH2(newMinFreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
functionGenToUpdate(channelID, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void functionGenControl::freqUpdate_CH2(double newFreq){
|
void functionGenControl::freqUpdate(double newFreq, int channelID)
|
||||||
qDebug() << "newFreq2 = " << newFreq;
|
{
|
||||||
freq_CH2 = newFreq;
|
qDebug() << "newFreq" << channelID << " = " << newFreq;
|
||||||
functionGenToUpdate(1, this);
|
channels[channelID].freq = newFreq;
|
||||||
|
functionGenToUpdate(channelID, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void functionGenControl::amplitudeUpdate_CH2(double newAmplitude){
|
void functionGenControl::amplitudeUpdate(double newAmplitude, int channelID)
|
||||||
qDebug() << "newAmplitude2 = " << newAmplitude;
|
{
|
||||||
amplitude_CH2 = newAmplitude;
|
qDebug() << "newAmplitude" << channelID << " = " << newAmplitude;
|
||||||
functionGenToUpdate(1, this);
|
channels[channelID].amplitude = newAmplitude;
|
||||||
|
functionGenToUpdate(channelID, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void functionGenControl::offsetUpdate_CH2(double newOffset){
|
void functionGenControl::offsetUpdate(double newOffset, int channelID)
|
||||||
qDebug() << "newOffset2 = " << newOffset;
|
{
|
||||||
offset_CH2 = newOffset;
|
qDebug() << "newOffset" << channelID << " = " << newOffset;
|
||||||
functionGenToUpdate(1, this);
|
channels[channelID].offset = newOffset;
|
||||||
|
functionGenToUpdate(channelID, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef FUNCTIONGENCONTROL_H
|
#ifndef FUNCTIONGENCONTROL_H
|
||||||
#define FUNCTIONGENCONTROL_H
|
#define FUNCTIONGENCONTROL_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
@ -15,10 +17,30 @@ class functionGenControl : public QLabel
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
struct ChannelData
|
||||||
|
{
|
||||||
|
std::vector<uint8_t> samples;
|
||||||
|
// TODO: get rid of length member. samples:std::vector already has this information
|
||||||
|
int length;
|
||||||
|
int divisibility;
|
||||||
|
double freq = 1000.0;
|
||||||
|
double amplitude = 0.0;
|
||||||
|
double offset = 0.0;
|
||||||
|
};
|
||||||
|
|
||||||
explicit functionGenControl(QWidget *parent = 0);
|
explicit functionGenControl(QWidget *parent = 0);
|
||||||
unsigned char *samples_CH1, *samples_CH2;
|
|
||||||
int length_CH1, divisibility_CH1, length_CH2, divisibility_CH2;
|
ChannelData channels[2];
|
||||||
double freq_CH1 = 1000, amplitude_CH1 = 0, offset_CH1 = 0, freq_CH2 = 1000, amplitude_CH2 = 0, offset_CH2 = 0;
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
// NOTE: An enum instead of a plain int would probably be better here
|
||||||
|
void waveformName(QString newName, int channelID);
|
||||||
|
void freqUpdate(double newFreq, int channelID);
|
||||||
|
void amplitudeUpdate(double newAmplitude, int channelID);
|
||||||
|
void offsetUpdate(double newOffset, int channelID);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void functionGenToUpdate(int channel, functionGenControl *fGenControl);
|
void functionGenToUpdate(int channel, functionGenControl *fGenControl);
|
||||||
void setMaxFreq_CH1(double maxFreq);
|
void setMaxFreq_CH1(double maxFreq);
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#include "genericusbdriver.h"
|
#include "genericusbdriver.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#ifndef LIBRADOR_LIBRARY
|
#ifndef LIBRADOR_LIBRARY
|
||||||
#include "platformspecific.h"
|
#include "platformspecific.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -72,7 +75,8 @@ void genericUsbDriver::setPsu(double voltage){
|
||||||
qDebug() << "Going to send value " << dutyPsu;
|
qDebug() << "Going to send value " << dutyPsu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void genericUsbDriver::setFunctionGen(int channel, functionGenControl *fGenControl){
|
void genericUsbDriver::setFunctionGen(int channelID, functionGenControl *fGenControl)
|
||||||
|
{
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
////NO RESIZING (YET)!!!////
|
////NO RESIZING (YET)!!!////
|
||||||
////////////////////////////
|
////////////////////////////
|
||||||
|
@ -81,54 +85,37 @@ void genericUsbDriver::setFunctionGen(int channel, functionGenControl *fGenContr
|
||||||
//// CH1 is AUX!! CH2 is "MAIN"!!////
|
//// CH1 is AUX!! CH2 is "MAIN"!!////
|
||||||
//////////////////////////////////////
|
//////////////////////////////////////
|
||||||
|
|
||||||
int length, maxLength, numDivides, maxDivides;
|
|
||||||
double freq, amplitude, offset;
|
|
||||||
unsigned char *samples;
|
|
||||||
|
|
||||||
//For recalling on crash.
|
//For recalling on crash.
|
||||||
if (channel == 0) fGenPtr_CH1 = fGenControl;
|
if (channelID == 0)
|
||||||
else fGenPtr_CH2 = fGenControl;
|
fGenPtr_CH1 = fGenControl;
|
||||||
|
else
|
||||||
|
fGenPtr_CH2 = fGenControl;
|
||||||
|
|
||||||
//Reading in data
|
//Reading in data
|
||||||
if (channel == 0){
|
functionGenControl::ChannelData channelData = fGenControl->channels[channelID];
|
||||||
length = fGenControl->length_CH1;
|
|
||||||
freq = fGenControl->freq_CH1;
|
|
||||||
amplitude = fGenControl->amplitude_CH1;
|
|
||||||
offset = fGenControl->offset_CH1;
|
|
||||||
samples = (unsigned char *) malloc(length);
|
|
||||||
memcpy(samples, fGenControl->samples_CH1, (unsigned int) length);
|
|
||||||
numDivides = fGenControl->divisibility_CH1;
|
|
||||||
}
|
|
||||||
else if(channel == 1){
|
|
||||||
length = fGenControl->length_CH2;
|
|
||||||
freq = fGenControl->freq_CH2;
|
|
||||||
amplitude = fGenControl->amplitude_CH2;
|
|
||||||
offset = fGenControl->offset_CH2;
|
|
||||||
samples = (unsigned char *) malloc(length);
|
|
||||||
memcpy(samples, fGenControl->samples_CH2, (unsigned int) length);
|
|
||||||
numDivides = fGenControl->divisibility_CH2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Triple mode
|
//Triple mode
|
||||||
if ((amplitude+offset) > FGEN_LIMIT){
|
if ((channelData.amplitude + channelData.offset) > FGEN_LIMIT)
|
||||||
amplitude = amplitude / 3;
|
{
|
||||||
offset = offset / 3;
|
channelData.amplitude /= 3.0;
|
||||||
fGenTriple |= ((unsigned char) !channel + 1);
|
channelData.offset /= 3.0;
|
||||||
|
fGenTriple |= uint8_t(!channelID + 1);
|
||||||
}
|
}
|
||||||
else fGenTriple &= ((unsigned char) (254 - !channel));
|
else
|
||||||
|
{
|
||||||
//qDebug() << "fGenTriple = " << fGenTriple << "fGenControl = " << fGenControl << "length = " << length << "freq = " << freq << "amplitude = " << amplitude << "offset = " << offset << "samples = " << samples;
|
fGenTriple &= uint8_t(254 - !channelID);
|
||||||
|
}
|
||||||
|
|
||||||
//Waveform scaling in V
|
//Waveform scaling in V
|
||||||
double tempDouble;
|
channelData.amplitude = (channelData.amplitude * 255) / FGEN_LIMIT;
|
||||||
amplitude = (amplitude * 255) / FGEN_LIMIT;
|
channelData.offset = (channelData.offset * 255) / FGEN_LIMIT;
|
||||||
offset = (offset * 255) / FGEN_LIMIT;
|
if (channelData.offset < FGEN_OFFSET)
|
||||||
if (offset<FGEN_OFFSET){
|
{
|
||||||
if (amplitude>5)
|
if (channelData.amplitude > 5)
|
||||||
amplitude -= FGEN_OFFSET;
|
channelData.amplitude -= FGEN_OFFSET;
|
||||||
else
|
else
|
||||||
amplitude = 0;
|
channelData.amplitude = 0;
|
||||||
offset = FGEN_OFFSET;
|
channelData.offset = FGEN_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef INVERT_TRIPLE
|
#ifdef INVERT_TRIPLE
|
||||||
|
@ -140,67 +127,63 @@ void genericUsbDriver::setFunctionGen(int channel, functionGenControl *fGenContr
|
||||||
usbSendControl(0x40, 0xa4, fGenTriple, 0, 0, NULL);
|
usbSendControl(0x40, 0xa4, fGenTriple, 0, 0, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//Applying amplitude and offset to all samples.
|
auto applyAmplitudeAndOffset = [=](unsigned char sample) -> unsigned char
|
||||||
for (int i=0;i<length;i++){
|
{
|
||||||
tempDouble = (double) samples[i];
|
return sample / 255.0 * channelData.amplitude + channelData.offset;
|
||||||
tempDouble *= amplitude;
|
};
|
||||||
tempDouble /= 255;
|
|
||||||
tempDouble += offset;
|
|
||||||
samples[i] = (unsigned char) tempDouble;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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!
|
//Need to increase size of wave if its freq too high, or too low!
|
||||||
maxDivides = numDivides;
|
{
|
||||||
bool loop_entered = false;
|
int shift = 0;
|
||||||
unsigned char *tempSamples = (unsigned char *) malloc(0);
|
|
||||||
|
|
||||||
while(length * freq > DAC_SPS){
|
while ((channelData.length >> shift) * channelData.freq > DAC_SPS)
|
||||||
loop_entered = true;
|
shift++;
|
||||||
numDivides--;
|
|
||||||
if (numDivides==0){
|
|
||||||
qDebug("numDivides = 0 - in T-stretching of genericUsbDriver:: setFunctionGen");
|
|
||||||
}
|
|
||||||
|
|
||||||
int shiftTemp = (maxDivides - numDivides);
|
if (shift != 0)
|
||||||
length = length >> 1;
|
{
|
||||||
|
channelData.divisibility -= shift;
|
||||||
|
channelData.length >>= shift;
|
||||||
|
|
||||||
free(tempSamples);
|
for (int i = 0; i < channelData.length; ++i)
|
||||||
tempSamples = (unsigned char *) malloc(length);
|
channelData.samples[i] = channelData.samples[i << shift];
|
||||||
for (int i=0; i<length;i++){
|
|
||||||
tempSamples[i] = samples[i<<shiftTemp];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(loop_entered){
|
|
||||||
samples = tempSamples;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Scaling in t here:
|
channelData.samples.resize(channelData.length);
|
||||||
// Something something maxLength something
|
channelData.samples.shrink_to_fit();
|
||||||
|
|
||||||
//Timer Setup
|
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};
|
int validClockDivs[7] = {1, 2, 4, 8, 64, 256, 1024};
|
||||||
|
auto period = [=](int division) -> int
|
||||||
|
{
|
||||||
|
return CLOCK_FREQ / (division * channelData.length * channelData.freq);
|
||||||
|
};
|
||||||
|
|
||||||
int clkSetting;
|
int* clkSettingIt = std::find_if(std::begin(validClockDivs), std::end(validClockDivs),
|
||||||
for(clkSetting = 0; clkSetting<7; clkSetting++){
|
[&](int division) -> bool { return period(division) < 65535; });
|
||||||
if ( (CLOCK_FREQ / (length * validClockDivs[clkSetting] * freq)) < 65535 )
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
int timerPeriod = CLOCK_FREQ / (length * freq * validClockDivs[clkSetting]);
|
|
||||||
|
|
||||||
clkSetting++; // Change from [0:n] to [1:n]
|
int timerPeriod = period(*clkSettingIt);
|
||||||
|
|
||||||
if(deviceMode == 5){
|
// +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");
|
qDebug("DEVICE IS IN MODE 5");
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << "First three samples:" << samples[0] << samples[1] << samples[2];
|
|
||||||
|
|
||||||
|
if (channelID)
|
||||||
|
usbSendControl(0x40, 0xa1, timerPeriod, clkSetting, channelData.length, channelData.samples.data());
|
||||||
|
else
|
||||||
|
usbSendControl(0x40, 0xa2, timerPeriod, clkSetting, channelData.length, channelData.samples.data());
|
||||||
|
|
||||||
if(channel){
|
|
||||||
usbSendControl(0x40, 0xa1, timerPeriod, clkSetting, length, samples);
|
|
||||||
}
|
|
||||||
else usbSendControl(0x40, 0xa2, timerPeriod, clkSetting, length, samples);
|
|
||||||
free(tempSamples);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,137 +0,0 @@
|
||||||
/****************************************************************************
|
|
||||||
** Resource object code
|
|
||||||
**
|
|
||||||
** Created by: The Resource Compiler for Qt version 5.9.4
|
|
||||||
**
|
|
||||||
** WARNING! All changes made in this file will be lost!
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
static const unsigned char qt_resource_data[] = {
|
|
||||||
// /home/esposch/git/labrador/Desktop_Interface/buffer_0.bmp
|
|
||||||
0x0,0x0,0x0,0x8d,
|
|
||||||
0x0,
|
|
||||||
0x0,0x28,0xb6,0x78,0x9c,0xed,0xd0,0xb1,0xd,0xc2,0x30,0x0,0x45,0xc1,0xb0,0x45,
|
|
||||||
0x6,0xa0,0xc8,0x4,0xc,0x90,0x3e,0x3b,0x30,0xa,0x53,0xb1,0x1e,0x98,0x28,0x5,
|
|
||||||
0xd5,0xd5,0x2e,0xde,0x49,0x5f,0xb2,0xec,0xc6,0x7a,0xfb,0xf1,0xde,0x96,0xd3,0x63,
|
|
||||||
0xec,0x77,0x7c,0x8e,0xdd,0xc7,0x6e,0xcb,0x7a,0xde,0xbf,0xae,0xf7,0x7f,0x9f,0x69,
|
|
||||||
0x4c,0xfb,0xb1,0x49,0xd4,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,
|
|
||||||
0x1f,0xab,0x8f,0xd5,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,
|
|
||||||
0xab,0x8f,0xd5,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,
|
|
||||||
0x8f,0xd5,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f,
|
|
||||||
0xd5,0xc7,0xea,0x63,0x73,0xf6,0xf9,0x2,0xf4,0x4,0x42,0xe7,
|
|
||||||
// /home/esposch/git/labrador/Desktop_Interface/buffer_2.bmp
|
|
||||||
0x0,0x0,0x0,0x7b,
|
|
||||||
0x0,
|
|
||||||
0x0,0x28,0xb6,0x78,0x9c,0xed,0xd0,0x31,0xd,0x80,0x30,0x14,0x45,0xd1,0xe2,0x82,
|
|
||||||
0x81,0xb1,0x3,0xa,0x10,0xc0,0x8e,0x7,0xa4,0xa0,0xa,0x57,0x78,0xa0,0x34,0xc,
|
|
||||||
0x95,0xf0,0x86,0xf3,0x73,0x7f,0xd2,0xb4,0x4b,0x73,0xf6,0xe3,0x5e,0x4b,0x9f,0xad,
|
|
||||||
0xed,0x77,0x3c,0xdb,0xd6,0xb6,0x53,0x99,0xfb,0xfd,0xf5,0xbf,0x8f,0x53,0x97,0x27,
|
|
||||||
0xa4,0xd8,0x8f,0x85,0xc4,0x87,0xf,0x1f,0x3e,0x7c,0x32,0xe3,0xc3,0x87,0xf,0x1f,
|
|
||||||
0x3e,0x99,0xf1,0xe1,0xc3,0x87,0xf,0x9f,0xcc,0xf8,0xf0,0xe1,0xc3,0x87,0x4f,0x66,
|
|
||||||
0x7c,0xf8,0xf0,0xe1,0xc3,0x27,0x33,0x3e,0x7c,0xf8,0xf0,0xe1,0x93,0x19,0x1f,0x3e,
|
|
||||||
0x7c,0xf8,0xf0,0x19,0x7b,0x1,0x6d,0x5a,0xf,0xce,
|
|
||||||
// /home/esposch/git/labrador/Desktop_Interface/buffer_1.bmp
|
|
||||||
0x0,0x0,0x0,0x97,
|
|
||||||
0x0,
|
|
||||||
0x0,0x28,0xb6,0x78,0x9c,0xed,0xd0,0xb1,0xd,0xc2,0x30,0x10,0x40,0xd1,0xb0,0x5,
|
|
||||||
0x5,0x65,0xa,0x26,0x60,0x0,0x7a,0x76,0x60,0x14,0xa6,0x62,0x2b,0x66,0x0,0x27,
|
|
||||||
0x42,0x2,0x51,0xbc,0x96,0x14,0xff,0xc9,0x27,0x9d,0xec,0xc6,0xfa,0xe7,0xcb,0xfd,
|
|
||||||
0x38,0xad,0x4e,0x63,0x96,0xf5,0x3a,0x66,0x1e,0xb3,0x9b,0xf6,0xeb,0xfd,0xed,0xfd,
|
|
||||||
0xfe,0xed,0xb9,0x19,0x3f,0x1f,0x9b,0xf,0x8f,0x2d,0x9c,0x7f,0x57,0xf9,0xa8,0x8f,
|
|
||||||
0xd5,0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f,0xd5,
|
|
||||||
0xc7,0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f,0xd5,0xc7,
|
|
||||||
0xea,0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f,0xd5,0xc7,0xea,
|
|
||||||
0x63,0xf5,0xb1,0xfa,0x58,0x7d,0xac,0x3e,0x56,0x1f,0xab,0x8f,0xd5,0xc7,0xb6,0xd9,
|
|
||||||
0xe7,0x5,0x35,0x2d,0xc9,0xf3,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char qt_resource_name[] = {
|
|
||||||
// bitmap
|
|
||||||
0x0,0x6,
|
|
||||||
0x6,0x90,0xb3,0x80,
|
|
||||||
0x0,0x62,
|
|
||||||
0x0,0x69,0x0,0x74,0x0,0x6d,0x0,0x61,0x0,0x70,
|
|
||||||
// buffer_0.bmp
|
|
||||||
0x0,0xc,
|
|
||||||
0xd,0x14,0xd0,0xc0,
|
|
||||||
0x0,0x62,
|
|
||||||
0x0,0x75,0x0,0x66,0x0,0x66,0x0,0x65,0x0,0x72,0x0,0x5f,0x0,0x30,0x0,0x2e,0x0,0x62,0x0,0x6d,0x0,0x70,
|
|
||||||
// buffer_2.bmp
|
|
||||||
0x0,0xc,
|
|
||||||
0xd,0x12,0xd0,0xc0,
|
|
||||||
0x0,0x62,
|
|
||||||
0x0,0x75,0x0,0x66,0x0,0x66,0x0,0x65,0x0,0x72,0x0,0x5f,0x0,0x32,0x0,0x2e,0x0,0x62,0x0,0x6d,0x0,0x70,
|
|
||||||
// buffer_1.bmp
|
|
||||||
0x0,0xc,
|
|
||||||
0xd,0x17,0xd0,0xc0,
|
|
||||||
0x0,0x62,
|
|
||||||
0x0,0x75,0x0,0x66,0x0,0x66,0x0,0x65,0x0,0x72,0x0,0x5f,0x0,0x31,0x0,0x2e,0x0,0x62,0x0,0x6d,0x0,0x70,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char qt_resource_struct[] = {
|
|
||||||
// :
|
|
||||||
0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x1,
|
|
||||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
|
||||||
// :/bitmap
|
|
||||||
0x0,0x0,0x0,0x0,0x0,0x2,0x0,0x0,0x0,0x3,0x0,0x0,0x0,0x2,
|
|
||||||
0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,
|
|
||||||
// :/bitmap/buffer_2.bmp
|
|
||||||
0x0,0x0,0x0,0x30,0x0,0x1,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x91,
|
|
||||||
0x0,0x0,0x1,0x66,0xe3,0x22,0x5,0x34,
|
|
||||||
// :/bitmap/buffer_0.bmp
|
|
||||||
0x0,0x0,0x0,0x12,0x0,0x1,0x0,0x0,0x0,0x1,0x0,0x0,0x0,0x0,
|
|
||||||
0x0,0x0,0x1,0x66,0xe3,0x22,0x5,0x34,
|
|
||||||
// :/bitmap/buffer_1.bmp
|
|
||||||
0x0,0x0,0x0,0x4e,0x0,0x1,0x0,0x0,0x0,0x1,0x0,0x0,0x1,0x10,
|
|
||||||
0x0,0x0,0x1,0x66,0xe3,0x22,0x5,0x34,
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef QT_NAMESPACE
|
|
||||||
# define QT_RCC_PREPEND_NAMESPACE(name) ::QT_NAMESPACE::name
|
|
||||||
# define QT_RCC_MANGLE_NAMESPACE0(x) x
|
|
||||||
# define QT_RCC_MANGLE_NAMESPACE1(a, b) a##_##b
|
|
||||||
# define QT_RCC_MANGLE_NAMESPACE2(a, b) QT_RCC_MANGLE_NAMESPACE1(a,b)
|
|
||||||
# define QT_RCC_MANGLE_NAMESPACE(name) QT_RCC_MANGLE_NAMESPACE2( \
|
|
||||||
QT_RCC_MANGLE_NAMESPACE0(name), QT_RCC_MANGLE_NAMESPACE0(QT_NAMESPACE))
|
|
||||||
#else
|
|
||||||
# define QT_RCC_PREPEND_NAMESPACE(name) name
|
|
||||||
# define QT_RCC_MANGLE_NAMESPACE(name) name
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef QT_NAMESPACE
|
|
||||||
namespace QT_NAMESPACE {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool qRegisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
|
|
||||||
|
|
||||||
bool qUnregisterResourceData(int, const unsigned char *, const unsigned char *, const unsigned char *);
|
|
||||||
|
|
||||||
#ifdef QT_NAMESPACE
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int QT_RCC_MANGLE_NAMESPACE(qInitResources_resources)();
|
|
||||||
int QT_RCC_MANGLE_NAMESPACE(qInitResources_resources)()
|
|
||||||
{
|
|
||||||
QT_RCC_PREPEND_NAMESPACE(qRegisterResourceData)
|
|
||||||
(0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_resources)();
|
|
||||||
int QT_RCC_MANGLE_NAMESPACE(qCleanupResources_resources)()
|
|
||||||
{
|
|
||||||
QT_RCC_PREPEND_NAMESPACE(qUnregisterResourceData)
|
|
||||||
(0x2, qt_resource_struct, qt_resource_name, qt_resource_data);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace {
|
|
||||||
struct initializer {
|
|
||||||
initializer() { QT_RCC_MANGLE_NAMESPACE(qInitResources_resources)(); }
|
|
||||||
~initializer() { QT_RCC_MANGLE_NAMESPACE(qCleanupResources_resources)(); }
|
|
||||||
} dummy;
|
|
||||||
}
|
|
Loading…
Reference in New Issue