From ced145be15ec5895a5f0301f955dfb5d315bcc70 Mon Sep 17 00:00:00 2001 From: prestonr Date: Wed, 23 Oct 2024 11:14:37 -0700 Subject: [PATCH] Add el2798 driver to jsd --- doc/fastcat_device_config_parameters.md | 12 +++ src/CMakeLists.txt | 2 + src/fcgen/fastcat_types.yaml | 45 +++++++++++ src/jsd/el2798.cc | 101 ++++++++++++++++++++++++ src/jsd/el2798.h | 32 ++++++++ src/jsd/el2798_offline.cc | 100 +++++++++++++++++++++++ src/jsd/el2798_offline.h | 24 ++++++ src/manager.cc | 8 ++ 8 files changed, 324 insertions(+) create mode 100644 src/jsd/el2798.cc create mode 100644 src/jsd/el2798.h create mode 100644 src/jsd/el2798_offline.cc create mode 100644 src/jsd/el2798_offline.h diff --git a/doc/fastcat_device_config_parameters.md b/doc/fastcat_device_config_parameters.md index f6747a69..94f63983 100644 --- a/doc/fastcat_device_config_parameters.md +++ b/doc/fastcat_device_config_parameters.md @@ -15,6 +15,7 @@ For every `JSD Device` there is an `Offline Device` to emulate the behavior of t | El3602 | Beckhoff | 2-channel +/-10v Diff. Analog Input | | El2124 | Beckhoff | 4-channel 5v Digital Output | | El2809 | Beckhoff | 16-channel 24v Digital Output | +| El2798 | Beckhoff | 8-channel 30v AC/48v DC 2A Solid State Relay Output | | El4102 | Beckhoff | 2-channel 0-10v Analog Output | | Ild1900 | Micro-Epsilon | Distance Laser Sensor | | AtiFts | ATI | Force-Torque Sensor | @@ -425,6 +426,17 @@ The permitted range values are: name: el2809_1 ``` +## El2798 (8-channel 30v AC/48v DC 2A Solid State Relay Output) + +**The El2798 device has no configuration parameters** + +#### Example + +``` yaml +- device_class: El2798 + name: el2798_1 +``` + ## El4102 (2-channel 0-10v Analog Output) **The El4102 device has no configuration parameters.** diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ae5d41a..ea1cf692 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -76,6 +76,7 @@ add_library(fastcat STATIC jsd/el3602.cc jsd/el2124.cc jsd/el2809.cc + jsd/el2798.cc jsd/el4102.cc jsd/el3162.cc jsd/el1008.cc @@ -92,6 +93,7 @@ add_library(fastcat STATIC jsd/egd_offline.cc jsd/el2124_offline.cc jsd/el2809_offline.cc + jsd/el2798_offline.cc jsd/el4102_offline.cc jsd/el3208_offline.cc jsd/el3602_offline.cc diff --git a/src/fcgen/fastcat_types.yaml b/src/fcgen/fastcat_types.yaml index a4d20a07..3b63a522 100644 --- a/src/fcgen/fastcat_types.yaml +++ b/src/fcgen/fastcat_types.yaml @@ -349,6 +349,25 @@ states: - name: level_ch16 type: uint8_t + - name: el2798 + fields: + - name: level_ch1 + type: uint8_t + - name: level_ch2 + type: uint8_t + - name: level_ch3 + type: uint8_t + - name: level_ch4 + type: uint8_t + - name: level_ch5 + type: uint8_t + - name: level_ch6 + type: uint8_t + - name: level_ch7 + type: uint8_t + - name: level_ch8 + type: uint8_t + - name: el4102 fields: - name: voltage_output_ch1 @@ -759,6 +778,32 @@ commands: - name: channel_ch16 type: uint8_t + - name: el2798_write_channel + fields: + - name: channel + type: uint8_t + - name: level + type: uint8_t + + - name: el2798_write_all_channels + fields: + - name: channel_ch1 + type: uint8_t + - name: channel_ch2 + type: uint8_t + - name: channel_ch3 + type: uint8_t + - name: channel_ch4 + type: uint8_t + - name: channel_ch5 + type: uint8_t + - name: channel_ch6 + type: uint8_t + - name: channel_ch7 + type: uint8_t + - name: channel_ch8 + type: uint8_t + - name: el4102_write_channel fields: - name: channel diff --git a/src/jsd/el2798.cc b/src/jsd/el2798.cc new file mode 100644 index 00000000..3fb479f1 --- /dev/null +++ b/src/jsd/el2798.cc @@ -0,0 +1,101 @@ +// Include related header (for cc files) +#include "fastcat/jsd/el2798.h" + +// Include c then c++ libraries +#include + +#include +#include + +// Include external then project includes +#include "fastcat/yaml_parser.h" + +fastcat::El2798::El2798() +{ + MSG_DEBUG("Constructed El2798"); + + state_ = std::make_shared(); + state_->type = EL2798_STATE; +} + +bool fastcat::El2798::ConfigFromYaml(const YAML::Node& node) +{ + bool retval = ConfigFromYamlCommon(node); + jsd_set_slave_config((jsd_t*)context_, slave_id_, jsd_slave_config_); + return retval; +} + +bool fastcat::El2798::ConfigFromYamlCommon(const YAML::Node& node) +{ + if (!ParseVal(node, "name", name_)) { + return false; + } + state_->name = name_; + + jsd_slave_config_.configuration_active = true; + jsd_slave_config_.driver_type = JSD_DRIVER_TYPE_EL2798; + snprintf(jsd_slave_config_.name, JSD_NAME_LEN, "%s", name_.c_str()); + + return true; +} + +bool fastcat::El2798::Read() +{ + const jsd_el2798_state_t* jsd_state = + jsd_el2798_get_state((jsd_t*)context_, slave_id_); + + state_->el2798_state.level_ch1 = jsd_state->output[0]; + state_->el2798_state.level_ch2 = jsd_state->output[1]; + state_->el2798_state.level_ch3 = jsd_state->output[2]; + state_->el2798_state.level_ch4 = jsd_state->output[3]; + state_->el2798_state.level_ch5 = jsd_state->output[4]; + state_->el2798_state.level_ch6 = jsd_state->output[5]; + state_->el2798_state.level_ch7 = jsd_state->output[6]; + state_->el2798_state.level_ch8 = jsd_state->output[7]; + + return true; +} + +fastcat::FaultType fastcat::El2798::Process() +{ + jsd_el2798_process((jsd_t*)context_, slave_id_); + return NO_FAULT; +} + +bool fastcat::El2798::Write(DeviceCmd& cmd) +{ + // If device supports async SDO requests + AsyncSdoRetVal sdoResult = WriteAsyncSdoRequest(cmd); + if (sdoResult != SDO_RET_VAL_NOT_APPLICABLE) { + return (sdoResult == SDO_RET_VAL_SUCCESS); + } + + if (cmd.type == EL2798_WRITE_CHANNEL_CMD) { + uint8_t ch = cmd.el2798_write_channel_cmd.channel; + if (ch < 1 || ch > JSD_EL2798_NUM_CHANNELS) { + ERROR("Channel must be in range (1,%u)", JSD_EL2798_NUM_CHANNELS); + return false; + } + + jsd_el2798_write_single_channel((jsd_t*)context_, slave_id_, ch - 1, + cmd.el2798_write_channel_cmd.level); + + } else if (cmd.type == EL2798_WRITE_ALL_CHANNELS_CMD) { + uint8_t output_array[JSD_EL2798_NUM_CHANNELS] = { + cmd.el2798_write_all_channels_cmd.channel_ch1, + cmd.el2798_write_all_channels_cmd.channel_ch2, + cmd.el2798_write_all_channels_cmd.channel_ch3, + cmd.el2798_write_all_channels_cmd.channel_ch4, + cmd.el2798_write_all_channels_cmd.channel_ch5, + cmd.el2798_write_all_channels_cmd.channel_ch6, + cmd.el2798_write_all_channels_cmd.channel_ch7, + cmd.el2798_write_all_channels_cmd.channel_ch8}; + + jsd_el2798_write_all_channels((jsd_t*)context_, slave_id_, output_array); + + } else { + ERROR("Bad EL2798 Command"); + return false; + } + return true; +} diff --git a/src/jsd/el2798.h b/src/jsd/el2798.h new file mode 100644 index 00000000..fcea6fa9 --- /dev/null +++ b/src/jsd/el2798.h @@ -0,0 +1,32 @@ +#ifndef FASTCAT_EL2798_H_ +#define FASTCAT_EL2798_H_ + +// Include related header (for cc files) + +// Include c then c++ libraries + +// Include external then project includes +#include "fastcat/jsd/jsd_device_base.h" +#include "jsd/jsd_el2798_pub.h" + +namespace fastcat +{ +class El2798 : public JsdDeviceBase +{ + public: + El2798(); + bool ConfigFromYaml(const YAML::Node& node) override; + bool Read() override; + FaultType Process() override; + bool Write(DeviceCmd& cmd) override; + + protected: + bool ConfigFromYamlCommon(const YAML::Node& node); + + private: + jsd_slave_config_t jsd_slave_config_ = {0}; +}; + +} // namespace fastcat + +#endif diff --git a/src/jsd/el2798_offline.cc b/src/jsd/el2798_offline.cc new file mode 100644 index 00000000..b5b9a8a7 --- /dev/null +++ b/src/jsd/el2798_offline.cc @@ -0,0 +1,100 @@ +// Include related header (for cc files) +#include "fastcat/jsd/el2798_offline.h" + +// Include c then c++ libraries +#include + +#include +#include + +// Include external then project includes +#include "fastcat/yaml_parser.h" + +bool fastcat::El2798Offline::ConfigFromYaml(const YAML::Node& node) +{ + return ConfigFromYamlCommon(node); +} + +bool fastcat::El2798Offline::Read() { return true; } + +fastcat::FaultType fastcat::El2798Offline::Process() +{ + return DeviceBase::Process(); +} + +bool fastcat::El2798Offline::Write(DeviceCmd& cmd) +{ + // If device supports async SDO requests + AsyncSdoRetVal sdoResult = WriteAsyncSdoRequest(cmd); + if (sdoResult != SDO_RET_VAL_NOT_APPLICABLE) { + return (sdoResult == SDO_RET_VAL_SUCCESS); + } + + if (cmd.type == EL2798_WRITE_CHANNEL_CMD) { + uint8_t ch = cmd.el2798_write_channel_cmd.channel; + if (ch < 1 || ch > JSD_EL2798_NUM_CHANNELS) { + ERROR("Channel must be in range (1,%u)", JSD_EL2798_NUM_CHANNELS); + return false; + } + switch (cmd.el2798_write_channel_cmd.channel) { + case 1: + state_->el2798_state.level_ch1 = cmd.el2798_write_channel_cmd.level; + break; + case 2: + state_->el2798_state.level_ch2 = cmd.el2798_write_channel_cmd.level; + break; + case 3: + state_->el2798_state.level_ch3 = cmd.el2798_write_channel_cmd.level; + break; + case 4: + state_->el2798_state.level_ch4 = cmd.el2798_write_channel_cmd.level; + break; + case 5: + state_->el2798_state.level_ch5 = cmd.el2798_write_channel_cmd.level; + break; + case 6: + state_->el2798_state.level_ch6 = cmd.el2798_write_channel_cmd.level; + break; + case 7: + state_->el2798_state.level_ch7 = cmd.el2798_write_channel_cmd.level; + break; + case 8: + state_->el2798_state.level_ch8 = cmd.el2798_write_channel_cmd.level; + break; + default: + ERROR("Bad Channel value"); + break; + } + return true; + + } else if (cmd.type == EL2798_WRITE_ALL_CHANNELS_CMD) { + state_->el2798_state.level_ch1 = + cmd.el2798_write_all_channels_cmd.channel_ch1; + + state_->el2798_state.level_ch2 = + cmd.el2798_write_all_channels_cmd.channel_ch2; + + state_->el2798_state.level_ch3 = + cmd.el2798_write_all_channels_cmd.channel_ch3; + + state_->el2798_state.level_ch4 = + cmd.el2798_write_all_channels_cmd.channel_ch4; + + state_->el2798_state.level_ch5 = + cmd.el2798_write_all_channels_cmd.channel_ch5; + + state_->el2798_state.level_ch6 = + cmd.el2798_write_all_channels_cmd.channel_ch6; + + state_->el2798_state.level_ch7 = + cmd.el2798_write_all_channels_cmd.channel_ch7; + + state_->el2798_state.level_ch8 = + cmd.el2798_write_all_channels_cmd.channel_ch8; + + } else { + ERROR("Bad EL2798 Command"); + return false; + } + return true; +} diff --git a/src/jsd/el2798_offline.h b/src/jsd/el2798_offline.h new file mode 100644 index 00000000..f1c3b742 --- /dev/null +++ b/src/jsd/el2798_offline.h @@ -0,0 +1,24 @@ +#ifndef FASTCAT_EL2798_OFFLINE_H_ +#define FASTCAT_EL2798_OFFLINE_H_ + +// Include related header (for cc files) + +// Include c then c++ libraries + +// Include external then project includes +#include "fastcat/jsd/el2798.h" + +namespace fastcat +{ +class El2798Offline : public El2798 +{ + public: + bool ConfigFromYaml(const YAML::Node& node) override; + bool Read() override; + FaultType Process() override; + bool Write(DeviceCmd& cmd) override; +}; + +} // namespace fastcat + +#endif diff --git a/src/manager.cc b/src/manager.cc index dd3ab94f..4acd6b8f 100644 --- a/src/manager.cc +++ b/src/manager.cc @@ -37,6 +37,8 @@ #include "fastcat/jsd/el2124_offline.h" #include "fastcat/jsd/el2809.h" #include "fastcat/jsd/el2809_offline.h" +#include "fastcat/jsd/el2798.h" +#include "fastcat/jsd/el2798_offline.h" #include "fastcat/jsd/el3104.h" #include "fastcat/jsd/el3104_offline.h" #include "fastcat/jsd/el3162.h" @@ -462,6 +464,9 @@ bool fastcat::Manager::ConfigJSDBusFromYaml(const YAML::Node& node, } else if (0 == device_class.compare("El2809")) { device = std::make_shared(); + } else if (0 == device_class.compare("El2798")) { + device = std::make_shared(); + } else if (0 == device_class.compare("El4102")) { device = std::make_shared(); @@ -692,6 +697,9 @@ bool fastcat::Manager::ConfigOfflineBusFromYaml(const YAML::Node& node, } else if (0 == device_class.compare("El2809")) { device = std::make_shared(); + } else if (0 == device_class.compare("El2798")) { + device = std::make_shared(); + } else if (0 == device_class.compare("El3208")) { device = std::make_shared();