mirror of https://github.com/EspoTek/Labrador.git
'Functiongencontrol refactor - part 3 (#74)
* move ChannelID to outside of functionGenControl * move ChannelData out of functionGenControl * make the genericUsbDriver fGenPtrs into an array * Make genericUsbDriver store pointers to ChannelData instead of to functionGenControl * split genericUsbDriver::setFunctionGen into two parts. Stop reassigning the fGen pointers * Big functionGenControl refactor - Create functionGen namespace - Rename functionGenControl to DualChannelController - Create a SingleChannelController class that holds all the functionality of a single channel (i.e. almost all of it). This class acts as a Qt wrapper over the actual data, it gives it the ability to emit and recieve signals while keeping the actual data copiable. - Add an alias functionGenControl = DualChannelController
This commit is contained in:
parent
525b03de1c
commit
e6f0e24a28
|
@ -1,63 +1,14 @@
|
|||
#include "functiongencontrol.h"
|
||||
#include "platformspecific.h"
|
||||
|
||||
namespace functionGen {
|
||||
|
||||
functionGenControl::functionGenControl(QWidget *parent) : QLabel(parent)
|
||||
{
|
||||
this->hide();
|
||||
ChannelData const& SingleChannelController::getData() const {
|
||||
return m_data;
|
||||
}
|
||||
|
||||
void functionGenControl::waveformName_CH1(QString newName)
|
||||
void SingleChannelController::waveformName(QString newName)
|
||||
{
|
||||
waveformName(ChannelID::CH1, newName);
|
||||
}
|
||||
|
||||
void functionGenControl::freqUpdate_CH1(double newFreq)
|
||||
{
|
||||
freqUpdate(ChannelID::CH1, newFreq);
|
||||
}
|
||||
|
||||
void functionGenControl::amplitudeUpdate_CH1(double newAmplitude)
|
||||
{
|
||||
amplitudeUpdate(ChannelID::CH1, newAmplitude);
|
||||
}
|
||||
|
||||
void functionGenControl::offsetUpdate_CH1(double newOffset)
|
||||
{
|
||||
offsetUpdate(ChannelID::CH1, newOffset);
|
||||
}
|
||||
|
||||
|
||||
void functionGenControl::waveformName_CH2(QString newName)
|
||||
{
|
||||
waveformName(ChannelID::CH2, newName);
|
||||
}
|
||||
|
||||
void functionGenControl::freqUpdate_CH2(double newFreq)
|
||||
{
|
||||
freqUpdate(ChannelID::CH2, newFreq);
|
||||
}
|
||||
|
||||
void functionGenControl::amplitudeUpdate_CH2(double newAmplitude)
|
||||
{
|
||||
amplitudeUpdate(ChannelID::CH2, newAmplitude);
|
||||
}
|
||||
|
||||
void functionGenControl::offsetUpdate_CH2(double newOffset)
|
||||
{
|
||||
offsetUpdate(ChannelID::CH2, newOffset);
|
||||
}
|
||||
|
||||
|
||||
functionGenControl::ChannelData& functionGenControl::getChannelData(ChannelID channelID)
|
||||
{
|
||||
return channels[static_cast<int>(channelID)];
|
||||
}
|
||||
|
||||
void functionGenControl::waveformName(ChannelID channelID, QString newName)
|
||||
{
|
||||
ChannelData& channel = getChannelData(channelID);
|
||||
|
||||
qDebug() << "newName = " << newName;
|
||||
newName.append(".tlw");
|
||||
|
||||
|
@ -81,16 +32,16 @@ void functionGenControl::waveformName(ChannelID channelID, QString newName)
|
|||
|
||||
line = fptr.readLine();
|
||||
strcpy(divisibilityString, line.data());
|
||||
sscanf(divisibilityString, "%d", &channel.divisibility);
|
||||
sscanf(divisibilityString, "%d", &m_data.divisibility);
|
||||
qDebug() << "divisibilityString" << divisibilityString;
|
||||
|
||||
qDebug() << "Length = " << length;
|
||||
qDebug() << "Divisibility = " << channel.divisibility;
|
||||
qDebug() << "Divisibility = " << m_data.divisibility;
|
||||
|
||||
QByteArray remainingData = fptr.readAll();
|
||||
char *dataString = remainingData.data();
|
||||
|
||||
channel.samples.resize(length);
|
||||
m_data.samples.resize(length);
|
||||
|
||||
int dummy;
|
||||
char *dataStringCurrent = dataString;
|
||||
|
@ -98,7 +49,7 @@ void functionGenControl::waveformName(ChannelID channelID, QString newName)
|
|||
{
|
||||
sscanf(dataStringCurrent, "%d", &dummy);
|
||||
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
||||
channel.samples[i] = static_cast<uint8_t>(dummy);
|
||||
m_data.samples[i] = static_cast<uint8_t>(dummy);
|
||||
}
|
||||
|
||||
#else
|
||||
|
@ -124,12 +75,12 @@ void functionGenControl::waveformName(ChannelID channelID, QString newName)
|
|||
}
|
||||
while ((divisibilityString[0] == '\r') || (divisibilityString[0] == '\n'));
|
||||
|
||||
sscanf(divisibilityString, "%d", &channel.divisibility);
|
||||
sscanf(divisibilityString, "%d", &m_data.divisibility);
|
||||
|
||||
qDebug() << "Length = " << length;
|
||||
qDebug() << "Divisibility = " << channel.divisibility;
|
||||
qDebug() << "Divisibility = " << m_data.divisibility;
|
||||
|
||||
channel.samples.resize(length);
|
||||
m_data.samples.resize(length);
|
||||
|
||||
char *dataString = (char *) malloc(length*5+1);
|
||||
fgets(dataString, length*5+1, fptr);
|
||||
|
@ -140,54 +91,142 @@ void functionGenControl::waveformName(ChannelID channelID, QString newName)
|
|||
{
|
||||
sscanf(dataStringCurrent, "%d", &dummy);
|
||||
dataStringCurrent += strcspn(dataStringCurrent, "\t") + 1;
|
||||
channel.samples[i] = static_cast<uint8_t>(dummy);
|
||||
m_data.samples[i] = static_cast<uint8_t>(dummy);
|
||||
}
|
||||
|
||||
free(dataString);
|
||||
fclose(fptr);
|
||||
#endif
|
||||
|
||||
double newMaxFreq = DAC_SPS / (length >> (channel.divisibility - 1));
|
||||
double newMaxFreq = DAC_SPS / (length >> (m_data.divisibility - 1));
|
||||
double newMinFreq = double(CLOCK_FREQ) / 1024.0 / 65535.0 / static_cast<double>(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.
|
||||
switch (channelID)
|
||||
{
|
||||
case ChannelID::CH1:
|
||||
setMaxFreq_CH1(newMaxFreq);
|
||||
setMinFreq_CH1(newMinFreq);
|
||||
break;
|
||||
case ChannelID::CH2:
|
||||
setMaxFreq_CH2(newMaxFreq);
|
||||
setMinFreq_CH2(newMinFreq);
|
||||
break;
|
||||
}
|
||||
setMaxFreq(newMaxFreq);
|
||||
setMinFreq(newMinFreq);
|
||||
|
||||
functionGenToUpdate(channelID, this);
|
||||
notifyUpdate(this);
|
||||
}
|
||||
|
||||
void functionGenControl::freqUpdate(ChannelID channelID, double newFreq)
|
||||
void SingleChannelController::freqUpdate(double newFreq)
|
||||
{
|
||||
qDebug() << "newFreq" << int(channelID) << " = " << newFreq;
|
||||
getChannelData(channelID).freq = newFreq;
|
||||
functionGenToUpdate(channelID, this);
|
||||
qDebug() << "newFreq = " << newFreq;
|
||||
m_data.freq = newFreq;
|
||||
notifyUpdate(this);
|
||||
}
|
||||
|
||||
void functionGenControl::amplitudeUpdate(ChannelID channelID, double newAmplitude)
|
||||
void SingleChannelController::amplitudeUpdate(double newAmplitude)
|
||||
{
|
||||
qDebug() << "newAmplitude" << int(channelID) << " = " << newAmplitude;
|
||||
getChannelData(channelID).amplitude = newAmplitude;
|
||||
functionGenToUpdate(channelID, this);
|
||||
qDebug() << "newAmplitude = " << newAmplitude;
|
||||
m_data.amplitude = newAmplitude;
|
||||
notifyUpdate(this);
|
||||
}
|
||||
|
||||
void functionGenControl::offsetUpdate(ChannelID channelID, double newOffset)
|
||||
void SingleChannelController::offsetUpdate(double newOffset)
|
||||
{
|
||||
qDebug() << "newOffset" << int(channelID) << " = " << newOffset;
|
||||
getChannelData(channelID).offset = newOffset;
|
||||
functionGenToUpdate(channelID, 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
|
||||
|
||||
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::setMaxFreq,
|
||||
this, &DualChannelController::setMaxFreq_CH1);
|
||||
|
||||
connect(controller1, &SingleChannelController::setMinFreq,
|
||||
this, &DualChannelController::setMinFreq_CH1);
|
||||
|
||||
|
||||
connect(controller2, &SingleChannelController::notifyUpdate,
|
||||
this, [=](SingleChannelController* ptr){ this->functionGenToUpdate(ChannelID::CH2, ptr); });
|
||||
|
||||
connect(controller1, &SingleChannelController::setMaxFreq,
|
||||
this, &DualChannelController::setMaxFreq_CH2);
|
||||
|
||||
connect(controller1, &SingleChannelController::setMinFreq,
|
||||
this, &DualChannelController::setMinFreq_CH2);
|
||||
|
||||
this->hide();
|
||||
}
|
||||
|
||||
|
||||
SingleChannelController* DualChannelController::getChannelController(ChannelID 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);
|
||||
}
|
||||
|
||||
void DualChannelController::freqUpdate(ChannelID channelID, double newFreq)
|
||||
{
|
||||
getChannelController(channelID)->freqUpdate(newFreq);
|
||||
}
|
||||
|
||||
void DualChannelController::amplitudeUpdate(ChannelID channelID, double newAmplitude)
|
||||
{
|
||||
getChannelController(channelID)->amplitudeUpdate(newAmplitude);
|
||||
}
|
||||
|
||||
void DualChannelController::offsetUpdate(ChannelID channelID, double newOffset)
|
||||
{
|
||||
getChannelController(channelID)->offsetUpdate(newOffset);
|
||||
}
|
||||
|
||||
|
||||
void DualChannelController::waveformName_CH1(QString newName)
|
||||
{
|
||||
waveformName(ChannelID::CH1, newName);
|
||||
}
|
||||
|
||||
void DualChannelController::freqUpdate_CH1(double newFreq)
|
||||
{
|
||||
freqUpdate(ChannelID::CH1, newFreq);
|
||||
}
|
||||
|
||||
void DualChannelController::amplitudeUpdate_CH1(double newAmplitude)
|
||||
{
|
||||
amplitudeUpdate(ChannelID::CH1, newAmplitude);
|
||||
}
|
||||
|
||||
void DualChannelController::offsetUpdate_CH1(double newOffset)
|
||||
{
|
||||
offsetUpdate(ChannelID::CH1, newOffset);
|
||||
}
|
||||
|
||||
|
||||
void DualChannelController::waveformName_CH2(QString newName)
|
||||
{
|
||||
waveformName(ChannelID::CH2, newName);
|
||||
}
|
||||
|
||||
void DualChannelController::freqUpdate_CH2(double newFreq)
|
||||
{
|
||||
freqUpdate(ChannelID::CH2, newFreq);
|
||||
}
|
||||
|
||||
void DualChannelController::amplitudeUpdate_CH2(double newAmplitude)
|
||||
{
|
||||
amplitudeUpdate(ChannelID::CH2, newAmplitude);
|
||||
}
|
||||
|
||||
void DualChannelController::offsetUpdate_CH2(double newOffset)
|
||||
{
|
||||
offsetUpdate(ChannelID::CH2, newOffset);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -13,54 +13,83 @@
|
|||
|
||||
//functionGenControl is a centralised object to control all of the high-level function gen commands for both channels.
|
||||
|
||||
class functionGenControl : public QLabel
|
||||
namespace functionGen {
|
||||
|
||||
enum class ChannelID
|
||||
{
|
||||
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;
|
||||
};
|
||||
|
||||
class SingleChannelController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ChannelData const& getData() const;
|
||||
|
||||
signals:
|
||||
void notifyUpdate(SingleChannelController* controller);
|
||||
void setMaxFreq(double maxFreq);
|
||||
void setMinFreq(double minFreq);
|
||||
|
||||
public slots:
|
||||
void waveformName(QString newName);
|
||||
void freqUpdate(double newFreq);
|
||||
void amplitudeUpdate(double newAmplitude);
|
||||
void offsetUpdate(double newOffset);
|
||||
|
||||
private:
|
||||
ChannelData m_data;
|
||||
};
|
||||
|
||||
class DualChannelController : public QLabel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
struct ChannelData
|
||||
{
|
||||
std::vector<uint8_t> samples;
|
||||
int divisibility;
|
||||
double freq = 1000.0;
|
||||
double amplitude = 0.0;
|
||||
double offset = 0.0;
|
||||
};
|
||||
|
||||
enum class ChannelID
|
||||
{
|
||||
CH1 = 0,
|
||||
CH2 = 1
|
||||
};
|
||||
|
||||
explicit functionGenControl(QWidget *parent = 0);
|
||||
|
||||
ChannelData channels[2];
|
||||
explicit DualChannelController(QWidget *parent = 0);
|
||||
|
||||
public:
|
||||
|
||||
ChannelData& getChannelData(ChannelID channelID);
|
||||
SingleChannelController* getChannelController(ChannelID channelID);
|
||||
|
||||
signals:
|
||||
void functionGenToUpdate(ChannelID channel, functionGenControl *fGenControl);
|
||||
void functionGenToUpdate(ChannelID channel, SingleChannelController* fGenControl);
|
||||
void setMaxFreq_CH1(double maxFreq);
|
||||
void setMinFreq_CH1(double minFreq);
|
||||
void setMaxFreq_CH2(double maxFreq);
|
||||
void setMinFreq_CH2(double minFreq);
|
||||
|
||||
public slots:
|
||||
void waveformName(ChannelID channelId, QString newName);
|
||||
void freqUpdate(ChannelID channelId, double newFreq);
|
||||
void amplitudeUpdate(ChannelID channelId, double newAmplitude);
|
||||
void offsetUpdate(ChannelID channelId, double newOffset);
|
||||
void waveformName(ChannelID channelID, QString newName);
|
||||
void freqUpdate(ChannelID channelID, double newFreq);
|
||||
void amplitudeUpdate(ChannelID channelID, double newAmplitude);
|
||||
void offsetUpdate(ChannelID channelID, double newOffset);
|
||||
|
||||
void waveformName_CH1(QString newName);
|
||||
void freqUpdate_CH1(double newFreq);
|
||||
void amplitudeUpdate_CH1(double newAmplitude);
|
||||
void offsetUpdate_CH1(double newOffset);
|
||||
|
||||
void waveformName_CH2(QString newName);
|
||||
void freqUpdate_CH2(double newFreq);
|
||||
void amplitudeUpdate_CH2(double newAmplitude);
|
||||
void offsetUpdate_CH2(double newOffset);
|
||||
|
||||
private:
|
||||
SingleChannelController m_channels[2];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
using functionGenControl = functionGen::DualChannelController;
|
||||
|
||||
#endif // FUNCTIONGENCONTROL_H
|
||||
|
|
|
@ -75,9 +75,8 @@ void genericUsbDriver::setPsu(double voltage){
|
|||
qDebug() << "Going to send value " << dutyPsu;
|
||||
}
|
||||
|
||||
void genericUsbDriver::setFunctionGen(functionGenControl::ChannelID channelID, functionGenControl *fGenControl)
|
||||
void genericUsbDriver::setFunctionGen(functionGen::ChannelID channelID, functionGen::SingleChannelController* fGenControl)
|
||||
{
|
||||
using ChannelID = functionGenControl::ChannelID;
|
||||
////////////////////////////
|
||||
////NO RESIZING (YET)!!!////
|
||||
////////////////////////////
|
||||
|
@ -87,13 +86,15 @@ void genericUsbDriver::setFunctionGen(functionGenControl::ChannelID channelID, f
|
|||
//////////////////////////////////////
|
||||
|
||||
//For recalling on crash.
|
||||
if (channelID == ChannelID::CH1)
|
||||
fGenPtr_CH1 = fGenControl;
|
||||
else
|
||||
fGenPtr_CH2 = fGenControl;
|
||||
fGenPtrData[(int)channelID] = fGenControl;
|
||||
|
||||
sendFunctionGenData(channelID);
|
||||
}
|
||||
|
||||
void genericUsbDriver::sendFunctionGenData(functionGen::ChannelID channelID)
|
||||
{
|
||||
//Reading in data
|
||||
functionGenControl::ChannelData channelData = fGenControl->getChannelData(channelID);
|
||||
functionGen::ChannelData channelData = fGenPtrData[(int)channelID]->getData();
|
||||
|
||||
//Triple mode
|
||||
if ((channelData.amplitude + channelData.offset) > FGEN_LIMIT)
|
||||
|
@ -180,12 +181,13 @@ void genericUsbDriver::setFunctionGen(functionGenControl::ChannelID channelID, f
|
|||
qDebug("DEVICE IS IN MODE 5");
|
||||
|
||||
|
||||
if (channelID == ChannelID::CH2)
|
||||
if (channelID == functionGen::ChannelID::CH2)
|
||||
usbSendControl(0x40, 0xa1, timerPeriod, clkSetting, channelData.samples.size(), channelData.samples.data());
|
||||
else
|
||||
usbSendControl(0x40, 0xa2, timerPeriod, clkSetting, channelData.samples.size(), channelData.samples.data());
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
void genericUsbDriver::newDig(int digState){
|
||||
|
@ -205,8 +207,11 @@ void genericUsbDriver::setDeviceMode(int mode){
|
|||
deviceMode = mode;
|
||||
usbSendControl(0x40, 0xa5, (mode == 5 ? 0 : mode), gainMask, 0, NULL);
|
||||
|
||||
if (fGenPtr_CH1 != NULL) setFunctionGen(functionGenControl::ChannelID::CH1, fGenPtr_CH1);
|
||||
if (fGenPtr_CH2 != NULL) setFunctionGen(functionGenControl::ChannelID::CH2, fGenPtr_CH2);
|
||||
if (fGenPtrData[(int)functionGen::ChannelID::CH1] != NULL)
|
||||
sendFunctionGenData(functionGen::ChannelID::CH1);
|
||||
|
||||
if (fGenPtrData[(int)functionGen::ChannelID::CH2] != NULL)
|
||||
sendFunctionGenData(functionGen::ChannelID::CH2);
|
||||
|
||||
//switch on new deviceMode!!
|
||||
switch(deviceMode){
|
||||
|
|
|
@ -76,7 +76,7 @@ protected:
|
|||
//State Vars
|
||||
unsigned char fGenTriple=0;
|
||||
unsigned short gainMask = 2056;
|
||||
functionGenControl *fGenPtr_CH1 = NULL, *fGenPtr_CH2 = NULL;
|
||||
functionGen::SingleChannelController* fGenPtrData[2] = {NULL, NULL};
|
||||
int dutyPsu = 0;
|
||||
double currentPsuVoltage;
|
||||
int digitalPinState = 0;
|
||||
|
@ -115,7 +115,8 @@ signals:
|
|||
void calibrateMe(void);
|
||||
public slots:
|
||||
void setPsu(double voltage);
|
||||
void setFunctionGen(functionGenControl::ChannelID channel, functionGenControl *fGenControl);
|
||||
void setFunctionGen(functionGen::ChannelID channelID, functionGen::SingleChannelController *fGenControl);
|
||||
void sendFunctionGenData(functionGen::ChannelID channelID);
|
||||
void setDeviceMode(int mode);
|
||||
void newDig(int digState);
|
||||
void psuTick(void);
|
||||
|
|
|
@ -1363,13 +1363,14 @@ void MainWindow::reinitUsbStage2(void){
|
|||
}
|
||||
|
||||
void MainWindow::resetUsbState(void){
|
||||
using functionGen::ChannelID;
|
||||
//ui->controller_iso->driver->setDeviceMode(deviceMode);
|
||||
//ui->controller_iso->driver->setPsu(currentPsuVoltage);
|
||||
ui->psuSlider->poke();
|
||||
//ui->controller_iso->driver->newDig(digitalPinState);
|
||||
ui->bufferDisplay->poke();
|
||||
ui->controller_iso->driver->setFunctionGen(functionGenControl::ChannelID::CH1, ui->controller_fg);
|
||||
ui->controller_iso->driver->setFunctionGen(functionGenControl::ChannelID::CH2, ui->controller_fg);
|
||||
ui->controller_iso->driver->setFunctionGen(ChannelID::CH1, ui->controller_fg->getChannelController(ChannelID::CH1));
|
||||
ui->controller_iso->driver->setFunctionGen(ChannelID::CH2, ui->controller_fg->getChannelController(ChannelID::CH2));
|
||||
|
||||
ui->controller_iso->clearBuffers(1,1,1);
|
||||
ui->controller_iso->doNotTouchGraph = false;
|
||||
|
|
Loading…
Reference in New Issue