30
30
#include < eez/index.h>
31
31
#include < eez/hmi.h>
32
32
#include < eez/util.h>
33
+ #include < eez/system.h>
33
34
#include < eez/gui/gui.h>
34
35
#include < eez/modules/psu/psu.h>
35
36
#include < eez/modules/psu/channel_dispatcher.h>
@@ -185,20 +186,25 @@ static const float PREVIEW_PERIOD_MIN = 0.001f;
185
186
static const float PREVIEW_PERIOD_DEF = 0 .2f ;
186
187
float g_previewPeriod = PREVIEW_PERIOD_DEF;
187
188
189
+ int g_funcGenChannelIndex;
190
+ uint64_t g_tickCountAtStart;
191
+
188
192
WaveformFunction g_waveFormFuncU[CH_MAX];
189
193
float g_phiU[CH_MAX];
190
194
float g_dphiU[CH_MAX];
191
195
float g_amplitudeU[CH_MAX];
192
196
float g_offsetU[CH_MAX];
193
197
float g_dutyCycleU[CH_MAX];
194
198
float g_freqU[CH_MAX];
199
+ bool g_isDcSetU[CH_MAX];
195
200
196
201
WaveformFunction g_waveFormFuncI[CH_MAX];
197
202
float g_phiI[CH_MAX];
198
203
float g_dphiI[CH_MAX];
199
204
float g_amplitudeI[CH_MAX];
200
205
float g_offsetI[CH_MAX];
201
206
float g_dutyCycleI[CH_MAX];
207
+ bool g_isDcSetI[CH_MAX];
202
208
203
209
bool g_dprogStateModified[CH_MAX];
204
210
bool g_currentRangeModified[CH_MAX];
@@ -417,6 +423,15 @@ class FunctionGeneratorPage : public SetPage {
417
423
const Style * style = getStyle (widget->style );
418
424
drawRectangle (widgetCursor.x , widgetCursor.y , (int )widget->w , (int )widget->h , style, false , false , true );
419
425
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
+
420
435
float minU = FLT_MAX;
421
436
float maxU = -FLT_MAX;
422
437
@@ -502,14 +517,14 @@ class FunctionGeneratorPage : public SetPage {
502
517
digitalWaveformParameters.offset = 0 ;
503
518
}
504
519
505
- drawWaveform (widgetCursor, digitalWaveformParameters, g_previewPeriod, 0 , 1 .0f );
520
+ drawWaveform (widgetCursor, digitalWaveformParameters, g_previewPeriod, 0 , 1 .0f , D );
506
521
507
522
digitalIndex++;
508
523
} else {
509
524
float min = waveformParameters.resourceType == FUNCTION_GENERATOR_RESOURCE_TYPE_U ? minU : minI;
510
525
float max = waveformParameters.resourceType == FUNCTION_GENERATOR_RESOURCE_TYPE_U ? maxU : maxI;
511
526
512
- drawWaveform (widgetCursor, waveformParameters, g_previewPeriod, min, max);
527
+ drawWaveform (widgetCursor, waveformParameters, g_previewPeriod, min, max, D );
513
528
}
514
529
}
515
530
@@ -530,17 +545,17 @@ class FunctionGeneratorPage : public SetPage {
530
545
digitalWaveformParameters.offset = 0 ;
531
546
}
532
547
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 );
535
550
} else {
536
551
float min = waveformParameters.resourceType == FUNCTION_GENERATOR_RESOURCE_TYPE_U ? minU : minI;
537
552
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 );
540
555
}
541
556
}
542
557
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 ) {
544
559
const Widget *widget = widgetCursor.widget ;
545
560
const Style * style = getStyle (widget->style );
546
561
font::Font font = styleGetFont (style);
@@ -600,7 +615,6 @@ class FunctionGeneratorPage : public SetPage {
600
615
float yt2 = ytMin;
601
616
602
617
if (fi2 - fi1 < 2 * M_PI || waveformParameters.waveform == WAVEFORM_DC) {
603
- int D = 20 ;
604
618
float dfi = (fi2 - fi1) / D;
605
619
for (int i = 0 ; i < D; i++) {
606
620
float fi = fi1 + dfi * i;
@@ -696,7 +710,7 @@ class FunctionGeneratorPage : public SetPage {
696
710
697
711
if (scrollPosition != m_scrollPosition) {
698
712
m_scrollPosition = scrollPosition;
699
- refreshScreen ();
713
+ // refreshScreen();
700
714
}
701
715
}
702
716
@@ -1804,29 +1818,34 @@ void reloadWaveformParameters() {
1804
1818
#endif
1805
1819
if (waveformParameters.resourceType == FUNCTION_GENERATOR_RESOURCE_TYPE_U) {
1806
1820
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;
1810
1821
1811
1822
if (waveformParameters.waveform == WAVEFORM_DC) {
1823
+ g_phiU[channel->channelIndex ] = 0 .0f ;
1824
+ g_dphiU[channel->channelIndex ] = 1 .0f ;
1812
1825
g_amplitudeU[channel->channelIndex ] = 0 .0f ;
1813
1826
g_offsetU[channel->channelIndex ] = waveformParameters.amplitude ;
1814
- g_freqU [channel->channelIndex ] = 0 ;
1827
+ g_isDcSetU [channel->channelIndex ] = false ;
1815
1828
} 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;
1816
1832
g_amplitudeU[channel->channelIndex ] = waveformParameters.amplitude ;
1817
1833
g_offsetU[channel->channelIndex ] = waveformParameters.offset ;
1818
1834
g_freqU[channel->channelIndex ] = waveformParameters.frequency ;
1819
1835
}
1820
1836
} else {
1821
1837
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;
1825
1838
1826
1839
if (waveformParameters.waveform == WAVEFORM_DC) {
1840
+ g_phiI[channel->channelIndex ] = 0 .0f ;
1841
+ g_dphiI[channel->channelIndex ] = 1 .0f ;
1827
1842
g_amplitudeI[channel->channelIndex ] = 0 .0f ;
1828
1843
g_offsetI[channel->channelIndex ] = waveformParameters.amplitude ;
1844
+ g_isDcSetI[channel->channelIndex ] = false ;
1829
1845
} 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;
1830
1849
g_amplitudeI[channel->channelIndex ] = waveformParameters.amplitude ;
1831
1850
g_offsetI[channel->channelIndex ] = waveformParameters.offset ;
1832
1851
}
@@ -1836,15 +1855,15 @@ void reloadWaveformParameters() {
1836
1855
if (channel->getCurrentRangeSelectionMode () == CURRENT_RANGE_SELECTION_USE_BOTH) {
1837
1856
float max = getMax (waveformParameters);
1838
1857
1839
- g_savedCurrentLimit[i ] = channel->getCurrentLimit ();
1858
+ g_savedCurrentLimit[channel-> channelIndex ] = channel->getCurrentLimit ();
1840
1859
1841
1860
if (max > 0 .05f ) {
1842
1861
channel_dispatcher::setCurrentRangeSelectionMode (*channel, CURRENT_RANGE_SELECTION_ALWAYS_HIGH);
1843
1862
} else {
1844
1863
channel_dispatcher::setCurrentRangeSelectionMode (*channel, CURRENT_RANGE_SELECTION_ALWAYS_LOW);
1845
1864
}
1846
1865
1847
- g_currentRangeModified[i ] = true ;
1866
+ g_currentRangeModified[channel-> channelIndex ] = true ;
1848
1867
}
1849
1868
}
1850
1869
}
@@ -1853,6 +1872,16 @@ void reloadWaveformParameters() {
1853
1872
#endif
1854
1873
}
1855
1874
}
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
1856
1885
}
1857
1886
1858
1887
void tick () {
@@ -1866,7 +1895,23 @@ void tick() {
1866
1895
1867
1896
int trackingChannel = -1 ;
1868
1897
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;
1870
1915
Channel &channel = Channel::get (i);
1871
1916
1872
1917
if (channel.flags .trackingEnabled ) {
@@ -1880,60 +1925,68 @@ void tick() {
1880
1925
}
1881
1926
1882
1927
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
+ }
1890
1941
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
+ }
1898
1949
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 ;
1905
1956
}
1906
-
1907
- channel_dispatcher::setVoltage (channel, value);
1908
1957
}
1909
1958
}
1910
1959
1911
1960
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
+ }
1919
1974
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
+ }
1927
1982
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 ;
1934
1989
}
1935
-
1936
- channel_dispatcher::setCurrent (channel, value);
1937
1990
}
1938
1991
}
1939
1992
@@ -1952,6 +2005,8 @@ void tick() {
1952
2005
}
1953
2006
}
1954
2007
}
2008
+
2009
+
1955
2010
}
1956
2011
1957
2012
void abort () {
@@ -1972,6 +2027,36 @@ void abort() {
1972
2027
}
1973
2028
}
1974
2029
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
+
1975
2060
} // namespace function_generator
1976
2061
} // namespace eez
1977
2062
@@ -2171,15 +2256,16 @@ void data_function_generator_selected_item_label(DataOperationEnum operation, Cu
2171
2256
g_functionGeneratorPage.m_selectedResources .m_waveformParameters [g_functionGeneratorPage.m_selectedItem ].absoluteResourceIndex ,
2172
2257
slotIndex, subchannelIndex, resourceIndex
2173
2258
);
2174
- value = g_slots[slotIndex]->getFunctionGeneratorResourceLabel (subchannelIndex, resourceIndex);
2259
+ value = Value ((int )((slotIndex << 6 ) | (subchannelIndex << 1 ) | resourceIndex),
2260
+ g_slots[slotIndex]->getFunctionGeneratorResourceLabel (subchannelIndex, resourceIndex));
2175
2261
}
2176
2262
}
2177
2263
2178
2264
2179
2265
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
+ }
2183
2269
}
2184
2270
2185
2271
void action_function_generator_item_toggle_selected () {
0 commit comments