Skip to content

Commit

Permalink
Transmit side of BERT driver GUI is now basically done. Still have to…
Browse files Browse the repository at this point in the history
… work on timebase and receiver
  • Loading branch information
azonenberg committed Aug 27, 2023
1 parent ee88704 commit 798d00d
Show file tree
Hide file tree
Showing 8 changed files with 318 additions and 255 deletions.
215 changes: 23 additions & 192 deletions src/ngscopeclient/BERTDialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,27 +51,12 @@ BERTDialog::BERTDialog(SCPIBERT* bert, shared_ptr<BERTState> state, Session* ses
, m_bert(bert)
, m_state(state)
{
//Inputs
for(size_t i=0; i<m_bert->GetChannelCount(); i++)
m_channelNames.push_back(m_bert->GetChannel(i)->GetDisplayName());

//Set up initial empty state
m_channelUIState.resize(m_bert->GetChannelCount());

/*
//Asynchronously load rest of the state
//Create UI state for each channel
for(size_t i=0; i<m_bert->GetChannelCount(); i++)
{
//Add placeholders for non-power channels
//TODO: can we avoid spawning a thread here pointlessly?
if( (m_bert->GetInstrumentTypesForChannel(i) & Instrument::INST_LOAD) == 0)
m_futureUIState.push_back(async(launch::async, [load, i]{ BERTChannelUIState dummy; return dummy; }));
//Actual power channels get async load
else
m_futureUIState.push_back(async(launch::async, [load, i]{ return BERTChannelUIState(load, i); }));
m_channelNames.push_back(m_bert->GetChannel(i)->GetDisplayName());
m_channelUIState.push_back(BERTChannelUIState(bert, i));
}
*/
}

BERTDialog::~BERTDialog()
Expand Down Expand Up @@ -106,198 +91,44 @@ bool BERTDialog::DoRender()

ImGui::EndDisabled();
}
/*
//Grab asynchronously loaded channel state if it's ready
if(m_futureUIState.size())
{
bool allDone = true;
for(size_t i=0; i<m_futureUIState.size(); i++)
{
//Already loaded? No action needed
//if(m_channelUIState[i].m_setVoltage != "")
// continue;

//Not ready? Keep waiting
if(m_futureUIState[i].wait_for(0s) != future_status::ready)
{
allDone = false;
continue;
}
//Ready, process it
m_channelUIState[i] = m_futureUIState[i].get();
}
//Timebase settings
if(ImGui::CollapsingHeader("Timebase"))
{

if(allDone)
m_futureUIState.clear();
}

//Channel information
for(size_t i=0; i<m_bert->GetChannelCount(); i++)
{
//Skip non-load channels
if( (m_bert->GetInstrumentTypesForChannel(i) & Instrument::INST_LOAD) == 0)
if( (m_bert->GetInstrumentTypesForChannel(i) & Instrument::INST_BERT) == 0)
continue;

if(ImGui::CollapsingHeader(m_channelNames[i].c_str(), ImGuiTreeNodeFlags_DefaultOpen))
if(dynamic_cast<BERTInputChannel*>(m_bert->GetChannel(i)))
{
ImGui::PushID(m_channelNames[i].c_str());
ChannelSettings(i);
ImGui::PopID();
if(ImGui::CollapsingHeader(m_channelNames[i].c_str(), ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::PushID(m_channelNames[i].c_str());
RxChannelSettings(i);
ImGui::PopID();
}
}
}
*/

return true;
}

/**
@brief Run settings for a single channel of the load
*/
/*
void BERTDialog::ChannelSettings(size_t channel)
void BERTDialog::RxChannelSettings(size_t channel)
{
float valueWidth = 150;
Unit volts(Unit::UNIT_VOLTS);
Unit amps(Unit::UNIT_AMPS);
Unit watts(Unit::UNIT_WATTS);
Unit ohms(Unit::UNIT_OHMS);
if(ImGui::Checkbox("BERT Enable", &m_channelUIState[channel].m_bertEnabled))
m_bert->SetBERTActive(channel, m_channelUIState[channel].m_bertEnabled);
ImGui::SetNextItemOpen(true, ImGuiCond_Appearing);
if(ImGui::TreeNode("Configuration"))
{
ImGui::SetNextItemWidth(valueWidth);
if(Dialog::Combo("Voltage Range",
m_channelUIState[channel].m_voltageRangeNames,
m_channelUIState[channel].m_voltageRangeIndex))
{
m_bert->SetBERTVoltageRange(channel, m_channelUIState[channel].m_voltageRangeIndex);
}
HelpMarker("Maximum operating voltage for the load");
ImGui::SetNextItemWidth(valueWidth);
if(Dialog::Combo("Current Range",
m_channelUIState[channel].m_currentRangeNames,
m_channelUIState[channel].m_currentRangeIndex))
{
m_bert->SetBERTCurrentRange(channel, m_channelUIState[channel].m_currentRangeIndex);
}
HelpMarker("Maximum operating current for the load");
const char* modes[4] =
{
"Constant current",
"Constant voltage",
"Constant resistance",
"Constant power"
};
ImGui::SetNextItemWidth(valueWidth);
if(ImGui::Combo("Mode", (int*)&m_channelUIState[channel].m_mode, modes, 4))
{
//Turn the load off before changing mode, to avoid accidental overloading of the DUT
m_bert->SetBERTActive(channel, false);
m_channelUIState[channel].m_bertEnabled = false;
m_bert->SetBERTMode(channel, m_channelUIState[channel].m_mode);
auto& uistate = m_channelUIState[channel];

//Refresh set point with hardware config for the new mode
m_channelUIState[channel].RefreshSetPoint();
}
HelpMarker("Operating mode for the control loop");
//Update set point text if it's been changed via the filter graph
if(m_channelUIState[channel].m_committedSetPoint != m_bert->GetBERTSetPoint(channel))
m_channelUIState[channel].RefreshSetPoint();
//Set point
ImGui::SetNextItemWidth(valueWidth);
bool applySetPoint = false;
switch(m_bert->GetBERTMode(channel))
{
case BERT::MODE_CONSTANT_CURRENT:
applySetPoint = UnitInputWithExplicitApply(
"Current",
m_channelUIState[channel].m_setPoint,
m_channelUIState[channel].m_committedSetPoint,
amps);
break;
case BERT::MODE_CONSTANT_VOLTAGE:
applySetPoint = UnitInputWithExplicitApply(
"Voltage",
m_channelUIState[channel].m_setPoint,
m_channelUIState[channel].m_committedSetPoint,
volts);
break;
case BERT::MODE_CONSTANT_RESISTANCE:
applySetPoint = UnitInputWithExplicitApply(
"Resistance",
m_channelUIState[channel].m_setPoint,
m_channelUIState[channel].m_committedSetPoint,
ohms);
break;
case BERT::MODE_CONSTANT_POWER:
applySetPoint = UnitInputWithExplicitApply(
"Power",
m_channelUIState[channel].m_setPoint,
m_channelUIState[channel].m_committedSetPoint,
watts);
break;
default:
break;
}
if(applySetPoint)
m_bert->SetBERTSetPoint(channel, m_channelUIState[channel].m_committedSetPoint);
HelpMarker("Set point for the load.\n\nChanges are not pushed to hardware until you click Apply.");
ImGui::TreePop();
}
//Actual values of channels
ImGui::SetNextItemOpen(true, ImGuiCond_Appearing);
if(ImGui::TreeNode("Measured"))
{
ImGui::BeginDisabled();
ImGui::SetNextItemWidth(valueWidth);
auto svolts = volts.PrettyPrint(m_state->m_channelVoltage[channel]);
ImGui::InputText("Voltage###VMeasured", &svolts);
ImGui::EndDisabled();
HelpMarker("Measured voltage being sunk by the load");
ImGui::BeginDisabled();
ImGui::SetNextItemWidth(valueWidth);
auto scurr = amps.PrettyPrint(m_state->m_channelCurrent[channel]);
ImGui::InputText("Current###IMeasured", &scurr);
ImGui::EndDisabled();
HelpMarker("Measured current being sunk by the load");
ImGui::BeginDisabled();
ImGui::SetNextItemWidth(valueWidth);
auto pcurr = watts.PrettyPrint(m_state->m_channelVoltage[channel] * m_state->m_channelCurrent[channel]);
ImGui::InputText("Power###PCalc", &pcurr);
ImGui::EndDisabled();
HelpMarker("Measured power being sunk by the load");
ImGui::BeginDisabled();
ImGui::SetNextItemWidth(valueWidth);
auto rcurr = ohms.PrettyPrint(m_state->m_channelVoltage[channel] / m_state->m_channelCurrent[channel]);
ImGui::InputText("Resistance###RCalc", &rcurr);
ImGui::EndDisabled();
HelpMarker("Equivalent resistance of the load");
float valueWidth = 150;
ImGui::SetNextItemWidth(valueWidth);
if(Dialog::Combo("Pattern", uistate.m_patternNames, uistate.m_patternIndex))
m_bert->SetRxPattern(channel, uistate.m_patternValues[uistate.m_patternIndex]);

ImGui::TreePop();
}
ImGui::SetNextItemWidth(valueWidth);
if(ImGui::Checkbox("Invert", &m_channelUIState[channel].m_invert))
m_bert->SetRxInvert(channel, m_channelUIState[channel].m_invert);
}
*/
83 changes: 21 additions & 62 deletions src/ngscopeclient/BERTDialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,19 +41,21 @@
#include <future>

/**
@brief UI state for a single load channel
@brief UI state for a single BERT channel
Stores uncommitted values we haven't pushed to hardware, etc
*/
class BERTChannelUIState
{
public:
/*
bool m_loadEnabled;

int m_voltageRangeIndex;
std::vector<std::string> m_voltageRangeNames;
bool m_invert;

int m_patternIndex;
std::vector<std::string> m_patternNames;
std::vector<BERT::Pattern> m_patternValues;

/*
int m_currentRangeIndex;
std::vector<std::string> m_currentRangeNames;
Expand All @@ -78,65 +80,22 @@ class BERTChannelUIState
,*/ m_chan(chan)
, m_bert(bert)
{
/*
//Voltage ranges
Unit volts(Unit::UNIT_VOLTS);
auto vranges = load->GetBERTVoltageRanges(chan);
for(auto v : vranges)
m_voltageRangeNames.push_back(volts.PrettyPrint(v));
m_voltageRangeIndex = load->GetBERTVoltageRange(chan);
//Current ranges
Unit amps(Unit::UNIT_AMPS);
auto iranges = load->GetBERTCurrentRanges(chan);
for(auto i : iranges)
m_currentRangeNames.push_back(amps.PrettyPrint(i));
m_currentRangeIndex = load->GetBERTCurrentRange(chan);
RefreshSetPoint();
*/
}

/**
@brief Pulls the set point from hardware
*/
/*
void RefreshSetPoint()
{
//can happen if we're a placeholder prior to completion of async init
if(m_load == nullptr)
return;
m_committedSetPoint = m_load->GetBERTSetPoint(m_chan);
//Mode
Unit volts(Unit::UNIT_VOLTS);
Unit amps(Unit::UNIT_AMPS);
Unit watts(Unit::UNIT_WATTS);
Unit ohms(Unit::UNIT_OHMS);
switch(m_mode)
//See if the channel is a transmit channel
BERT::Pattern pat;
m_invert = m_bert->GetRxInvert(chan);
m_patternValues = m_bert->GetAvailableRxPatterns(chan);
pat = m_bert->GetRxPattern(chan);

//Fill list box
m_patternIndex = 0;
for(size_t i=0; i<m_patternValues.size(); i++)
{
case BERT::MODE_CONSTANT_CURRENT:
m_setPoint = amps.PrettyPrint(m_committedSetPoint);
break;
case BERT::MODE_CONSTANT_VOLTAGE:
m_setPoint = volts.PrettyPrint(m_committedSetPoint);
break;
case BERT::MODE_CONSTANT_POWER:
m_setPoint = watts.PrettyPrint(m_committedSetPoint);
break;
case BERT::MODE_CONSTANT_RESISTANCE:
m_setPoint = ohms.PrettyPrint(m_committedSetPoint);
break;
default:
break;
auto p = m_patternValues[i];
m_patternNames.push_back(m_bert->GetPatternName(p));
if(p == pat)
m_patternIndex = i;
}
}
*/

protected:
size_t m_chan;
Expand All @@ -157,7 +116,7 @@ class BERTDialog : public Dialog

protected:

//void ChannelSettings(size_t channel);
void RxChannelSettings(size_t channel);

///@brief Session handle so we can remove the load when closed
Session* m_session;
Expand Down
Loading

0 comments on commit 798d00d

Please sign in to comment.