'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:
Sebastián Mestre 2019-03-25 20:12:08 -03:00 committed by Chris Esposito
parent 525b03de1c
commit e6f0e24a28
5 changed files with 206 additions and 131 deletions

View File

@ -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);
}
}

View File

@ -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

View File

@ -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){

View File

@ -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);

View File

@ -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;