diff --git a/.vscode/settings.json b/.vscode/settings.json index 8b2e23372..fd72b0607 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -21,5 +21,5 @@ "initializer_list": "cpp", "queue": "cpp" }, - "cmake.configureOnOpen": false + "C_Cpp.errorSquiggles": "Disabled" } \ No newline at end of file diff --git a/modular-psu-firmware.eez-project b/modular-psu-firmware.eez-project index fa6ee76cc..07e72a054 100644 --- a/modular-psu-firmware.eez-project +++ b/modular-psu-firmware.eez-project @@ -61009,118 +61009,6 @@ ] } }, - { - "name": "MEASure[:SCALar]:MODe", - "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", - "parameters": [ - { - "name": "mode", - "type": [ - { - "type": "discrete", - "enumeration": "MeasureMode" - } - ], - "isOptional": false - }, - { - "name": "channel", - "type": [ - { - "type": "discrete", - "enumeration": "Channel" - } - ], - "isOptional": true - } - ], - "response": { - "type": [ - { - "type": "numeric" - } - ] - } - }, - { - "name": "MEASure[:SCALar]:MODe?", - "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", - "parameters": [ - { - "name": "channel", - "type": [ - { - "type": "discrete", - "enumeration": "Channel" - } - ], - "isOptional": true - } - ], - "response": { - "type": [ - { - "type": "discrete", - "enumeration": "MeasureMode" - } - ] - } - }, - { - "name": "MEASure[:SCALar]:RANGe", - "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", - "parameters": [ - { - "name": "range", - "type": [ - { - "type": "nr1" - } - ], - "isOptional": false - }, - { - "name": "channel", - "type": [ - { - "type": "discrete", - "enumeration": "Channel" - } - ], - "isOptional": true - } - ], - "response": { - "type": [ - { - "type": "numeric" - } - ] - } - }, - { - "name": "MEASure[:SCALar]:RANGe?", - "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", - "parameters": [ - { - "name": "channel", - "type": [ - { - "type": "discrete", - "enumeration": "Channel" - } - ], - "isOptional": true - } - ], - "response": { - "type": [ - { - "type": "nr1" - } - ] - } - }, { "name": "MEASure:DIGital[:BYTE]?", "parameters": [ @@ -62477,7 +62365,64 @@ "helpLink": "EEZ BB3 SCPI reference 5.14 - SENSe.html", "commands": [ { - "name": "SENSe:CURRent[:DC]:RANGe[:UPPer]", + "name": "SENSe:FUNCtion[:ON]", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "function", + "type": [ + { + "type": "discrete", + "enumeration": "MeasureFunction" + } + ], + "isOptional": false + }, + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "numeric" + } + ] + } + }, + { + "name": "SENSe:FUNCtion[:ON]?", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "discrete", + "enumeration": "MeasureFunction" + } + ] + } + }, + { + "name": "[SENSe]:CURRent[:DC]:RANGe", "helpLink": "EEZ BB3 SCPI reference 5.14 - SENSe.html#sens_curr_rang", "parameters": [ { @@ -62492,6 +62437,16 @@ } ], "isOptional": false + }, + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true } ], "response": { @@ -62501,9 +62456,19 @@ } }, { - "name": "SENSe:CURRent[:DC]:RANGe[:UPPer]?", + "name": "[SENSe]:CURRent[:DC]:RANGe?", "helpLink": "EEZ BB3 SCPI reference 5.14 - SENSe.html#sens_curr_rang", - "parameters": [], + "parameters": [ + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ] + } + ], "response": { "type": [ { @@ -62512,6 +62477,217 @@ ] } }, + { + "name": "[SENSe]:VOLTage[:DC]:RANGe", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "range", + "type": [ + { + "type": "nr1" + } + ], + "isOptional": false + }, + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "numeric" + } + ] + } + }, + { + "name": "[SENSe]:VOLTage[:DC]:RANGe?", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "nr1" + } + ] + } + }, + { + "name": "SENSe:CURRent[:DC]:NPLCycles", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "cycles", + "type": [ + { + "type": "nr1" + } + ], + "isOptional": false + }, + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "numeric" + } + ] + } + }, + { + "name": "SENSe:CURRent[:DC]:NPLCycles?", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "numeric" + } + ] + } + }, + { + "name": "SENSe:CURRent[:DC]:APERture?", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "numeric" + } + ] + } + }, + { + "name": "SENSe:VOLTage[:DC]:NPLCycles", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "cycles", + "type": [ + { + "type": "nr1" + } + ], + "isOptional": false + }, + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "numeric" + } + ] + } + }, + { + "name": "SENSe:VOLTage[:DC]:NPLCycles?", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "numeric" + } + ] + } + }, + { + "name": "SENSe:VOLTage[:DC]:APERture?", + "helpLink": "EEZ BB3 SCPI reference 5.9 - MEASure.html#meas_volt", + "parameters": [ + { + "name": "channel", + "type": [ + { + "type": "discrete", + "enumeration": "Channel" + } + ], + "isOptional": true + } + ], + "response": { + "type": [ + { + "type": "numeric" + } + ] + } + }, { "name": "SENSe:DLOG:FUNCtion:CURRent", "helpLink": "EEZ BB3 SCPI reference 5.14 - SENSe.html#sens_dlog_func_curr", @@ -64549,14 +64725,14 @@ } }, { - "name": "[SOURce[]]:MODe", + "name": "SOURce:FUNCtion[:ON]", "parameters": [ { - "name": "mode", + "name": "function", "type": [ { "type": "discrete", - "enumeration": "SourceMode" + "enumeration": "SourceFunction" } ] } @@ -64568,19 +64744,19 @@ } }, { - "name": "[SOURce[]]:MODe?", + "name": "SOURce:FUNCtion[:ON]?", "parameters": [], "response": { "type": [ { "type": "discrete", - "enumeration": "SourceMode" + "enumeration": "SourceFunction" } ] } }, { - "name": "[SOURce[]]:CURRent:RANGe", + "name": "SOURce:CURRent:RANGe", "parameters": [ { "name": "range", @@ -64598,7 +64774,7 @@ } }, { - "name": "[SOURce[]]:CURRent:RANGe?", + "name": "SOURce:CURRent:RANGe?", "parameters": [], "response": { "type": [ @@ -64609,7 +64785,7 @@ } }, { - "name": "[SOURce[]]:VOLTage:RANGe", + "name": "SOURce:VOLTage:RANGe", "parameters": [ { "name": "range", @@ -64627,7 +64803,7 @@ } }, { - "name": "[SOURce[]]:VOLTage:RANGe?", + "name": "SOURce:VOLTage:RANGe?", "parameters": [], "response": { "type": [ @@ -67496,6 +67672,33 @@ } ] } + }, + { + "name": "SYSTem:LFRequency", + "parameters": [ + { + "name": "mode", + "type": [ + { + "type": "nr1" + } + ] + } + ], + "response": { + "type": [ + {} + ] + } + }, + { + "name": "SYSTem:LFRequency?", + "parameters": [], + "response": { + "type": [ + {} + ] + } } ] }, @@ -69354,7 +69557,7 @@ ] }, { - "name": "SourceMode", + "name": "SourceFunction", "members": [ { "name": "CURRent", @@ -69397,7 +69600,7 @@ ] }, { - "name": "MeasureMode", + "name": "MeasureFunction", "members": [ { "name": "CURRent", diff --git a/src/eez/index.cpp b/src/eez/index.cpp index 410bff558..d1c5d1547 100644 --- a/src/eez/index.cpp +++ b/src/eez/index.cpp @@ -368,42 +368,42 @@ bool Module::setDigitalOutputData(int subchannelIndex, uint8_t data, int *err) { return false; } -bool Module::getMode(int subchannelIndex, SourceMode &mode, int *err) { +bool Module::getSourceMode(int subchannelIndex, SourceMode &mode, int *err) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } -bool Module::setMode(int subchannelIndex, SourceMode mode, int *err) { +bool Module::setSourceMode(int subchannelIndex, SourceMode mode, int *err) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } -bool Module::getCurrentRange(int subchannelIndex, uint8_t &range, int *err) { +bool Module::getSourceCurrentRange(int subchannelIndex, uint8_t &range, int *err) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } -bool Module::setCurrentRange(int subchannelIndex, uint8_t range, int *err) { +bool Module::setSourceCurrentRange(int subchannelIndex, uint8_t range, int *err) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } -bool Module::getVoltageRange(int subchannelIndex, uint8_t &range, int *err) { +bool Module::getSourceVoltageRange(int subchannelIndex, uint8_t &range, int *err) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } -bool Module::setVoltageRange(int subchannelIndex, uint8_t range, int *err) { +bool Module::setSourceVoltageRange(int subchannelIndex, uint8_t range, int *err) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } @@ -424,20 +424,62 @@ bool Module::setMeasureMode(int subchannelIndex, MeasureMode mode, int *err) { return false; } -bool Module::getMeasureRange(int subchannelIndex, uint8_t &range, int *err) { +bool Module::getMeasureCurrentRange(int subchannelIndex, uint8_t &range, int *err) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } -bool Module::setMeasureRange(int subchannelIndex, uint8_t range, int *err) { +bool Module::setMeasureCurrentRange(int subchannelIndex, uint8_t range, int *err) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } +bool Module::getMeasureVoltageRange(int subchannelIndex, uint8_t &range, int *err) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; +} + +bool Module::setMeasureVoltageRange(int subchannelIndex, uint8_t range, int *err) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; +} + +bool Module::getMeasureCurrentNumPowerLineCycles(int subchannelIndex, uint8_t &numPowerLineCycles, int *err) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; +} + +bool Module::setMeasureCurrentNumPowerLineCycles(int subchannelIndex, uint8_t numPowerLineCycles, int *err) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; +} + +bool Module::getMeasureVoltageNumPowerLineCycles(int subchannelIndex, uint8_t &numPowerLineCycles, int *err) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; +} + +bool Module::setMeasureVoltageNumPowerLineCycles(int subchannelIndex, uint8_t numPowerLineCycles, int *err) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; +} + bool Module::isRouteOpen(int subchannelIndex, bool &isRouteOpen, int *err) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; diff --git a/src/eez/index.h b/src/eez/index.h index 72747606d..2c32ecd5a 100644 --- a/src/eez/index.h +++ b/src/eez/index.h @@ -290,20 +290,29 @@ struct Module { virtual bool getDigitalOutputData(int subchannelIndex, uint8_t &data, int *err); virtual bool setDigitalOutputData(int subchannelIndex, uint8_t data, int *err); - virtual bool getMode(int subchannelIndex, SourceMode &mode, int *err); - virtual bool setMode(int subchannelIndex, SourceMode mode, int *err); + virtual bool getSourceMode(int subchannelIndex, SourceMode &mode, int *err); + virtual bool setSourceMode(int subchannelIndex, SourceMode mode, int *err); - virtual bool getCurrentRange(int subchannelIndex, uint8_t &range, int *err); - virtual bool setCurrentRange(int subchannelIndex, uint8_t range, int *err); + virtual bool getSourceCurrentRange(int subchannelIndex, uint8_t &range, int *err); + virtual bool setSourceCurrentRange(int subchannelIndex, uint8_t range, int *err); - virtual bool getVoltageRange(int subchannelIndex, uint8_t &range, int *err); - virtual bool setVoltageRange(int subchannelIndex, uint8_t range, int *err); + virtual bool getSourceVoltageRange(int subchannelIndex, uint8_t &range, int *err); + virtual bool setSourceVoltageRange(int subchannelIndex, uint8_t range, int *err); virtual bool getMeasureMode(int subchannelIndex, MeasureMode &mode, int *err); virtual bool setMeasureMode(int subchannelIndex, MeasureMode mode, int *err); - virtual bool getMeasureRange(int subchannelIndex, uint8_t &range, int *err); - virtual bool setMeasureRange(int subchannelIndex, uint8_t range, int *err); + virtual bool getMeasureCurrentRange(int subchannelIndex, uint8_t &range, int *err); + virtual bool setMeasureCurrentRange(int subchannelIndex, uint8_t range, int *err); + + virtual bool getMeasureVoltageRange(int subchannelIndex, uint8_t &range, int *err); + virtual bool setMeasureVoltageRange(int subchannelIndex, uint8_t range, int *err); + + virtual bool getMeasureCurrentNumPowerLineCycles(int subchannelIndex, uint8_t &numPowerLineCycles, int *err); + virtual bool setMeasureCurrentNumPowerLineCycles(int subchannelIndex, uint8_t numPowerLineCycles, int *err); + + virtual bool getMeasureVoltageNumPowerLineCycles(int subchannelIndex, uint8_t &numPowerLineCycles, int *err); + virtual bool setMeasureVoltageNumPowerLineCycles(int subchannelIndex, uint8_t numPowerLineCycles, int *err); virtual bool isRouteOpen(int subchannelIndex, bool &isRouteOpen, int *err); virtual bool routeOpen(ChannelList channelList, int *err); diff --git a/src/eez/modules/dib-mio168/dib-mio168.cpp b/src/eez/modules/dib-mio168/dib-mio168.cpp index b182014b3..a52d46ab7 100644 --- a/src/eez/modules/dib-mio168/dib-mio168.cpp +++ b/src/eez/modules/dib-mio168/dib-mio168.cpp @@ -105,7 +105,7 @@ static float PWM_MAX_FREQUENCY = 1000000.0f; static const size_t CHANNEL_LABEL_MAX_LENGTH = 5; -static const uint32_t REFRESH_TIME_MS = 250; +static const uint32_t REFRESH_TIME_MS = 249; static const uint32_t TIMEOUT_TIME_MS = 350; static const uint32_t TIMEOUT_UNTIL_OUT_OF_SYNC_MS = 10000; @@ -151,8 +151,11 @@ struct SetParams { struct { uint8_t mode; // enum SourceMode uint8_t range; + uint8_t numPowerLineCycles; // from 0 to 25 } ain[4]; + uint8_t powerLineFrequency; // 50 or 60 + struct { uint8_t outputEnabled; uint8_t outputRange; @@ -457,33 +460,65 @@ struct DoutChannel { struct AinChannel { int m_subchannelIndex; float m_value = 0; - uint8_t m_mode = 1; - uint8_t m_range = 0; - char m_label[CHANNEL_LABEL_MAX_LENGTH + 1]; + uint8_t m_mode = MEASURE_MODE_VOLTAGE; + + // AIN1 and AIN2: + // 0: +/- 48 mA + // AIN3 and AIN4: + // 0: +/- 24 mA + // 1: +/- 1.2 A + // 2: +/- 10 A + uint8_t m_currentRange = 0; + + // AIN1 and AIN2: + // 0: +/- 2.4 V + // 1: +/- 24 V + // 2: +/- 240 V + // AIN3 and AIN4: + // 0: +/- 2.4 V + // 1: +/- 12 V + uint8_t m_voltageRange = 0; + + uint8_t m_numCurrentPowerLineCycles = 25; + uint8_t m_numVoltagePowerLineCycles = 25; + + char m_label[CHANNEL_LABEL_MAX_LENGTH + 1]; AinChannel(int subchannelIndex) : m_subchannelIndex(subchannelIndex) {} struct ProfileParameters { uint8_t mode; - uint8_t range; + uint8_t currentRange; + uint8_t voltageRange; + uint8_t numCurrentPowerLineCycles; + uint8_t numVoltagePowerLineCycles; char label[CHANNEL_LABEL_MAX_LENGTH + 1]; }; void resetProfileToDefaults(ProfileParameters ¶meters) { - parameters.mode = 1; - parameters.range = 0; + parameters.mode = MEASURE_MODE_VOLTAGE; + parameters.currentRange = 0; + parameters.voltageRange = 0; + parameters.numCurrentPowerLineCycles = 25; + parameters.numVoltagePowerLineCycles = 25; *parameters.label = 0; } void getProfileParameters(ProfileParameters ¶meters) { parameters.mode = m_mode; - parameters.range = m_range; + parameters.currentRange = m_currentRange; + parameters.voltageRange = m_voltageRange; + parameters.numCurrentPowerLineCycles = m_numCurrentPowerLineCycles; + parameters.numVoltagePowerLineCycles = m_numVoltagePowerLineCycles; memcpy(parameters.label, m_label, sizeof(m_label)); } void setProfileParameters(ProfileParameters ¶meters) { m_mode = parameters.mode; - m_range = parameters.range; + m_currentRange = parameters.currentRange; + m_voltageRange = parameters.voltageRange; + m_numCurrentPowerLineCycles = parameters.numCurrentPowerLineCycles; + m_numVoltagePowerLineCycles = parameters.numVoltagePowerLineCycles; memcpy(m_label, parameters.label, sizeof(m_label)); } @@ -493,10 +528,19 @@ struct AinChannel { sprintf(propName, "ain_%d_mode", i+1); WRITE_PROPERTY(propName, parameters.mode); - sprintf(propName, "ain_%d_range", i+1); - WRITE_PROPERTY(propName, parameters.range); + sprintf(propName, "ain_%d_currentRange", i+1); + WRITE_PROPERTY(propName, parameters.currentRange); - sprintf(propName, "ain_%d_label", i+1); + sprintf(propName, "ain_%d_voltageRange", i + 1); + WRITE_PROPERTY(propName, parameters.voltageRange); + + sprintf(propName, "ain_%d_numCurrentPowerLineCycles", i + 1); + WRITE_PROPERTY(propName, parameters.numCurrentPowerLineCycles); + + sprintf(propName, "ain_%d_numVoltagePowerLineCycles", i + 1); + WRITE_PROPERTY(propName, parameters.numVoltagePowerLineCycles); + + sprintf(propName, "ain_%d_label", i+1); WRITE_PROPERTY(propName, parameters.label); return true; @@ -508,35 +552,63 @@ struct AinChannel { sprintf(propName, "ain_%d_mode", i+1); READ_PROPERTY(propName, parameters.mode); - sprintf(propName, "ain_%d_range", i+1); - READ_PROPERTY(propName, parameters.range); + sprintf(propName, "ain_%d_currentRange", i+1); + READ_PROPERTY(propName, parameters.currentRange); + + sprintf(propName, "ain_%d_voltageRange", i + 1); + READ_PROPERTY(propName, parameters.voltageRange); + + sprintf(propName, "ain_%d_numCurrentPowerLineCycles", i + 1); + READ_PROPERTY(propName, parameters.numCurrentPowerLineCycles); + + sprintf(propName, "ain_%d_numVoltagePowerLineCycles", i + 1); + READ_PROPERTY(propName, parameters.numVoltagePowerLineCycles); - sprintf(propName, "ain_%d_label", i+1); + sprintf(propName, "ain_%d_label", i+1); READ_STRING_PROPERTY(propName, parameters.label, CHANNEL_LABEL_MAX_LENGTH); return false; } void resetConfiguration() { - m_mode = 1; - m_range = 0; + m_mode = MEASURE_MODE_VOLTAGE; + m_currentRange = 0; + m_voltageRange = 0; + m_numCurrentPowerLineCycles = 25; + m_numVoltagePowerLineCycles = 25; *m_label = 0; } + int8_t getCurrentRange() { + return m_currentRange; + } + + void setCurrentRange(int8_t range) { + m_currentRange = range; + } + + int8_t getVoltageRange() { + return m_voltageRange; + } + + void setVoltageRange(int8_t range) { + m_voltageRange = range; + } + Unit getUnit() { if (m_subchannelIndex == AIN_1_SUBCHANNEL_INDEX || m_subchannelIndex == AIN_2_SUBCHANNEL_INDEX) { return m_mode == MEASURE_MODE_VOLTAGE ? UNIT_VOLT : UNIT_MILLI_AMPER; } else { - return m_mode == MEASURE_MODE_VOLTAGE ? UNIT_VOLT : m_range == 0 ? UNIT_MILLI_AMPER : UNIT_AMPER; + return m_mode == MEASURE_MODE_VOLTAGE ? UNIT_VOLT : m_currentRange == 0 ? UNIT_MILLI_AMPER : UNIT_AMPER; } } int getNumFixedDecimals() { if (m_subchannelIndex == AIN_1_SUBCHANNEL_INDEX || m_subchannelIndex == AIN_2_SUBCHANNEL_INDEX) { if (m_mode == MEASURE_MODE_VOLTAGE) { - if (m_range == 0) { + if (m_voltageRange == 0) { return 4; // +/- 2.4 V - } else if (m_range == 1) { + } else if (m_voltageRange == 1) { return 3; // +/- 48 V } else { return 2; // +/- 240 V @@ -546,15 +618,15 @@ struct AinChannel { } } else { if (m_mode == MEASURE_MODE_VOLTAGE) { - if (m_range == 0) { + if (m_voltageRange == 0) { return 4; // +/- 2.4 V } else { return 3; // +/- 12 V } } else { - if (m_range == 0) { + if (m_currentRange == 0) { return 2; // +/- 24 mA -> 5-3 = 2 - } else if (m_range == 1) { + } else if (m_currentRange == 1) { return 4; // +/- 1.2 A } else { return 3; // +/- 10 A @@ -571,11 +643,20 @@ struct AinChannel { m_value = value; } - static uint8_t getRangeMaxValue(int subchannelIndex, uint8_t mode) { + static uint8_t getCurrentRangeMaxValue(int subchannelIndex) { if (subchannelIndex == AIN_1_SUBCHANNEL_INDEX || subchannelIndex == AIN_2_SUBCHANNEL_INDEX) { - return mode == SOURCE_MODE_VOLTAGE ? 2 : 0; + return 0; } else { - return mode == SOURCE_MODE_VOLTAGE ? 1 : mode == SOURCE_MODE_CURRENT ? 2 : 0; + return 2; + } + } + + static uint8_t getVoltageRangeMaxValue(int subchannelIndex) { + if (subchannelIndex == AIN_1_SUBCHANNEL_INDEX || subchannelIndex == AIN_2_SUBCHANNEL_INDEX) { + return 2; + } + else { + return 1; } } }; @@ -1320,13 +1401,16 @@ struct Mio168Module : public Module { for (int i = 0; i < 4; i++) { auto channel = &ainChannels[i]; params.ain[i].mode = channel->m_mode; - params.ain[i].range = channel->m_range; + params.ain[i].range = channel->m_mode == MEASURE_MODE_VOLTAGE ? channel->getVoltageRange() : channel->getCurrentRange(); + params.ain[i].numPowerLineCycles = channel->m_mode == MEASURE_MODE_VOLTAGE ? channel->m_numVoltagePowerLineCycles : channel->m_numCurrentPowerLineCycles; } + params.powerLineFrequency = persist_conf::getPowerLineFrequency(); + for (int i = 0; i < 2; i++) { auto channel = &aoutDac7760Channels[i]; params.aout_dac7760[i].outputEnabled = channel->m_outputEnabled; - params.aout_dac7760[i].outputRange = channel->getMode() == SOURCE_MODE_VOLTAGE ? channel->getVoltageRange() : channel->m_currentRange; + params.aout_dac7760[i].outputRange = channel->getMode() == SOURCE_MODE_VOLTAGE ? channel->getVoltageRange() : channel->getCurrentRange(); params.aout_dac7760[i].outputValue = channel->getCalibratedValue(); } @@ -1863,9 +1947,6 @@ struct Mio168Module : public Module { doutChannel.setProfileParameters(parameters->doutChannel); for (int i = 0; i < 4; i++) { ainChannels[i].setProfileParameters(parameters->ainChannels[i]); - if (ainChannels[i].m_range > AinChannel::getRangeMaxValue(AIN_1_SUBCHANNEL_INDEX + i, ainChannels[i].m_mode)) { - ainChannels[i].m_range = 0; - } } for (int i = 0; i < 2; i++) { aoutDac7760Channels[i].setProfileParameters(parameters->aoutDac7760Channels[i]); @@ -2310,8 +2391,8 @@ struct Mio168Module : public Module { return true; } - bool getMode(int subchannelIndex, SourceMode &mode, int *err) override { - if (subchannelIndex != AOUT_1_SUBCHANNEL_INDEX && subchannelIndex != AOUT_2_SUBCHANNEL_INDEX) { + bool getSourceMode(int subchannelIndex, SourceMode &mode, int *err) override { + if (subchannelIndex < AOUT_1_SUBCHANNEL_INDEX || subchannelIndex > AOUT_2_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } @@ -2321,8 +2402,8 @@ struct Mio168Module : public Module { return true; } - bool setMode(int subchannelIndex, SourceMode mode, int *err) override { - if (subchannelIndex != AOUT_1_SUBCHANNEL_INDEX && subchannelIndex != AOUT_2_SUBCHANNEL_INDEX) { + bool setSourceMode(int subchannelIndex, SourceMode mode, int *err) override { + if (subchannelIndex < AOUT_1_SUBCHANNEL_INDEX || subchannelIndex > AOUT_2_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } @@ -2332,8 +2413,8 @@ struct Mio168Module : public Module { return true; } - bool getCurrentRange(int subchannelIndex, uint8_t &range, int *err) override { - if (subchannelIndex != AOUT_1_SUBCHANNEL_INDEX && subchannelIndex != AOUT_2_SUBCHANNEL_INDEX) { + bool getSourceCurrentRange(int subchannelIndex, uint8_t &range, int *err) override { + if (subchannelIndex < AOUT_1_SUBCHANNEL_INDEX || subchannelIndex > AOUT_2_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } @@ -2343,19 +2424,27 @@ struct Mio168Module : public Module { return true; } - bool setCurrentRange(int subchannelIndex, uint8_t range, int *err) override { - if (subchannelIndex != AOUT_1_SUBCHANNEL_INDEX && subchannelIndex != AOUT_2_SUBCHANNEL_INDEX) { + bool setSourceCurrentRange(int subchannelIndex, uint8_t range, int *err) override { + if (subchannelIndex < AOUT_1_SUBCHANNEL_INDEX || subchannelIndex > AOUT_2_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } + + if (range < 5 || range > 7) { + if (err) { + *err = SCPI_ERROR_ILLEGAL_PARAMETER_VALUE; + } + return false; + } + aoutDac7760Channels[subchannelIndex - AOUT_1_SUBCHANNEL_INDEX].setCurrentRange(range); return true; } - bool getVoltageRange(int subchannelIndex, uint8_t &range, int *err) override { - if (subchannelIndex != AOUT_1_SUBCHANNEL_INDEX && subchannelIndex != AOUT_2_SUBCHANNEL_INDEX) { + bool getSourceVoltageRange(int subchannelIndex, uint8_t &range, int *err) override { + if (subchannelIndex < AOUT_1_SUBCHANNEL_INDEX || subchannelIndex > AOUT_2_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } @@ -2365,19 +2454,27 @@ struct Mio168Module : public Module { return true; } - bool setVoltageRange(int subchannelIndex, uint8_t range, int *err) override { - if (subchannelIndex != AOUT_1_SUBCHANNEL_INDEX && subchannelIndex != AOUT_2_SUBCHANNEL_INDEX) { + bool setSourceVoltageRange(int subchannelIndex, uint8_t range, int *err) override { + if (subchannelIndex < AOUT_1_SUBCHANNEL_INDEX || subchannelIndex > AOUT_2_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } + + if (range < 0 || range > 3) { + if (err) { + *err = SCPI_ERROR_ILLEGAL_PARAMETER_VALUE; + } + return false; + } + aoutDac7760Channels[subchannelIndex - AOUT_1_SUBCHANNEL_INDEX].setVoltageRange(range); return true; } bool getMeasureMode(int subchannelIndex, MeasureMode &mode, int *err) override { - if (subchannelIndex != AIN_1_SUBCHANNEL_INDEX && subchannelIndex != AIN_4_SUBCHANNEL_INDEX) { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } @@ -2388,7 +2485,7 @@ struct Mio168Module : public Module { } bool setMeasureMode(int subchannelIndex, MeasureMode mode, int *err) override { - if (subchannelIndex != AIN_1_SUBCHANNEL_INDEX && subchannelIndex != AIN_4_SUBCHANNEL_INDEX) { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } @@ -2398,37 +2495,130 @@ struct Mio168Module : public Module { return true; } - bool getMeasureRange(int subchannelIndex, uint8_t &range, int *err) override { - if (subchannelIndex != AIN_1_SUBCHANNEL_INDEX && subchannelIndex != AIN_4_SUBCHANNEL_INDEX) { + bool getMeasureCurrentRange(int subchannelIndex, uint8_t &range, int *err) override { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } - range = ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].m_range; + range = ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].getCurrentRange(); return true; } - bool setMeasureRange(int subchannelIndex, uint8_t range, int *err) override { - if (subchannelIndex != AIN_1_SUBCHANNEL_INDEX && subchannelIndex != AIN_4_SUBCHANNEL_INDEX) { + bool setMeasureCurrentRange(int subchannelIndex, uint8_t range, int *err) override { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { if (err) { *err = SCPI_ERROR_HARDWARE_MISSING; } return false; } - if (range > AinChannel::getRangeMaxValue(subchannelIndex, ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].m_mode)) { + if (range > AinChannel::getCurrentRangeMaxValue(subchannelIndex)) { if (err) { *err = SCPI_ERROR_ILLEGAL_PARAMETER_VALUE; } return false; } - ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].m_range = range; + ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].setCurrentRange(range); + + return true; + } + + bool getMeasureVoltageRange(int subchannelIndex, uint8_t &range, int *err) override { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; + } + range = ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].getVoltageRange(); + return true; + } + + bool setMeasureVoltageRange(int subchannelIndex, uint8_t range, int *err) override { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; + } + + if (range > AinChannel::getVoltageRangeMaxValue(subchannelIndex)) { + if (err) { + *err = SCPI_ERROR_ILLEGAL_PARAMETER_VALUE; + } + return false; + } + + ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].setVoltageRange(range); + + return true; + } + bool getMeasureCurrentNumPowerLineCycles(int subchannelIndex, uint8_t &numPowerLineCycles, int *err) override { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; + } + numPowerLineCycles = ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].m_numCurrentPowerLineCycles; return true; } + bool setMeasureCurrentNumPowerLineCycles(int subchannelIndex, uint8_t numPowerLineCycles, int *err) override { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; + } + + if (numPowerLineCycles > 25) { + if (err) { + *err = SCPI_ERROR_ILLEGAL_PARAMETER_VALUE; + } + return false; + } + + ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].m_numCurrentPowerLineCycles = numPowerLineCycles; + + return true; + } + + bool getMeasureVoltageNumPowerLineCycles(int subchannelIndex, uint8_t &numPowerLineCycles, int *err) override { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; + } + numPowerLineCycles = ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].m_numVoltagePowerLineCycles; + return true; + } + + bool setMeasureVoltageNumPowerLineCycles(int subchannelIndex, uint8_t numPowerLineCycles, int *err) override { + if (subchannelIndex < AIN_1_SUBCHANNEL_INDEX || subchannelIndex > AIN_4_SUBCHANNEL_INDEX) { + if (err) { + *err = SCPI_ERROR_HARDWARE_MISSING; + } + return false; + } + + if (numPowerLineCycles > 25) { + if (err) { + *err = SCPI_ERROR_ILLEGAL_PARAMETER_VALUE; + } + return false; + } + + ainChannels[subchannelIndex - AIN_1_SUBCHANNEL_INDEX].m_numVoltagePowerLineCycles = numPowerLineCycles; + + return true; + } + bool outputEnable(int subchannelIndex, bool enable, int *err) override { if (subchannelIndex < AOUT_1_SUBCHANNEL_INDEX || subchannelIndex > AOUT_2_SUBCHANNEL_INDEX) { if (err) { @@ -3162,7 +3352,7 @@ class AinConfigurationPage : public SetPage { AinChannel &channel = module->ainChannels[g_selectedChannelIndex - AIN_1_SUBCHANNEL_INDEX]; m_mode = m_modeOrig = channel.m_mode; - m_range = m_rangeOrig = channel.m_range; + m_range = m_rangeOrig = channel.m_mode == MEASURE_MODE_VOLTAGE ? channel.getVoltageRange() : channel.getCurrentRange(); } int getDirty() { @@ -3246,7 +3436,7 @@ class AinConfigurationPage : public SetPage { if (subchannelIndex == AIN_1_SUBCHANNEL_INDEX || subchannelIndex == AIN_2_SUBCHANNEL_INDEX) { if (channel.m_mode == MEASURE_MODE_VOLTAGE) { - return channel.m_range; + return channel.getVoltageRange(); } else if (channel.m_mode == MEASURE_MODE_CURRENT) { return 3; } else { @@ -3254,9 +3444,9 @@ class AinConfigurationPage : public SetPage { } } else { if (channel.m_mode == MEASURE_MODE_VOLTAGE) { - return channel.m_range; + return channel.getVoltageRange(); } else if (channel.m_mode == MEASURE_MODE_CURRENT) { - return 2 + channel.m_range; + return 2 + channel.getCurrentRange(); } else { return 5; } @@ -3270,18 +3460,18 @@ class AinConfigurationPage : public SetPage { if (subchannelIndex == AIN_1_SUBCHANNEL_INDEX || subchannelIndex == AIN_2_SUBCHANNEL_INDEX) { if (modeRange < 3) { channel.m_mode = MEASURE_MODE_VOLTAGE; - channel.m_range = modeRange; + channel.setVoltageRange(modeRange); } else { channel.m_mode = MEASURE_MODE_CURRENT; - channel.m_range = 0; + channel.setCurrentRange(0); } } else { if (modeRange < 2) { channel.m_mode = MEASURE_MODE_VOLTAGE; - channel.m_range = modeRange; + channel.setVoltageRange(modeRange); } else { channel.m_mode = MEASURE_MODE_CURRENT; - channel.m_range = modeRange - 2; + channel.setCurrentRange(modeRange); } } } @@ -3450,7 +3640,11 @@ void Mio168Module::onHighPriorityThreadMessage(uint8_t type, uint32_t param) { } else if (type == PSU_MESSAGE_AIN_CONFIGURE) { AinChannel &channel = ainChannels[AinConfigurationPage::g_selectedChannelIndex - AIN_1_SUBCHANNEL_INDEX]; channel.m_mode = g_ainConfigurationPage.m_mode; - channel.m_range = g_ainConfigurationPage.m_range; + if (g_ainConfigurationPage.m_mode == MEASURE_MODE_VOLTAGE) { + channel.setVoltageRange(g_ainConfigurationPage.m_range); + } else { + channel.setCurrentRange(g_ainConfigurationPage.m_range); + } } else if (type == PSU_MESSAGE_AOUT_DAC7760_CONFIGURE) { AoutDac7760Channel &channel = aoutDac7760Channels[AoutDac7760ConfigurationPage::g_selectedChannelIndex - AOUT_1_SUBCHANNEL_INDEX]; channel.m_outputEnabled = g_aoutDac7760ConfigurationPage.m_outputEnabled; @@ -3841,9 +4035,6 @@ void data_dib_mio168_ain_mode(DataOperationEnum operation, Cursor cursor, Value void action_dib_mio168_ain_select_mode() { g_ainConfigurationPage.m_mode = g_ainConfigurationPage.m_mode == MEASURE_MODE_VOLTAGE ? MEASURE_MODE_CURRENT : MEASURE_MODE_VOLTAGE; - if (g_ainConfigurationPage.m_range > AinChannel::getRangeMaxValue(g_ainConfigurationPage.g_selectedChannelIndex, g_ainConfigurationPage.m_mode)) { - g_ainConfigurationPage.m_range = 0; - } } void data_dib_mio168_ain_range_is_available(DataOperationEnum operation, Cursor cursor, Value &value) { diff --git a/src/eez/modules/psu/channel_dispatcher.cpp b/src/eez/modules/psu/channel_dispatcher.cpp index c7750c19c..83c891560 100644 --- a/src/eez/modules/psu/channel_dispatcher.cpp +++ b/src/eez/modules/psu/channel_dispatcher.cpp @@ -2208,28 +2208,28 @@ bool setDigitalOutputData(int slotIndex, int subchannelIndex, uint8_t data, int return g_slots[slotIndex]->setDigitalOutputData(subchannelIndex, data, err); } -bool getMode(int slotIndex, int subchannelIndex, SourceMode &mode, int *err) { - return g_slots[slotIndex]->getMode(subchannelIndex, mode, err); +bool getSourceMode(int slotIndex, int subchannelIndex, SourceMode &mode, int *err) { + return g_slots[slotIndex]->getSourceMode(subchannelIndex, mode, err); } -bool setMode(int slotIndex, int subchannelIndex, SourceMode mode, int *err) { - return g_slots[slotIndex]->setMode(subchannelIndex, mode, err); +bool setSourceMode(int slotIndex, int subchannelIndex, SourceMode mode, int *err) { + return g_slots[slotIndex]->setSourceMode(subchannelIndex, mode, err); } -bool getCurrentRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err) { - return g_slots[slotIndex]->getCurrentRange(subchannelIndex, range, err); +bool getSourceCurrentRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err) { + return g_slots[slotIndex]->getSourceCurrentRange(subchannelIndex, range, err); } -bool setCurrentRange(int slotIndex, int subchannelIndex, uint8_t range, int *err) { - return g_slots[slotIndex]->setCurrentRange(subchannelIndex, range, err); +bool setSourceCurrentRange(int slotIndex, int subchannelIndex, uint8_t range, int *err) { + return g_slots[slotIndex]->setSourceCurrentRange(subchannelIndex, range, err); } -bool getVoltageRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err) { - return g_slots[slotIndex]->getVoltageRange(subchannelIndex, range, err); +bool getSourceVoltageRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err) { + return g_slots[slotIndex]->getSourceVoltageRange(subchannelIndex, range, err); } -bool setVoltageRange(int slotIndex, int subchannelIndex, uint8_t range, int *err) { - return g_slots[slotIndex]->setVoltageRange(subchannelIndex, range, err); +bool setSourceVoltageRange(int slotIndex, int subchannelIndex, uint8_t range, int *err) { + return g_slots[slotIndex]->setSourceVoltageRange(subchannelIndex, range, err); } bool getMeasureMode(int slotIndex, int subchannelIndex, MeasureMode &mode, int *err) { @@ -2240,12 +2240,36 @@ bool setMeasureMode(int slotIndex, int subchannelIndex, MeasureMode mode, int *e return g_slots[slotIndex]->setMeasureMode(subchannelIndex, mode, err); } -bool getMeasureRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err) { - return g_slots[slotIndex]->getMeasureRange(subchannelIndex, range, err); +bool getMeasureCurrentRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err) { + return g_slots[slotIndex]->getMeasureCurrentRange(subchannelIndex, range, err); } -bool setMeasureRange(int slotIndex, int subchannelIndex, uint8_t range, int *err) { - return g_slots[slotIndex]->setMeasureRange(subchannelIndex, range, err); +bool setMeasureCurrentRange(int slotIndex, int subchannelIndex, uint8_t range, int *err) { + return g_slots[slotIndex]->setMeasureCurrentRange(subchannelIndex, range, err); +} + +bool getMeasureVoltageRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err) { + return g_slots[slotIndex]->getMeasureVoltageRange(subchannelIndex, range, err); +} + +bool setMeasureVoltageRange(int slotIndex, int subchannelIndex, uint8_t range, int *err) { + return g_slots[slotIndex]->setMeasureVoltageRange(subchannelIndex, range, err); +} + +bool getMeasureCurrentNumPowerLineCycles(int slotIndex, int subchannelIndex, uint8_t &numPowerLineCycles, int *err) { + return g_slots[slotIndex]->getMeasureCurrentNumPowerLineCycles(subchannelIndex, numPowerLineCycles, err); +} + +bool setMeasureCurrentNumPowerLineCylces(int slotIndex, int subchannelIndex, uint8_t numPowerLineCycles, int *err) { + return g_slots[slotIndex]->setMeasureCurrentNumPowerLineCycles(subchannelIndex, numPowerLineCycles, err); +} + +bool getMeasureVoltageNumPowerLineCycles(int slotIndex, int subchannelIndex, uint8_t &numPowerLineCycles, int *err) { + return g_slots[slotIndex]->getMeasureVoltageNumPowerLineCycles(subchannelIndex, numPowerLineCycles, err); +} + +bool setMeasureVoltageNumPowerLineCylces(int slotIndex, int subchannelIndex, uint8_t numPowerLineCycles, int *err) { + return g_slots[slotIndex]->setMeasureVoltageNumPowerLineCycles(subchannelIndex, numPowerLineCycles, err); } bool routeOpen(ChannelList channelList, int *err) { diff --git a/src/eez/modules/psu/channel_dispatcher.h b/src/eez/modules/psu/channel_dispatcher.h index 0c4fbea12..a6aa28e0b 100644 --- a/src/eez/modules/psu/channel_dispatcher.h +++ b/src/eez/modules/psu/channel_dispatcher.h @@ -195,20 +195,29 @@ bool setDigitalInputSpeed(int slotIndex, int subchannelIndex, uint8_t pin, uint8 bool getDigitalOutputData(int slotIndex, int subchannelIndex, uint8_t &data, int *err); bool setDigitalOutputData(int slotIndex, int subchannelIndex, uint8_t data, int *err); -bool getMode(int slotIndex, int subchannelIndex, SourceMode &mode, int *err); -bool setMode(int slotIndex, int subchannelIndex, SourceMode mode, int *err); +bool getSourceMode(int slotIndex, int subchannelIndex, SourceMode &mode, int *err); +bool setSourceMode(int slotIndex, int subchannelIndex, SourceMode mode, int *err); -bool getCurrentRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err); -bool setCurrentRange(int slotIndex, int subchannelIndex, uint8_t range, int *err); +bool getSourceCurrentRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err); +bool setSourceCurrentRange(int slotIndex, int subchannelIndex, uint8_t range, int *err); -bool getVoltageRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err); -bool setVoltageRange(int slotIndex, int subchannelIndex, uint8_t range, int *err); +bool getSourceVoltageRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err); +bool setSourceVoltageRange(int slotIndex, int subchannelIndex, uint8_t range, int *err); bool getMeasureMode(int slotIndex, int subchannelIndex, MeasureMode &mode, int *err); bool setMeasureMode(int slotIndex, int subchannelIndex, MeasureMode mode, int *err); -bool getMeasureRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err); -bool setMeasureRange(int slotIndex, int subchannelIndex, uint8_t range, int *err); +bool getMeasureCurrentRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err); +bool setMeasureCurrentRange(int slotIndex, int subchannelIndex, uint8_t range, int *err); + +bool getMeasureVoltageRange(int slotIndex, int subchannelIndex, uint8_t &range, int *err); +bool setMeasureVoltageRange(int slotIndex, int subchannelIndex, uint8_t range, int *err); + +bool getMeasureCurrentNumPowerLineCycles(int slotIndex, int subchannelIndex, uint8_t &numPowerLineCycles, int *err); +bool setMeasureCurrentNumPowerLineCylces(int slotIndex, int subchannelIndex, uint8_t numPowerLineCycles, int *err); + +bool getMeasureVoltageNumPowerLineCycles(int slotIndex, int subchannelIndex, uint8_t &numPowerLineCycles, int *err); +bool setMeasureVoltageNumPowerLineCylces(int slotIndex, int subchannelIndex, uint8_t numPowerLineCycles, int *err); bool isRouteOpen(int slotIndex, int subchannelIndex, int *err); bool routeOpen(ChannelList channelList, int *err); diff --git a/src/eez/modules/psu/persist_conf.cpp b/src/eez/modules/psu/persist_conf.cpp index 690c45ee9..a916f6e08 100644 --- a/src/eez/modules/psu/persist_conf.cpp +++ b/src/eez/modules/psu/persist_conf.cpp @@ -1297,6 +1297,18 @@ void setSlotEnabled(int slotIndex, bool enabled) { } } +int getPowerLineFrequency() { + return g_devConf.powerLineFrequencyMode == 0 ? 50 : 60; +} + +void setPowerLineFrequency(int powerLineFrequency) { + if (powerLineFrequency == 50) { + g_devConf.powerLineFrequencyMode = 0; + } else if (powerLineFrequency == 60) { + g_devConf.powerLineFrequencyMode = 1; + } +} + //////////////////////////////////////////////////////////////////////////////// ModuleConfiguration g_moduleConf[NUM_SLOTS]; diff --git a/src/eez/modules/psu/persist_conf.h b/src/eez/modules/psu/persist_conf.h index 94db57231..5d0a7c648 100644 --- a/src/eez/modules/psu/persist_conf.h +++ b/src/eez/modules/psu/persist_conf.h @@ -149,11 +149,11 @@ struct DeviceConfiguration { float reserved52; // was triggerDelay struct { - unsigned reserved1 : 1; - unsigned reserved2 : 7; + unsigned reserved2 : 8; } reserved53[4]; // was ioPins - unsigned reserved54 : 1; // was triggerContinuousInitializationEnabled + + unsigned powerLineFrequencyMode : 1; // 0 - 50 Hz, 1 - 60 Hz unsigned isFrontPanelLocked : 1; @@ -343,6 +343,12 @@ void setDlogViewShowLabels(bool showLabels); bool isSlotEnabled(int slotIndex); void setSlotEnabled(int slotIndex, bool enabled); +// returns 50 or 60 +int getPowerLineFrequency(); + +// powerLineFrequency parameter accepts value 50 or 60 +void setPowerLineFrequency(int powerLineFrequency); + //////////////////////////////////////////////////////////////////////////////// struct ModuleConfiguration { diff --git a/src/eez/modules/psu/profile.h b/src/eez/modules/psu/profile.h index 359269fef..347ab8cc2 100644 --- a/src/eez/modules/psu/profile.h +++ b/src/eez/modules/psu/profile.h @@ -29,7 +29,7 @@ namespace psu { /// PSU configuration profiles (save, recall, ...). namespace profile { -#define MAX_CHANNEL_PARAMETERS_SIZE 250 +#define MAX_CHANNEL_PARAMETERS_SIZE 280 #define MAX_SLOT_PARAMETERS_SIZE 200 /// Channel parameters stored in profile. diff --git a/src/eez/modules/psu/scpi/inst.cpp b/src/eez/modules/psu/scpi/inst.cpp index f2207b85d..9948f60c3 100644 --- a/src/eez/modules/psu/scpi/inst.cpp +++ b/src/eez/modules/psu/scpi/inst.cpp @@ -69,7 +69,7 @@ scpi_result_t scpi_cmd_instrumentSelect(scpi_t *context) { SlotAndSubchannelIndex slotAndSubchannelIndex; if (!getChannelFromParam(context, slotAndSubchannelIndex)) { - return SCPI_RES_ERR; + return SCPI_RES_ERR; } Channel *channel = Channel::getBySlotIndex(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex); diff --git a/src/eez/modules/psu/scpi/meas.cpp b/src/eez/modules/psu/scpi/meas.cpp index b6eef1d8d..47d62dd88 100644 --- a/src/eez/modules/psu/scpi/meas.cpp +++ b/src/eez/modules/psu/scpi/meas.cpp @@ -93,93 +93,6 @@ scpi_result_t scpi_cmd_measureScalarVoltageDcQ(scpi_t *context) { return SCPI_RES_OK; } -static scpi_choice_def_t g_measureModeChoice[] = { - { "CURRent", MEASURE_MODE_CURRENT }, - { "VOLTage", MEASURE_MODE_VOLTAGE }, - SCPI_CHOICE_LIST_END /* termination of option list */ -}; - -scpi_result_t scpi_cmd_measureScalarMode(scpi_t *context) { - int32_t mode; - if (!SCPI_ParamChoice(context, g_measureModeChoice, &mode, true)) { - return SCPI_RES_ERR; - } - - SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromParam(context, slotAndSubchannelIndex)) { - return SCPI_RES_ERR; - } - - int err; - if (!channel_dispatcher::setMeasureMode(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, (MeasureMode)mode, &err)) { - SCPI_ErrorPush(context, err); - return SCPI_RES_ERR; - } - - return SCPI_RES_OK; -} - -scpi_result_t scpi_cmd_measureScalarModeQ(scpi_t *context) { - SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromParam(context, slotAndSubchannelIndex)) { - return SCPI_RES_ERR; - } - - MeasureMode mode; - int err; - if (!channel_dispatcher::getMeasureMode(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, mode, &err)) { - SCPI_ErrorPush(context, err); - return SCPI_RES_ERR; - } - - resultChoiceName(context, g_measureModeChoice, mode); - - return SCPI_RES_OK; -} - -scpi_result_t scpi_cmd_measureScalarRange(scpi_t *context) { - int32_t range; - if (!SCPI_ParamInt32(context, &range, true)) { - return SCPI_RES_ERR; - } - - if (range < 0 || range > 255) { - SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); - return SCPI_RES_ERR; - } - - SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromParam(context, slotAndSubchannelIndex)) { - return SCPI_RES_ERR; - } - - int err; - if (!channel_dispatcher::setMeasureRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { - SCPI_ErrorPush(context, err); - return SCPI_RES_ERR; - } - - return SCPI_RES_OK; -} - -scpi_result_t scpi_cmd_measureScalarRangeQ(scpi_t *context) { - SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromParam(context, slotAndSubchannelIndex)) { - return SCPI_RES_ERR; - } - - uint8_t range; - int err; - if (!channel_dispatcher::getMeasureRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { - SCPI_ErrorPush(context, err); - return SCPI_RES_ERR; - } - - SCPI_ResultUInt8(context, range); - - return SCPI_RES_OK; -} - scpi_result_t scpi_cmd_measureDigitalByteQ(scpi_t *context) { SlotAndSubchannelIndex slotAndSubchannelIndex; if (!getChannelFromParam(context, slotAndSubchannelIndex)) { diff --git a/src/eez/modules/psu/scpi/params.cpp b/src/eez/modules/psu/scpi/params.cpp index 5e9e0a3b2..1922c968c 100644 --- a/src/eez/modules/psu/scpi/params.cpp +++ b/src/eez/modules/psu/scpi/params.cpp @@ -243,6 +243,7 @@ bool getChannelFromParam(scpi_t *context, SlotAndSubchannelIndex &slotAndSubchan slotAndSubchannelIndex = channelList.channels[0]; return true; } + SCPI_ErrorPush(context, SCPI_ERROR_HARDWARE_MISSING); return false; } diff --git a/src/eez/modules/psu/scpi/sense.cpp b/src/eez/modules/psu/scpi/sense.cpp index c1051208d..89f808b8f 100644 --- a/src/eez/modules/psu/scpi/sense.cpp +++ b/src/eez/modules/psu/scpi/sense.cpp @@ -26,7 +26,49 @@ namespace eez { namespace psu { namespace scpi { -//////////////////////////////////////////////////////////////////////////////// +static scpi_choice_def_t g_senseFunctionChoice[] = { + { "CURRent", MEASURE_MODE_CURRENT }, + { "VOLTage", MEASURE_MODE_VOLTAGE }, + SCPI_CHOICE_LIST_END /* termination of option list */ +}; + +scpi_result_t scpi_cmd_senseFunctionOn(scpi_t *context) { + int32_t mode; + if (!SCPI_ParamChoice(context, g_senseFunctionChoice, &mode, true)) { + return SCPI_RES_ERR; + } + + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; + } + + int err; + if (!channel_dispatcher::setMeasureMode(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, (MeasureMode)mode, &err)) { + SCPI_ErrorPush(context, err); + return SCPI_RES_ERR; + } + + return SCPI_RES_OK; +} + +scpi_result_t scpi_cmd_senseFunctionOnQ(scpi_t *context) { + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; + } + + MeasureMode mode; + int err; + if (!channel_dispatcher::getMeasureMode(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, mode, &err)) { + SCPI_ErrorPush(context, err); + return SCPI_RES_ERR; + } + + resultChoiceName(context, g_senseFunctionChoice, mode); + + return SCPI_RES_OK; +} static scpi_choice_def_t currentRangeSelection[] = { { "LOW", CURRENT_RANGE_SELECTION_ALWAYS_LOW }, @@ -35,81 +77,282 @@ static scpi_choice_def_t currentRangeSelection[] = { SCPI_CHOICE_LIST_END /* termination of option list */ }; -scpi_result_t scpi_cmd_senseCurrentDcRangeUpper(scpi_t *context) { +scpi_result_t scpi_cmd_senseCurrentDcRange(scpi_t *context) { CurrentRangeSelectionMode mode; - scpi_parameter_t param; - if (!SCPI_Parameter(context, ¶m, true)) { + scpi_parameter_t parameter; + if (!SCPI_Parameter(context, ¶meter, true)) { return SCPI_RES_ERR; } - if (SCPI_ParamIsNumber(¶m, true)) { - float value; - if (!SCPI_ParamToFloat(context, ¶m, &value)) { + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; + } + + Channel *channel = Channel::getBySlotIndex(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex); + if (channel) { + if (SCPI_ParamIsNumber(¶meter, true)) { + float value; + if (!SCPI_ParamToFloat(context, ¶meter, &value)) { + return SCPI_RES_ERR; + } + if (value == 0.05f) { + mode = CURRENT_RANGE_SELECTION_ALWAYS_LOW; + } else if (value == 5.0f) { + mode = CURRENT_RANGE_SELECTION_ALWAYS_HIGH; + } else { + SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); + return SCPI_RES_ERR; + } + } else { + int32_t modeInt; + if (!SCPI_ParamToChoice(context, ¶meter, currentRangeSelection, &modeInt)) { + return SCPI_RES_ERR; + } + mode = (CurrentRangeSelectionMode)modeInt; + } + + if (!channel->hasSupportForCurrentDualRange()) { + SCPI_ErrorPush(context, SCPI_ERROR_HARDWARE_MISSING); return SCPI_RES_ERR; } - if (value == 0.05f) { - mode = CURRENT_RANGE_SELECTION_ALWAYS_LOW; - } else if (value == 5.0f) { - mode = CURRENT_RANGE_SELECTION_ALWAYS_HIGH; - } else { + + if (channel->flags.trackingEnabled) { + SCPI_ErrorPush(context, SCPI_ERROR_EXECUTION_ERROR); + return SCPI_RES_ERR; + } + + channel_dispatcher::setCurrentRangeSelectionMode(*channel, mode); + } else { + int32_t range; + if (!SCPI_ParamToInt32(context, ¶meter, &range)) { + SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); + return SCPI_RES_ERR; + } + + if (range < 0 || range > 255) { SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); return SCPI_RES_ERR; } + + int err; + if (!channel_dispatcher::setMeasureCurrentRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { + SCPI_ErrorPush(context, err); + return SCPI_RES_ERR; + } + } + + return SCPI_RES_OK; +} + +scpi_result_t scpi_cmd_senseCurrentDcRangeQ(scpi_t *context) { + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; + } + + Channel *channel = Channel::getBySlotIndex(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex); + if (channel) { + if (!channel) { + return SCPI_RES_ERR; + } + + if (!channel->hasSupportForCurrentDualRange()) { + SCPI_ErrorPush(context, SCPI_ERROR_HARDWARE_MISSING); + return SCPI_RES_ERR; + } + + if (channel->flags.trackingEnabled) { + SCPI_ErrorPush(context, SCPI_ERROR_EXECUTION_ERROR); + return SCPI_RES_ERR; + } + + CurrentRangeSelectionMode mode = channel->getCurrentRangeSelectionMode(); + + if (mode == CURRENT_RANGE_SELECTION_ALWAYS_LOW) { + SCPI_ResultFloat(context, 0.05f); + } else if (mode == CURRENT_RANGE_SELECTION_ALWAYS_HIGH) { + SCPI_ResultFloat(context, 5); + } else { + SCPI_ResultText(context, "BEST"); + } } else { - int32_t modeInt; - if (!SCPI_ParamToChoice(context, ¶m, currentRangeSelection, &modeInt)) { + uint8_t range; + int err; + if (!channel_dispatcher::getMeasureCurrentRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { + SCPI_ErrorPush(context, err); return SCPI_RES_ERR; } - mode = (CurrentRangeSelectionMode)modeInt; + + SCPI_ResultUInt8(context, range); + } + + return SCPI_RES_OK; +} + +scpi_result_t scpi_cmd_senseVoltageDcRange(scpi_t *context) { + int32_t range; + if (!SCPI_ParamInt32(context, &range, true)) { + return SCPI_RES_ERR; } - Channel *channel = getPowerChannelFromParam(context); - if (!channel) { + if (range < 0 || range > 255) { + SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); return SCPI_RES_ERR; } - if (!channel->hasSupportForCurrentDualRange()) { - SCPI_ErrorPush(context, SCPI_ERROR_HARDWARE_MISSING); + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { return SCPI_RES_ERR; } - if (channel->flags.trackingEnabled) { - SCPI_ErrorPush(context, SCPI_ERROR_EXECUTION_ERROR); + int err; + if (!channel_dispatcher::setMeasureVoltageRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { + SCPI_ErrorPush(context, err); return SCPI_RES_ERR; } - channel_dispatcher::setCurrentRangeSelectionMode(*channel, mode); + return SCPI_RES_OK; +} + +scpi_result_t scpi_cmd_senseVoltageDcRangeQ(scpi_t *context) { + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; + } + + uint8_t range; + int err; + if (!channel_dispatcher::getMeasureVoltageRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { + SCPI_ErrorPush(context, err); + return SCPI_RES_ERR; + } + + SCPI_ResultUInt8(context, range); return SCPI_RES_OK; } -scpi_result_t scpi_cmd_senseCurrentDcRangeUpperQ(scpi_t *context) { - Channel *channel = getPowerChannelFromParam(context); - if (!channel) { +scpi_result_t scpi_cmd_senseCurrentDcNplcycles(scpi_t *context) { + int32_t numPowerLineCycles; + if (!SCPI_ParamInt32(context, &numPowerLineCycles, true)) { + return SCPI_RES_ERR; + } + + if (numPowerLineCycles < 0) { + SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); return SCPI_RES_ERR; } - if (!channel->hasSupportForCurrentDualRange()) { - SCPI_ErrorPush(context, SCPI_ERROR_HARDWARE_MISSING); + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { return SCPI_RES_ERR; } - if (channel->flags.trackingEnabled) { - SCPI_ErrorPush(context, SCPI_ERROR_EXECUTION_ERROR); + int err; + if (!channel_dispatcher::setMeasureCurrentNumPowerLineCylces(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, numPowerLineCycles, &err)) { + SCPI_ErrorPush(context, err); return SCPI_RES_ERR; } - CurrentRangeSelectionMode mode = channel->getCurrentRangeSelectionMode(); + return SCPI_RES_OK; +} - if (mode == CURRENT_RANGE_SELECTION_ALWAYS_LOW) { - SCPI_ResultFloat(context, 0.05f); - } else if (mode == CURRENT_RANGE_SELECTION_ALWAYS_HIGH) { - SCPI_ResultFloat(context, 5); - } else { - SCPI_ResultText(context, "BEST"); +scpi_result_t scpi_cmd_senseCurrentDcNplcyclesQ(scpi_t *context) { + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; } + uint8_t numPowerLineCycles; + int err; + if (!channel_dispatcher::getMeasureCurrentNumPowerLineCycles(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, numPowerLineCycles, &err)) { + SCPI_ErrorPush(context, err); + return SCPI_RES_ERR; + } + + SCPI_ResultUInt8(context, numPowerLineCycles); + + return SCPI_RES_OK; +} + +scpi_result_t scpi_cmd_senseCurrentDcApertureQ(scpi_t *context) { + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; + } + + uint8_t numPowerLineCycles; + int err; + if (!channel_dispatcher::getMeasureCurrentNumPowerLineCycles(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, numPowerLineCycles, &err)) { + SCPI_ErrorPush(context, err); + return SCPI_RES_ERR; + } + + SCPI_ResultFloat(context, numPowerLineCycles / persist_conf::getPowerLineFrequency()); + + return SCPI_RES_OK; +} + +scpi_result_t scpi_cmd_senseVoltageDcNplcycles(scpi_t *context) { + int32_t numPowerLineCycles; + if (!SCPI_ParamInt32(context, &numPowerLineCycles, true)) { + return SCPI_RES_ERR; + } + + if (numPowerLineCycles < 0) { + SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); + return SCPI_RES_ERR; + } + + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; + } + + int err; + if (!channel_dispatcher::setMeasureVoltageNumPowerLineCylces(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, numPowerLineCycles, &err)) { + SCPI_ErrorPush(context, err); + return SCPI_RES_ERR; + } + + return SCPI_RES_OK; +} + +scpi_result_t scpi_cmd_senseVoltageDcNplcyclesQ(scpi_t *context) { + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; + } + + uint8_t numPowerLineCycles; + int err; + if (!channel_dispatcher::getMeasureVoltageNumPowerLineCycles(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, numPowerLineCycles, &err)) { + SCPI_ErrorPush(context, err); + return SCPI_RES_ERR; + } + + SCPI_ResultUInt8(context, numPowerLineCycles); + + return SCPI_RES_OK; +} + +scpi_result_t scpi_cmd_senseVoltageDcApertureQ(scpi_t *context) { + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { + return SCPI_RES_ERR; + } + + uint8_t numPowerLineCycles; + int err; + if (!channel_dispatcher::getMeasureVoltageNumPowerLineCycles(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, numPowerLineCycles, &err)) { + SCPI_ErrorPush(context, err); + return SCPI_RES_ERR; + } + + SCPI_ResultFloat(context, numPowerLineCycles / persist_conf::getPowerLineFrequency()); + return SCPI_RES_OK; } diff --git a/src/eez/modules/psu/scpi/sour.cpp b/src/eez/modules/psu/scpi/sour.cpp index 6ab5037b7..0d2480353 100644 --- a/src/eez/modules/psu/scpi/sour.cpp +++ b/src/eez/modules/psu/scpi/sour.cpp @@ -1467,19 +1467,19 @@ static scpi_choice_def_t g_sourceModeChoice[] = { SCPI_CHOICE_LIST_END /* termination of option list */ }; -scpi_result_t scpi_cmd_sourceMode(scpi_t *context) { - SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromCommandNumber(context, slotAndSubchannelIndex)) { +scpi_result_t scpi_cmd_sourceFunctionOn(scpi_t *context) { + int32_t mode; + if (!SCPI_ParamChoice(context, g_sourceModeChoice, &mode, true)) { return SCPI_RES_ERR; } - int32_t mode; - if (!SCPI_ParamChoice(context, g_sourceModeChoice, &mode, true)) { + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { return SCPI_RES_ERR; } int err; - if (!channel_dispatcher::setMode(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, (SourceMode)mode, &err)) { + if (!channel_dispatcher::setSourceMode(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, (SourceMode)mode, &err)) { SCPI_ErrorPush(context, err); return SCPI_RES_ERR; } @@ -1487,15 +1487,15 @@ scpi_result_t scpi_cmd_sourceMode(scpi_t *context) { return SCPI_RES_OK; } -scpi_result_t scpi_cmd_sourceModeQ(scpi_t *context) { +scpi_result_t scpi_cmd_sourceFunctionOnQ(scpi_t *context) { SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromCommandNumber(context, slotAndSubchannelIndex)) { + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { return SCPI_RES_ERR; } SourceMode mode; int err; - if (!channel_dispatcher::getMode(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, mode, &err)) { + if (!channel_dispatcher::getSourceMode(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, mode, &err)) { SCPI_ErrorPush(context, err); return SCPI_RES_ERR; } @@ -1506,23 +1506,18 @@ scpi_result_t scpi_cmd_sourceModeQ(scpi_t *context) { } scpi_result_t scpi_cmd_sourceCurrentRange(scpi_t *context) { - SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromCommandNumber(context, slotAndSubchannelIndex)) { - return SCPI_RES_ERR; - } - int32_t range; if (!SCPI_ParamInt32(context, &range, true)) { return SCPI_RES_ERR; } - if (range < 5 || range > 7) { - SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { return SCPI_RES_ERR; } int err; - if (!channel_dispatcher::setCurrentRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { + if (!channel_dispatcher::setSourceCurrentRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { SCPI_ErrorPush(context, err); return SCPI_RES_ERR; } @@ -1532,13 +1527,13 @@ scpi_result_t scpi_cmd_sourceCurrentRange(scpi_t *context) { scpi_result_t scpi_cmd_sourceCurrentRangeQ(scpi_t *context) { SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromCommandNumber(context, slotAndSubchannelIndex)) { + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { return SCPI_RES_ERR; } uint8_t range; int err; - if (!channel_dispatcher::getCurrentRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { + if (!channel_dispatcher::getSourceCurrentRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { SCPI_ErrorPush(context, err); return SCPI_RES_ERR; } @@ -1549,23 +1544,18 @@ scpi_result_t scpi_cmd_sourceCurrentRangeQ(scpi_t *context) { } scpi_result_t scpi_cmd_sourceVoltageRange(scpi_t *context) { - SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromCommandNumber(context, slotAndSubchannelIndex)) { - return SCPI_RES_ERR; - } - int32_t range; if (!SCPI_ParamInt32(context, &range, true)) { return SCPI_RES_ERR; } - if (range < 0 || range > 3) { - SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); + SlotAndSubchannelIndex slotAndSubchannelIndex; + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { return SCPI_RES_ERR; } int err; - if (!channel_dispatcher::setVoltageRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { + if (!channel_dispatcher::setSourceVoltageRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { SCPI_ErrorPush(context, err); return SCPI_RES_ERR; } @@ -1575,13 +1565,13 @@ scpi_result_t scpi_cmd_sourceVoltageRange(scpi_t *context) { scpi_result_t scpi_cmd_sourceVoltageRangeQ(scpi_t *context) { SlotAndSubchannelIndex slotAndSubchannelIndex; - if (!getChannelFromCommandNumber(context, slotAndSubchannelIndex)) { + if (!getChannelFromParam(context, slotAndSubchannelIndex)) { return SCPI_RES_ERR; } uint8_t range; int err; - if (!channel_dispatcher::getVoltageRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { + if (!channel_dispatcher::getSourceVoltageRange(slotAndSubchannelIndex.slotIndex, slotAndSubchannelIndex.subchannelIndex, range, &err)) { SCPI_ErrorPush(context, err); return SCPI_RES_ERR; } diff --git a/src/eez/modules/psu/scpi/syst.cpp b/src/eez/modules/psu/scpi/syst.cpp index fe1b3ed8e..aead29a09 100644 --- a/src/eez/modules/psu/scpi/syst.cpp +++ b/src/eez/modules/psu/scpi/syst.cpp @@ -2310,6 +2310,27 @@ scpi_result_t scpi_cmd_systemChannelPinLabelQ(scpi_t *context) { return SCPI_RES_OK; } +scpi_result_t scpi_cmd_systemLfrequency(scpi_t *context) { + uint32_t powerLineFrequency; + if (!SCPI_ParamUInt32(context, &powerLineFrequency, false)) { + return SCPI_RES_ERR; + } + + if (powerLineFrequency != 50 && powerLineFrequency != 60) { + SCPI_ErrorPush(context, SCPI_ERROR_ILLEGAL_PARAMETER_VALUE); + return SCPI_RES_ERR; + } + + persist_conf::setPowerLineFrequency(powerLineFrequency); + + return SCPI_RES_OK; +} + +scpi_result_t scpi_cmd_systemLfrequencyQ(scpi_t *context) { + SCPI_ResultUInt32(context, persist_conf::getPowerLineFrequency()); + return SCPI_RES_OK; +} + } // namespace scpi } // namespace psu } // namespace eez diff --git a/src/eez/scpi/commands_simulator.h b/src/eez/scpi/commands_simulator.h index 9c6725680..facd231ec 100644 --- a/src/eez/scpi/commands_simulator.h +++ b/src/eez/scpi/commands_simulator.h @@ -79,10 +79,6 @@ SCPI_COMMAND("MEASure[:SCALar]:CURRent[:DC]?", scpi_cmd_measureScalarCurrentDcQ) \ SCPI_COMMAND("MEASure[:SCALar]:POWer[:DC]?", scpi_cmd_measureScalarPowerDcQ) \ SCPI_COMMAND("MEASure[:SCALar][:VOLTage][:DC]?", scpi_cmd_measureScalarVoltageDcQ) \ - SCPI_COMMAND("MEASure[:SCALar]:MODe", scpi_cmd_measureScalarMode) \ - SCPI_COMMAND("MEASure[:SCALar]:MODe?", scpi_cmd_measureScalarModeQ) \ - SCPI_COMMAND("MEASure[:SCALar]:RANGe", scpi_cmd_measureScalarRange) \ - SCPI_COMMAND("MEASure[:SCALar]:RANGe?", scpi_cmd_measureScalarRangeQ) \ SCPI_COMMAND("MEASure:DIGital[:BYTE]?", scpi_cmd_measureDigitalByteQ) \ SCPI_COMMAND("MEMory:NSTates?", scpi_cmd_memoryNstatesQ) \ SCPI_COMMAND("MEMory:STATe:CATalog?", scpi_cmd_memoryStateCatalogQ) \ @@ -144,8 +140,18 @@ SCPI_COMMAND("ROUTe:LABel:COLumn?", scpi_cmd_routeLabelColumnQ) \ SCPI_COMMAND("ROUTe:LABel:CHANnel", scpi_cmd_routeLabelChannel) \ SCPI_COMMAND("ROUTe:LABel:CHANnel?", scpi_cmd_routeLabelChannelQ) \ - SCPI_COMMAND("SENSe:CURRent[:DC]:RANGe[:UPPer]", scpi_cmd_senseCurrentDcRangeUpper) \ - SCPI_COMMAND("SENSe:CURRent[:DC]:RANGe[:UPPer]?", scpi_cmd_senseCurrentDcRangeUpperQ) \ + SCPI_COMMAND("SENSe:FUNCtion[:ON]", scpi_cmd_senseFunctionOn) \ + SCPI_COMMAND("SENSe:FUNCtion[:ON]?", scpi_cmd_senseFunctionOnQ) \ + SCPI_COMMAND("[SENSe]:CURRent[:DC]:RANGe", scpi_cmd_senseCurrentDcRange) \ + SCPI_COMMAND("[SENSe]:CURRent[:DC]:RANGe?", scpi_cmd_senseCurrentDcRangeQ) \ + SCPI_COMMAND("[SENSe]:VOLTage[:DC]:RANGe", scpi_cmd_senseVoltageDcRange) \ + SCPI_COMMAND("[SENSe]:VOLTage[:DC]:RANGe?", scpi_cmd_senseVoltageDcRangeQ) \ + SCPI_COMMAND("SENSe:CURRent[:DC]:NPLCycles", scpi_cmd_senseCurrentDcNplcycles) \ + SCPI_COMMAND("SENSe:CURRent[:DC]:NPLCycles?", scpi_cmd_senseCurrentDcNplcyclesQ) \ + SCPI_COMMAND("SENSe:CURRent[:DC]:APERture?", scpi_cmd_senseCurrentDcApertureQ) \ + SCPI_COMMAND("SENSe:VOLTage[:DC]:NPLCycles", scpi_cmd_senseVoltageDcNplcycles) \ + SCPI_COMMAND("SENSe:VOLTage[:DC]:NPLCycles?", scpi_cmd_senseVoltageDcNplcyclesQ) \ + SCPI_COMMAND("SENSe:VOLTage[:DC]:APERture?", scpi_cmd_senseVoltageDcApertureQ) \ SCPI_COMMAND("SENSe:DLOG:FUNCtion:CURRent", scpi_cmd_senseDlogFunctionCurrent) \ SCPI_COMMAND("SENSe:DLOG:FUNCtion:CURRent?", scpi_cmd_senseDlogFunctionCurrentQ) \ SCPI_COMMAND("SENSe:DLOG:FUNCtion:POWer", scpi_cmd_senseDlogFunctionPower) \ @@ -248,12 +254,12 @@ SCPI_COMMAND("[SOURce#]:DIGital:RANGe?", scpi_cmd_sourceDigitalRangeQ) \ SCPI_COMMAND("[SOURce#]:DIGital:SPEED", scpi_cmd_sourceDigitalSpeed) \ SCPI_COMMAND("[SOURce#]:DIGital:SPEED?", scpi_cmd_sourceDigitalSpeedQ) \ - SCPI_COMMAND("[SOURce#]:MODe", scpi_cmd_sourceMode) \ - SCPI_COMMAND("[SOURce#]:MODe?", scpi_cmd_sourceModeQ) \ - SCPI_COMMAND("[SOURce#]:CURRent:RANGe", scpi_cmd_sourceCurrentRange) \ - SCPI_COMMAND("[SOURce#]:CURRent:RANGe?", scpi_cmd_sourceCurrentRangeQ) \ - SCPI_COMMAND("[SOURce#]:VOLTage:RANGe", scpi_cmd_sourceVoltageRange) \ - SCPI_COMMAND("[SOURce#]:VOLTage:RANGe?", scpi_cmd_sourceVoltageRangeQ) \ + SCPI_COMMAND("SOURce:FUNCtion[:ON]", scpi_cmd_sourceFunctionOn) \ + SCPI_COMMAND("SOURce:FUNCtion[:ON]?", scpi_cmd_sourceFunctionOnQ) \ + SCPI_COMMAND("SOURce:CURRent:RANGe", scpi_cmd_sourceCurrentRange) \ + SCPI_COMMAND("SOURce:CURRent:RANGe?", scpi_cmd_sourceCurrentRangeQ) \ + SCPI_COMMAND("SOURce:VOLTage:RANGe", scpi_cmd_sourceVoltageRange) \ + SCPI_COMMAND("SOURce:VOLTage:RANGe?", scpi_cmd_sourceVoltageRangeQ) \ SCPI_COMMAND("STATus:OPERation:CONDition?", scpi_cmd_statusOperationConditionQ) \ SCPI_COMMAND("STATus:OPERation:ENABle", scpi_cmd_statusOperationEnable) \ SCPI_COMMAND("STATus:OPERation:ENABle?", scpi_cmd_statusOperationEnableQ) \ @@ -404,6 +410,8 @@ SCPI_COMMAND("SYSTem:TIME:ZONE?", scpi_cmd_systemTimeZoneQ) \ SCPI_COMMAND("SYSTem:TIME?", scpi_cmd_systemTimeQ) \ SCPI_COMMAND("SYSTem:VERSion?", scpi_cmd_systemVersionQ) \ + SCPI_COMMAND("SYSTem:LFRequency", scpi_cmd_systemLfrequency) \ + SCPI_COMMAND("SYSTem:LFRequency?", scpi_cmd_systemLfrequencyQ) \ SCPI_COMMAND("TRIGger:DLOG:SOURce", scpi_cmd_triggerDlogSource) \ SCPI_COMMAND("TRIGger:DLOG:SOURce?", scpi_cmd_triggerDlogSourceQ) \ SCPI_COMMAND("TRIGger:DLOG[:IMMediate]", scpi_cmd_triggerDlogImmediate) \ diff --git a/src/eez/scpi/commands_stm32.h b/src/eez/scpi/commands_stm32.h index 9c6725680..facd231ec 100644 --- a/src/eez/scpi/commands_stm32.h +++ b/src/eez/scpi/commands_stm32.h @@ -79,10 +79,6 @@ SCPI_COMMAND("MEASure[:SCALar]:CURRent[:DC]?", scpi_cmd_measureScalarCurrentDcQ) \ SCPI_COMMAND("MEASure[:SCALar]:POWer[:DC]?", scpi_cmd_measureScalarPowerDcQ) \ SCPI_COMMAND("MEASure[:SCALar][:VOLTage][:DC]?", scpi_cmd_measureScalarVoltageDcQ) \ - SCPI_COMMAND("MEASure[:SCALar]:MODe", scpi_cmd_measureScalarMode) \ - SCPI_COMMAND("MEASure[:SCALar]:MODe?", scpi_cmd_measureScalarModeQ) \ - SCPI_COMMAND("MEASure[:SCALar]:RANGe", scpi_cmd_measureScalarRange) \ - SCPI_COMMAND("MEASure[:SCALar]:RANGe?", scpi_cmd_measureScalarRangeQ) \ SCPI_COMMAND("MEASure:DIGital[:BYTE]?", scpi_cmd_measureDigitalByteQ) \ SCPI_COMMAND("MEMory:NSTates?", scpi_cmd_memoryNstatesQ) \ SCPI_COMMAND("MEMory:STATe:CATalog?", scpi_cmd_memoryStateCatalogQ) \ @@ -144,8 +140,18 @@ SCPI_COMMAND("ROUTe:LABel:COLumn?", scpi_cmd_routeLabelColumnQ) \ SCPI_COMMAND("ROUTe:LABel:CHANnel", scpi_cmd_routeLabelChannel) \ SCPI_COMMAND("ROUTe:LABel:CHANnel?", scpi_cmd_routeLabelChannelQ) \ - SCPI_COMMAND("SENSe:CURRent[:DC]:RANGe[:UPPer]", scpi_cmd_senseCurrentDcRangeUpper) \ - SCPI_COMMAND("SENSe:CURRent[:DC]:RANGe[:UPPer]?", scpi_cmd_senseCurrentDcRangeUpperQ) \ + SCPI_COMMAND("SENSe:FUNCtion[:ON]", scpi_cmd_senseFunctionOn) \ + SCPI_COMMAND("SENSe:FUNCtion[:ON]?", scpi_cmd_senseFunctionOnQ) \ + SCPI_COMMAND("[SENSe]:CURRent[:DC]:RANGe", scpi_cmd_senseCurrentDcRange) \ + SCPI_COMMAND("[SENSe]:CURRent[:DC]:RANGe?", scpi_cmd_senseCurrentDcRangeQ) \ + SCPI_COMMAND("[SENSe]:VOLTage[:DC]:RANGe", scpi_cmd_senseVoltageDcRange) \ + SCPI_COMMAND("[SENSe]:VOLTage[:DC]:RANGe?", scpi_cmd_senseVoltageDcRangeQ) \ + SCPI_COMMAND("SENSe:CURRent[:DC]:NPLCycles", scpi_cmd_senseCurrentDcNplcycles) \ + SCPI_COMMAND("SENSe:CURRent[:DC]:NPLCycles?", scpi_cmd_senseCurrentDcNplcyclesQ) \ + SCPI_COMMAND("SENSe:CURRent[:DC]:APERture?", scpi_cmd_senseCurrentDcApertureQ) \ + SCPI_COMMAND("SENSe:VOLTage[:DC]:NPLCycles", scpi_cmd_senseVoltageDcNplcycles) \ + SCPI_COMMAND("SENSe:VOLTage[:DC]:NPLCycles?", scpi_cmd_senseVoltageDcNplcyclesQ) \ + SCPI_COMMAND("SENSe:VOLTage[:DC]:APERture?", scpi_cmd_senseVoltageDcApertureQ) \ SCPI_COMMAND("SENSe:DLOG:FUNCtion:CURRent", scpi_cmd_senseDlogFunctionCurrent) \ SCPI_COMMAND("SENSe:DLOG:FUNCtion:CURRent?", scpi_cmd_senseDlogFunctionCurrentQ) \ SCPI_COMMAND("SENSe:DLOG:FUNCtion:POWer", scpi_cmd_senseDlogFunctionPower) \ @@ -248,12 +254,12 @@ SCPI_COMMAND("[SOURce#]:DIGital:RANGe?", scpi_cmd_sourceDigitalRangeQ) \ SCPI_COMMAND("[SOURce#]:DIGital:SPEED", scpi_cmd_sourceDigitalSpeed) \ SCPI_COMMAND("[SOURce#]:DIGital:SPEED?", scpi_cmd_sourceDigitalSpeedQ) \ - SCPI_COMMAND("[SOURce#]:MODe", scpi_cmd_sourceMode) \ - SCPI_COMMAND("[SOURce#]:MODe?", scpi_cmd_sourceModeQ) \ - SCPI_COMMAND("[SOURce#]:CURRent:RANGe", scpi_cmd_sourceCurrentRange) \ - SCPI_COMMAND("[SOURce#]:CURRent:RANGe?", scpi_cmd_sourceCurrentRangeQ) \ - SCPI_COMMAND("[SOURce#]:VOLTage:RANGe", scpi_cmd_sourceVoltageRange) \ - SCPI_COMMAND("[SOURce#]:VOLTage:RANGe?", scpi_cmd_sourceVoltageRangeQ) \ + SCPI_COMMAND("SOURce:FUNCtion[:ON]", scpi_cmd_sourceFunctionOn) \ + SCPI_COMMAND("SOURce:FUNCtion[:ON]?", scpi_cmd_sourceFunctionOnQ) \ + SCPI_COMMAND("SOURce:CURRent:RANGe", scpi_cmd_sourceCurrentRange) \ + SCPI_COMMAND("SOURce:CURRent:RANGe?", scpi_cmd_sourceCurrentRangeQ) \ + SCPI_COMMAND("SOURce:VOLTage:RANGe", scpi_cmd_sourceVoltageRange) \ + SCPI_COMMAND("SOURce:VOLTage:RANGe?", scpi_cmd_sourceVoltageRangeQ) \ SCPI_COMMAND("STATus:OPERation:CONDition?", scpi_cmd_statusOperationConditionQ) \ SCPI_COMMAND("STATus:OPERation:ENABle", scpi_cmd_statusOperationEnable) \ SCPI_COMMAND("STATus:OPERation:ENABle?", scpi_cmd_statusOperationEnableQ) \ @@ -404,6 +410,8 @@ SCPI_COMMAND("SYSTem:TIME:ZONE?", scpi_cmd_systemTimeZoneQ) \ SCPI_COMMAND("SYSTem:TIME?", scpi_cmd_systemTimeQ) \ SCPI_COMMAND("SYSTem:VERSion?", scpi_cmd_systemVersionQ) \ + SCPI_COMMAND("SYSTem:LFRequency", scpi_cmd_systemLfrequency) \ + SCPI_COMMAND("SYSTem:LFRequency?", scpi_cmd_systemLfrequencyQ) \ SCPI_COMMAND("TRIGger:DLOG:SOURce", scpi_cmd_triggerDlogSource) \ SCPI_COMMAND("TRIGger:DLOG:SOURce?", scpi_cmd_triggerDlogSourceQ) \ SCPI_COMMAND("TRIGger:DLOG[:IMMediate]", scpi_cmd_triggerDlogImmediate) \