Skip to content

Commit 7e51df9

Browse files
committed
1 parent eee5a5b commit 7e51df9

File tree

3 files changed

+157
-67
lines changed

3 files changed

+157
-67
lines changed

src/eez/function_generator.cpp

+153-67
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include <eez/index.h>
3131
#include <eez/hmi.h>
3232
#include <eez/util.h>
33+
#include <eez/system.h>
3334
#include <eez/gui/gui.h>
3435
#include <eez/modules/psu/psu.h>
3536
#include <eez/modules/psu/channel_dispatcher.h>
@@ -185,20 +186,25 @@ static const float PREVIEW_PERIOD_MIN = 0.001f;
185186
static const float PREVIEW_PERIOD_DEF = 0.2f;
186187
float g_previewPeriod = PREVIEW_PERIOD_DEF;
187188

189+
int g_funcGenChannelIndex;
190+
uint64_t g_tickCountAtStart;
191+
188192
WaveformFunction g_waveFormFuncU[CH_MAX];
189193
float g_phiU[CH_MAX];
190194
float g_dphiU[CH_MAX];
191195
float g_amplitudeU[CH_MAX];
192196
float g_offsetU[CH_MAX];
193197
float g_dutyCycleU[CH_MAX];
194198
float g_freqU[CH_MAX];
199+
bool g_isDcSetU[CH_MAX];
195200

196201
WaveformFunction g_waveFormFuncI[CH_MAX];
197202
float g_phiI[CH_MAX];
198203
float g_dphiI[CH_MAX];
199204
float g_amplitudeI[CH_MAX];
200205
float g_offsetI[CH_MAX];
201206
float g_dutyCycleI[CH_MAX];
207+
bool g_isDcSetI[CH_MAX];
202208

203209
bool g_dprogStateModified[CH_MAX];
204210
bool g_currentRangeModified[CH_MAX];
@@ -417,6 +423,15 @@ class FunctionGeneratorPage : public SetPage {
417423
const Style* style = getStyle(widget->style);
418424
drawRectangle(widgetCursor.x, widgetCursor.y, (int)widget->w, (int)widget->h, style, false, false, true);
419425

426+
int D;
427+
if (m_selectedResources.m_numResources <= 2) {
428+
D = 20;
429+
} else if (m_selectedResources.m_numResources <= 4) {
430+
D = 10;
431+
} else {
432+
D = 5;
433+
}
434+
420435
float minU = FLT_MAX;
421436
float maxU = -FLT_MAX;
422437

@@ -502,14 +517,14 @@ class FunctionGeneratorPage : public SetPage {
502517
digitalWaveformParameters.offset = 0;
503518
}
504519

505-
drawWaveform(widgetCursor, digitalWaveformParameters, g_previewPeriod, 0, 1.0f);
520+
drawWaveform(widgetCursor, digitalWaveformParameters, g_previewPeriod, 0, 1.0f, D);
506521

507522
digitalIndex++;
508523
} else {
509524
float min = waveformParameters.resourceType == FUNCTION_GENERATOR_RESOURCE_TYPE_U ? minU : minI;
510525
float max = waveformParameters.resourceType == FUNCTION_GENERATOR_RESOURCE_TYPE_U ? maxU : maxI;
511526

512-
drawWaveform(widgetCursor, waveformParameters, g_previewPeriod, min, max);
527+
drawWaveform(widgetCursor, waveformParameters, g_previewPeriod, min, max, D);
513528
}
514529
}
515530

@@ -530,17 +545,17 @@ class FunctionGeneratorPage : public SetPage {
530545
digitalWaveformParameters.offset = 0;
531546
}
532547

533-
drawWaveform(widgetCursor, digitalWaveformParameters, g_previewPeriod, 0, 1.0f, true);
534-
drawWaveform(widgetCursor, digitalWaveformParameters, g_previewPeriod, 0, 1.0f, true, 1);
548+
drawWaveform(widgetCursor, digitalWaveformParameters, g_previewPeriod, 0, 1.0f, D, true);
549+
drawWaveform(widgetCursor, digitalWaveformParameters, g_previewPeriod, 0, 1.0f, D, true, 1);
535550
} else {
536551
float min = waveformParameters.resourceType == FUNCTION_GENERATOR_RESOURCE_TYPE_U ? minU : minI;
537552
float max = waveformParameters.resourceType == FUNCTION_GENERATOR_RESOURCE_TYPE_U ? maxU : maxI;
538-
drawWaveform(widgetCursor, waveformParameters, g_previewPeriod, min, max, true);
539-
drawWaveform(widgetCursor, waveformParameters, g_previewPeriod, min, max, true, 1);
553+
drawWaveform(widgetCursor, waveformParameters, g_previewPeriod, min, max, D, true);
554+
drawWaveform(widgetCursor, waveformParameters, g_previewPeriod, min, max, D, true, 1);
540555
}
541556
}
542557

543-
static void drawWaveform(const WidgetCursor &widgetCursor, WaveformParameters &waveformParameters, float T, float min, float max, bool selected = false, int yOffset = 0) {
558+
static void drawWaveform(const WidgetCursor &widgetCursor, WaveformParameters &waveformParameters, float T, float min, float max, int D, bool selected = false, int yOffset = 0) {
544559
const Widget *widget = widgetCursor.widget;
545560
const Style* style = getStyle(widget->style);
546561
font::Font font = styleGetFont(style);
@@ -600,7 +615,6 @@ class FunctionGeneratorPage : public SetPage {
600615
float yt2 = ytMin;
601616

602617
if (fi2 - fi1 < 2 * M_PI || waveformParameters.waveform == WAVEFORM_DC) {
603-
int D = 20;
604618
float dfi = (fi2 - fi1) / D;
605619
for (int i = 0; i < D; i++) {
606620
float fi = fi1 + dfi * i;
@@ -696,7 +710,7 @@ class FunctionGeneratorPage : public SetPage {
696710

697711
if (scrollPosition != m_scrollPosition) {
698712
m_scrollPosition = scrollPosition;
699-
refreshScreen();
713+
//refreshScreen();
700714
}
701715
}
702716

@@ -1804,29 +1818,34 @@ void reloadWaveformParameters() {
18041818
#endif
18051819
if (waveformParameters.resourceType == FUNCTION_GENERATOR_RESOURCE_TYPE_U) {
18061820
g_waveFormFuncU[channel->channelIndex] = getWaveformFunction(waveformParameters);
1807-
g_dutyCycleU[channel->channelIndex] = g_dutyCycle;
1808-
g_phiU[channel->channelIndex] = 2.0 * M_PI * waveformParameters.phaseShift / 360.0f;
1809-
g_dphiU[channel->channelIndex] = 2.0 * M_PI * waveformParameters.frequency * PERIOD;
18101821

18111822
if (waveformParameters.waveform == WAVEFORM_DC) {
1823+
g_phiU[channel->channelIndex] = 0.0f;
1824+
g_dphiU[channel->channelIndex] = 1.0f;
18121825
g_amplitudeU[channel->channelIndex] = 0.0f;
18131826
g_offsetU[channel->channelIndex] = waveformParameters.amplitude;
1814-
g_freqU[channel->channelIndex] = 0;
1827+
g_isDcSetU[channel->channelIndex] = false;
18151828
} else {
1829+
g_dutyCycleU[channel->channelIndex] = g_dutyCycle;
1830+
g_phiU[channel->channelIndex] = 2.0 * M_PI * waveformParameters.phaseShift / 360.0f;
1831+
g_dphiU[channel->channelIndex] = 2.0 * M_PI * waveformParameters.frequency * PERIOD;
18161832
g_amplitudeU[channel->channelIndex] = waveformParameters.amplitude;
18171833
g_offsetU[channel->channelIndex] = waveformParameters.offset;
18181834
g_freqU[channel->channelIndex] = waveformParameters.frequency;
18191835
}
18201836
} else {
18211837
g_waveFormFuncI[channel->channelIndex] = getWaveformFunction(waveformParameters);
1822-
g_dutyCycleI[channel->channelIndex] = g_dutyCycle;
1823-
g_phiI[channel->channelIndex] = 2.0 * M_PI * waveformParameters.phaseShift / 360.0f;
1824-
g_dphiI[channel->channelIndex] = 2.0 * M_PI * waveformParameters.frequency * PERIOD;
18251838

18261839
if (waveformParameters.waveform == WAVEFORM_DC) {
1840+
g_phiI[channel->channelIndex] = 0.0f;
1841+
g_dphiI[channel->channelIndex] = 1.0f;
18271842
g_amplitudeI[channel->channelIndex] = 0.0f;
18281843
g_offsetI[channel->channelIndex] = waveformParameters.amplitude;
1844+
g_isDcSetI[channel->channelIndex] = false;
18291845
} else {
1846+
g_dutyCycleI[channel->channelIndex] = g_dutyCycle;
1847+
g_phiI[channel->channelIndex] = 2.0 * M_PI * waveformParameters.phaseShift / 360.0f;
1848+
g_dphiI[channel->channelIndex] = 2.0 * M_PI * waveformParameters.frequency * PERIOD;
18301849
g_amplitudeI[channel->channelIndex] = waveformParameters.amplitude;
18311850
g_offsetI[channel->channelIndex] = waveformParameters.offset;
18321851
}
@@ -1836,15 +1855,15 @@ void reloadWaveformParameters() {
18361855
if (channel->getCurrentRangeSelectionMode() == CURRENT_RANGE_SELECTION_USE_BOTH) {
18371856
float max = getMax(waveformParameters);
18381857

1839-
g_savedCurrentLimit[i] = channel->getCurrentLimit();
1858+
g_savedCurrentLimit[channel->channelIndex] = channel->getCurrentLimit();
18401859

18411860
if (max > 0.05f) {
18421861
channel_dispatcher::setCurrentRangeSelectionMode(*channel, CURRENT_RANGE_SELECTION_ALWAYS_HIGH);
18431862
} else {
18441863
channel_dispatcher::setCurrentRangeSelectionMode(*channel, CURRENT_RANGE_SELECTION_ALWAYS_LOW);
18451864
}
18461865

1847-
g_currentRangeModified[i] = true;
1866+
g_currentRangeModified[channel->channelIndex] = true;
18481867
}
18491868
}
18501869
}
@@ -1853,6 +1872,16 @@ void reloadWaveformParameters() {
18531872
#endif
18541873
}
18551874
}
1875+
1876+
g_funcGenChannelIndex = 0;
1877+
1878+
#if defined(EEZ_PLATFORM_STM32)
1879+
g_tickCountAtStart = g_tickCount;
1880+
#endif
1881+
1882+
#if defined(EEZ_PLATFORM_SIMULATOR)
1883+
g_tickCountAtStart = millis() * 1 / (1000 * PERIOD);
1884+
#endif
18561885
}
18571886

18581887
void tick() {
@@ -1866,7 +1895,23 @@ void tick() {
18661895

18671896
int trackingChannel = -1;
18681897

1869-
for (int i = 0; i < CH_NUM; i++) {
1898+
uint64_t tickCount;
1899+
1900+
#if defined(EEZ_PLATFORM_STM32)
1901+
tickCount = g_tickCount;
1902+
#endif
1903+
1904+
#if defined(EEZ_PLATFORM_SIMULATOR)
1905+
tickCount = millis() * 1 / (1000 * PERIOD);
1906+
#endif
1907+
1908+
uint64_t tickDiff = tickCount - g_tickCountAtStart;
1909+
1910+
static const int MAX_VALUE_CHANGES_PER_TICK = 2;
1911+
int n = MAX_VALUE_CHANGES_PER_TICK;
1912+
for (int j = 0; j < CH_NUM && n > 0; j++) {
1913+
int i = g_funcGenChannelIndex;
1914+
g_funcGenChannelIndex = (g_funcGenChannelIndex + 1) % CH_NUM;
18701915
Channel &channel = Channel::get(i);
18711916

18721917
if (channel.flags.trackingEnabled) {
@@ -1880,60 +1925,68 @@ void tick() {
18801925
}
18811926

18821927
if (channel.flags.voltageTriggerMode == TRIGGER_MODE_FUNCTION_GENERATOR) {
1883-
g_dutyCycle = g_dutyCycleU[i];
1884-
float value = g_offsetU[i] + g_amplitudeU[i] * g_waveFormFuncU[i](g_phiU[i]) / 2.0f;
1885-
1886-
g_phiU[i] += g_dphiU[i];
1887-
while (g_phiU[i] >= 2.0f * M_PI_F) {
1888-
g_phiU[i] -= 2.0f * M_PI_F;
1889-
}
1928+
if (g_waveFormFuncU[i] != dcf || !g_isDcSetU[i]) {
1929+
g_dutyCycle = g_dutyCycleU[i];
1930+
float phi = fmod(g_phiU[i] + tickDiff * g_dphiU[i], 2.0f * M_PI_F);
1931+
float value = g_offsetU[i] + g_amplitudeU[i] * g_waveFormFuncU[i](phi) / 2.0f;
1932+
1933+
if (channel_dispatcher::getUSet(channel) != value) {
1934+
if (!io_pins::isInhibited()) {
1935+
if (channel.isVoltageLimitExceeded(value)) {
1936+
g_errorChannelIndex = channel.channelIndex;
1937+
psuErrorMessage(channel.channelIndex, MakeScpiErrorValue(SCPI_ERROR_VOLTAGE_LIMIT_EXCEEDED));
1938+
trigger::abort();
1939+
return;
1940+
}
18901941

1891-
if (!io_pins::isInhibited()) {
1892-
if (channel.isVoltageLimitExceeded(value)) {
1893-
g_errorChannelIndex = channel.channelIndex;
1894-
psuErrorMessage(channel.channelIndex, MakeScpiErrorValue(SCPI_ERROR_VOLTAGE_LIMIT_EXCEEDED));
1895-
trigger::abort();
1896-
return;
1897-
}
1942+
int err;
1943+
if (channel.isPowerLimitExceeded(value, channel.i.set, &err)) {
1944+
g_errorChannelIndex = channel.channelIndex;
1945+
psuErrorMessage(channel.channelIndex, MakeScpiErrorValue(err));
1946+
trigger::abort();
1947+
return;
1948+
}
18981949

1899-
int err;
1900-
if (channel.isPowerLimitExceeded(value, channel.i.set, &err)) {
1901-
g_errorChannelIndex = channel.channelIndex;
1902-
psuErrorMessage(channel.channelIndex, MakeScpiErrorValue(err));
1903-
trigger::abort();
1904-
return;
1950+
channel_dispatcher::setVoltage(channel, value);
1951+
g_isDcSetU[i] = true;
1952+
n--;
1953+
}
1954+
} else {
1955+
g_isDcSetU[i] = true;
19051956
}
1906-
1907-
channel_dispatcher::setVoltage(channel, value);
19081957
}
19091958
}
19101959

19111960
if (channel.flags.currentTriggerMode == TRIGGER_MODE_FUNCTION_GENERATOR) {
1912-
g_dutyCycle = g_dutyCycleI[i];
1913-
float value = g_offsetI[i] + g_amplitudeI[i] * g_waveFormFuncI[i](g_phiI[i]) / 2.0f;
1914-
1915-
g_phiI[i] += g_dphiI[i];
1916-
if (g_phiI[i] >= 2.0f * M_PI_F) {
1917-
g_phiI[i] -= 2.0f * M_PI_F;
1918-
}
1961+
if (g_waveFormFuncI[i] != dcf || !g_isDcSetI[i]) {
1962+
g_dutyCycle = g_dutyCycleI[i];
1963+
float phi = fmod(g_phiI[i] + tickDiff * g_dphiI[i], 2.0f * M_PI_F);
1964+
float value = g_offsetI[i] + g_amplitudeI[i] * g_waveFormFuncI[i](phi) / 2.0f;
1965+
1966+
if (channel_dispatcher::getISet(channel) != value) {
1967+
if (!io_pins::isInhibited()) {
1968+
if (channel.isCurrentLimitExceeded(value)) {
1969+
g_errorChannelIndex = channel.channelIndex;
1970+
psuErrorMessage(channel.channelIndex, MakeScpiErrorValue(SCPI_ERROR_CURRENT_LIMIT_EXCEEDED));
1971+
trigger::abort();
1972+
return;
1973+
}
19191974

1920-
if (!io_pins::isInhibited()) {
1921-
if (channel.isCurrentLimitExceeded(value)) {
1922-
g_errorChannelIndex = channel.channelIndex;
1923-
psuErrorMessage(channel.channelIndex, MakeScpiErrorValue(SCPI_ERROR_CURRENT_LIMIT_EXCEEDED));
1924-
trigger::abort();
1925-
return;
1926-
}
1975+
int err;
1976+
if (channel.isPowerLimitExceeded(channel.u.set, value, &err)) {
1977+
g_errorChannelIndex = channel.channelIndex;
1978+
psuErrorMessage(channel.channelIndex, MakeScpiErrorValue(err));
1979+
trigger::abort();
1980+
return;
1981+
}
19271982

1928-
int err;
1929-
if (channel.isPowerLimitExceeded(channel.u.set, value, &err)) {
1930-
g_errorChannelIndex = channel.channelIndex;
1931-
psuErrorMessage(channel.channelIndex, MakeScpiErrorValue(err));
1932-
trigger::abort();
1933-
return;
1983+
channel_dispatcher::setCurrent(channel, value);
1984+
g_isDcSetI[i] = true;
1985+
n--;
1986+
}
1987+
} else {
1988+
g_isDcSetI[i] = true;
19341989
}
1935-
1936-
channel_dispatcher::setCurrent(channel, value);
19371990
}
19381991
}
19391992

@@ -1952,6 +2005,8 @@ void tick() {
19522005
}
19532006
}
19542007
}
2008+
2009+
19552010
}
19562011

19572012
void abort() {
@@ -1972,6 +2027,36 @@ void abort() {
19722027
}
19732028
}
19742029

2030+
void tickGui() {
2031+
// // change m_selectedItem to the currently selected channel in max view
2032+
// if (psu::gui::getActivePageId() == PAGE_ID_MAIN && persist_conf::isMaxView()) {
2033+
// int maxSlotIndex = persist_conf::getMaxSlotIndex();
2034+
// int maxSubchannelIndex = persist_conf::getMaxSubchannelIndex();
2035+
2036+
// auto &waveformParameters = g_functionGeneratorPage.m_selectedResources.m_waveformParameters[g_functionGeneratorPage.m_selectedItem];
2037+
// int slotIndex;
2038+
// int subchannelIndex;
2039+
// int resourceIndex;
2040+
// AllResources::findResource(waveformParameters.absoluteResourceIndex,
2041+
// slotIndex, subchannelIndex, resourceIndex);
2042+
2043+
// if (slotIndex != maxSlotIndex || (maxSubchannelIndex != -1 && subchannelIndex != maxSubchannelIndex)) {
2044+
// for (int i = 0; i < g_selectedResources.m_numResources; i++) {
2045+
// auto &waveformParameters = g_functionGeneratorPage.m_selectedResources.m_waveformParameters[i];
2046+
// int slotIndex;
2047+
// int subchannelIndex;
2048+
// int resourceIndex;
2049+
// AllResources::findResource(waveformParameters.absoluteResourceIndex,
2050+
// slotIndex, subchannelIndex, resourceIndex);
2051+
// if (slotIndex == maxSlotIndex && (maxSubchannelIndex == -1 || maxSubchannelIndex == subchannelIndex)) {
2052+
// g_functionGeneratorPage.m_selectedItem = i;
2053+
// break;
2054+
// }
2055+
// }
2056+
// }
2057+
// }
2058+
}
2059+
19752060
} // namespace function_generator
19762061
} // namespace eez
19772062

@@ -2171,15 +2256,16 @@ void data_function_generator_selected_item_label(DataOperationEnum operation, Cu
21712256
g_functionGeneratorPage.m_selectedResources.m_waveformParameters[g_functionGeneratorPage.m_selectedItem].absoluteResourceIndex,
21722257
slotIndex, subchannelIndex, resourceIndex
21732258
);
2174-
value = g_slots[slotIndex]->getFunctionGeneratorResourceLabel(subchannelIndex, resourceIndex);
2259+
value = Value((int)((slotIndex << 6) | (subchannelIndex << 1) | resourceIndex),
2260+
g_slots[slotIndex]->getFunctionGeneratorResourceLabel(subchannelIndex, resourceIndex));
21752261
}
21762262
}
21772263

21782264

21792265
void data_function_generator_item_is_selected(DataOperationEnum operation, Cursor cursor, Value &value) {
2180-
if (operation == DATA_OPERATION_GET) {
2181-
value = g_functionGeneratorPage.m_selectedItem == cursor;
2182-
}
2266+
if (operation == DATA_OPERATION_GET) {
2267+
value = g_functionGeneratorPage.m_selectedItem == cursor;
2268+
}
21832269
}
21842270

21852271
void action_function_generator_item_toggle_selected() {

src/eez/function_generator.h

+2
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,8 @@ void executionStart();
104104
void tick();
105105
void abort();
106106

107+
void tickGui();
108+
107109
extern eez::gui::SetPage *g_pFunctionGeneratorPage;
108110
extern eez::gui::SetPage *g_pFunctionGeneratorSelectChannelsPage;
109111

0 commit comments

Comments
 (0)