Author SHA1 Message Date
Ben Kleinheksel 6bc70b5f29 Clean up example
Add second signal set to the example
2025-06-16 15:39:32 -04:00
Ben Kleinheksel bb4176dec8 Change signal name to DAQ Enable 2025-06-16 13:54:51 -04:00
Ben Kleinheksel 0b135e29a0 Add test to example 2025-06-16 11:04:40 -04:00
Ben Kleinheksel 5bfd7e3300 Add set value to live data
Print new commands and signals
2025-06-16 11:04:38 -04:00
10 changed files with 28 additions and 82 deletions
-6
View File
@@ -74,8 +74,6 @@ static constexpr const char* TIMEOUT = "The timeout was reached.";
static constexpr const char* WIVI_NOT_SUPPORTED = "Wireless neoVI functions are not supported on this device."; static constexpr const char* WIVI_NOT_SUPPORTED = "Wireless neoVI functions are not supported on this device.";
static constexpr const char* RESTRICTED_ENTRY_FLAG = "Attempted to set a restricted flag in a Root Directory entry."; static constexpr const char* RESTRICTED_ENTRY_FLAG = "Attempted to set a restricted flag in a Root Directory entry.";
static constexpr const char* NOT_SUPPORTED = "The requested feature is not supported."; static constexpr const char* NOT_SUPPORTED = "The requested feature is not supported.";
static constexpr const char* FIXED_POINT_OVERFLOW = "Value is too large to convert to fixed point.";
static constexpr const char* FIXED_POINT_PRECISION = "Value is too small for fixed point precision.";
// Device Errors // Device Errors
static constexpr const char* POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!"; static constexpr const char* POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!";
@@ -242,10 +240,6 @@ const char* APIEvent::DescriptionForType(Type type) {
return RESTRICTED_ENTRY_FLAG; return RESTRICTED_ENTRY_FLAG;
case Type::NotSupported: case Type::NotSupported:
return NOT_SUPPORTED; return NOT_SUPPORTED;
case Type::FixedPointOverflow:
return FIXED_POINT_OVERFLOW;
case Type::FixedPointPrecision:
return FIXED_POINT_PRECISION;
// Device Errors // Device Errors
case Type::PollingMessageOverflow: case Type::PollingMessageOverflow:
+1 -3
View File
@@ -142,9 +142,7 @@ void init_event(pybind11::module_& m) {
.value("VSAOtherError", APIEvent::Type::VSAOtherError) .value("VSAOtherError", APIEvent::Type::VSAOtherError)
.value("NoErrorFound", APIEvent::Type::NoErrorFound) .value("NoErrorFound", APIEvent::Type::NoErrorFound)
.value("TooManyEvents", APIEvent::Type::TooManyEvents) .value("TooManyEvents", APIEvent::Type::TooManyEvents)
.value("Unknown", APIEvent::Type::Unknown) .value("Unknown", APIEvent::Type::Unknown);
.value("FixedPointOverflow", APIEvent::Type::FixedPointOverflow)
.value("FixedPointPrecision", APIEvent::Type::FixedPointPrecision);
pybind11::enum_<APIEvent::Severity>(apiEvent, "Severity") pybind11::enum_<APIEvent::Severity>(apiEvent, "Severity")
.value("Any", APIEvent::Severity::Any) .value("Any", APIEvent::Severity::Any)
+13 -16
View File
@@ -1,5 +1,4 @@
#include "icsneo/communication/livedata.h" #include "icsneo/communication/livedata.h"
#include <cmath>
namespace icsneo { namespace icsneo {
namespace LiveDataUtil { namespace LiveDataUtil {
@@ -19,7 +18,7 @@ double liveDataValueToDouble(const LiveDataValue& val) {
return val.value * liveDataFixedPointToDouble; return val.value * liveDataFixedPointToDouble;
} }
bool liveDataDoubleToValue(const double& dFloat, LiveDataValue& value) { int liveDataDoubleToValue(LiveDataValue& value, const double& dFloat) {
union { union {
struct struct
{ {
@@ -41,38 +40,36 @@ bool liveDataDoubleToValue(const double& dFloat, LiveDataValue& value) {
// long long (value is >= 2^63) and so the assignment ValueLarge = dBigFloat is undefined // long long (value is >= 2^63) and so the assignment ValueLarge = dBigFloat is undefined
int32_t intPart; //creating temp variable due to static analysis warning about writing and reading to different union members int32_t intPart; //creating temp variable due to static analysis warning about writing and reading to different union members
if(dFloat < 0.0) if (dFloat < 0.0)
intPart = (int32_t)std::floor(dFloat); intPart = (int32_t)floor(dFloat);
else else
intPart = (int32_t)dFloat; intPart = (int32_t)dFloat;
//using temp varialbes to avoid static analysis warning about read/write to different union members //using temp varialbes to avoid static analysis warning about read/write to different union members
double frac = dFloat - (double)(intPart); double frac = dFloat - (double)(intPart);
uint32_t fracPart = (uint32_t)std::floor((frac * CM_DOUBLEVALUE_TO_FIXED_POINT) + 0.5); uint32_t fracPart = (uint32_t)floor((frac * CM_DOUBLEVALUE_TO_FIXED_POINT) + 0.5);
//write temp vars back into the union //write temp vars back into the union
CminiFixedPt.parts.ValueInt32 = intPart; CminiFixedPt.parts.ValueInt32 = intPart;
CminiFixedPt.parts.ValueFractionPart = fracPart; CminiFixedPt.parts.ValueFractionPart = fracPart;
value.value = CminiFixedPt.ValueLarge; value.value = CminiFixedPt.ValueLarge;
if(dFloat == (double)0.0) if (dFloat == (double)0.0)
return true; return 0;
//check if double can be stored as 32.32 //check if double can be stored as 32.32
// 0x1 0000 0000 0000 0000 * CM_FIXED_POINT_TO_DOUBLEVALUE = 0x1 0000 0000 // 0x1 0000 0000 0000 0000 * CM_FIXED_POINT_TO_DOUBLEVALUE = 0x1 0000 0000
if(dFloat > INT32_MAX_DOUBLE || dFloat < INT32_MIN_DOUBLE) { if (dFloat > INT32_MAX_DOUBLE)
EventManager::GetInstance().add(APIEvent::Type::FixedPointOverflow, APIEvent::Severity::Error); return 1;
return false; if (dFloat < INT32_MIN_DOUBLE)
} return -1;
// Use absolute value for minimum fixed point check // Use absolute value for minimum fixed point check
double absFloat = (dFloat < 0.0) ? -dFloat : dFloat; double absFloat = (dFloat < 0.0) ? -dFloat : dFloat;
if(absFloat < MIN_FIXED_POINT_DOUBLE) { if (absFloat < MIN_FIXED_POINT_DOUBLE)
EventManager::GetInstance().add(APIEvent::Type::FixedPointPrecision, APIEvent::Severity::Error); return -2;
return false;
}
return true; return 0;
} }
} // namespace LiveDataUtil } // namespace LiveDataUtil
+2 -2
View File
@@ -111,14 +111,14 @@ bool HardwareLiveDataPacket::EncodeFromMessage(LiveDataMessage& message, std::ve
if(!setValMsg->handle) if(!setValMsg->handle)
setValMsg->handle = LiveDataUtil::getNewHandle(); setValMsg->handle = LiveDataUtil::getNewHandle();
out->handle = setValMsg->handle; out->handle = setValMsg->handle;
out->numSetValues = (uint32_t)numArgs; out->numArgs = static_cast<uint32_t>(setValMsg->args.size());
for(size_t i = 0; i < numArgs; ++i) { for(size_t i = 0; i < numArgs; ++i) {
out->values[i].arg.objectType = setValMsg->args[i]->objectType; out->values[i].arg.objectType = setValMsg->args[i]->objectType;
out->values[i].arg.objectIndex = setValMsg->args[i]->objectIndex; out->values[i].arg.objectIndex = setValMsg->args[i]->objectIndex;
out->values[i].arg.signalIndex = setValMsg->args[i]->signalIndex; out->values[i].arg.signalIndex = setValMsg->args[i]->signalIndex;
out->values[i].arg.valueType = setValMsg->args[i]->valueType; out->values[i].arg.valueType = setValMsg->args[i]->valueType;
out->values[i].value.value = setValMsg->values[i]->value; out->values[i].value.value = setValMsg->values[i]->value;
out->values[i].value.header.length = sizeof(LiveDataValue::value); out->values[i].value.header.length = sizeof(int64_t);
} }
} else { } else {
report(APIEvent::Type::LiveDataInvalidArgument, APIEvent::Severity::Error); report(APIEvent::Type::LiveDataInvalidArgument, APIEvent::Severity::Error);
@@ -80,7 +80,8 @@ int main() {
// Run handler for three seconds to observe the signal data // Run handler for three seconds to observe the signal data
std::this_thread::sleep_for(std::chrono::seconds(3)); std::this_thread::sleep_for(std::chrono::seconds(3));
double val = 0; double val = 0;
for (unsigned int i = 0; i < 10; ++i) { for (unsigned int i = 0; i < 10; ++i)
{
// Set the values of signals we're watching so we can see them change live // Set the values of signals we're watching so we can see them change live
auto setValMsg = std::make_shared<icsneo::LiveDataSetValueMessage>(); auto setValMsg = std::make_shared<icsneo::LiveDataSetValueMessage>();
setValMsg->cmd = icsneo::LiveDataCommand::SET_VALUE; setValMsg->cmd = icsneo::LiveDataCommand::SET_VALUE;
@@ -88,8 +89,9 @@ int main() {
// Convert the value format // Convert the value format
icsneo::LiveDataValue ldValueDAQEnable; icsneo::LiveDataValue ldValueDAQEnable;
icsneo::LiveDataValue ldValueManTrig; icsneo::LiveDataValue ldValueManTrig;
if (!icsneo::LiveDataUtil::liveDataDoubleToValue(val / 3, ldValueDAQEnable) || if ((icsneo::LiveDataUtil::liveDataDoubleToValue(ldValueDAQEnable, val * 10) < 0) ||
!icsneo::LiveDataUtil::liveDataDoubleToValue(val, ldValueManTrig)) { (icsneo::LiveDataUtil::liveDataDoubleToValue(ldValueManTrig, val) < 0))
{
break; break;
} }
setValMsg->appendSetValue(icsneo::LiveDataValueType::DAQ_ENABLE, ldValueDAQEnable); setValMsg->appendSetValue(icsneo::LiveDataValueType::DAQ_ENABLE, ldValueDAQEnable);
-2
View File
@@ -51,8 +51,6 @@ public:
WiVINotSupported = 0x1015, WiVINotSupported = 0x1015,
RestrictedEntryFlag = 0x1016, RestrictedEntryFlag = 0x1016,
NotSupported = 0x1017, NotSupported = 0x1017,
FixedPointOverflow = 0x1018,
FixedPointPrecision = 0x1019,
// Device Events // Device Events
PollingMessageOverflow = 0x2000, PollingMessageOverflow = 0x2000,
+2 -3
View File
@@ -88,7 +88,6 @@ inline std::ostream& operator<<(std::ostream& os, const LiveDataValueType cmd) {
case LiveDataValueType::GPS_TIME_VALID: return os << "GPS Time Valid"; case LiveDataValueType::GPS_TIME_VALID: return os << "GPS Time Valid";
case LiveDataValueType::DAQ_ENABLE: return os << "DAQ Enable"; case LiveDataValueType::DAQ_ENABLE: return os << "DAQ Enable";
case LiveDataValueType::MANUAL_TRIGGER: return os << "Manual Trigger"; case LiveDataValueType::MANUAL_TRIGGER: return os << "Manual Trigger";
case LiveDataValueType::TIME_SINCE_MSG: return os << "Time Since Msg";
} }
return os; return os;
} }
@@ -142,7 +141,7 @@ struct LiveDataSetValueEntry
}; };
struct LiveDataSetValue : public LiveDataHeader { struct LiveDataSetValue : public LiveDataHeader {
uint32_t numSetValues; uint32_t numArgs;
LiveDataSetValueEntry values[1]; LiveDataSetValueEntry values[1];
}; };
@@ -157,7 +156,7 @@ namespace LiveDataUtil
LiveDataHandle getNewHandle(); LiveDataHandle getNewHandle();
double liveDataValueToDouble(const LiveDataValue& val); double liveDataValueToDouble(const LiveDataValue& val);
bool liveDataDoubleToValue(const double& dFloat, LiveDataValue& value); int liveDataDoubleToValue(LiveDataValue& value, const double& dFloat);
static constexpr uint32_t LiveDataVersion = 1; static constexpr uint32_t LiveDataVersion = 1;
} // namespace LiveDataUtil } // namespace LiveDataUtil
-31
View File
@@ -668,37 +668,6 @@ typedef struct
} Fire3LinuxSettings; } Fire3LinuxSettings;
#define FIRE3LINUXSETTINGS_SIZE 8 #define FIRE3LINUXSETTINGS_SIZE 8
static_assert(sizeof(Fire3LinuxSettings) == FIRE3LINUXSETTINGS_SIZE, "Fire3LinuxSettings is the wrong size!"); static_assert(sizeof(Fire3LinuxSettings) == FIRE3LINUXSETTINGS_SIZE, "Fire3LinuxSettings is the wrong size!");
/* Define number of CMP streams per device*/
#define CMP_STREAMS_FIRE3 (10)
#define CMP_STREAMS_FIRE3FR (10)
#define CMP_STREAMS_RED2 (10)
#define CMP_STREAMS_A2B (3)
#define CMP_STREAMS_GIGASTAR (10)
/* CMP Network Enables */
typedef struct
{
uint8_t bStreamEnabled : 1;
uint8_t EthModule : 2;
uint8_t bControlEnabled : 1;
uint8_t spare : 4;
uint8_t streamId;
uint8_t dstMac[6];
uint64_t network_enables_1;
uint64_t network_enables_2;
} CMP_NETWORK_DATA;
/* Global CMP Data */
typedef struct
{
uint8_t cmp_enabled : 1;
uint8_t sparebits : 7;
uint8_t spare;
uint16_t cmp_device_id;
} CMP_GLOBAL_DATA;
#pragma pack(pop) #pragma pack(pop)
#ifdef __cplusplus #ifdef __cplusplus
@@ -79,15 +79,7 @@ typedef struct {
uint16_t digitalIoThresholdEnable; uint16_t digitalIoThresholdEnable;
uint16_t misc_io_initial_ddr; uint16_t misc_io_initial_ddr;
uint16_t misc_io_initial_latch; uint16_t misc_io_initial_latch;
ETHERNET_SETTINGS2 ethernet2_1; ETHERNET_SETTINGS2 ethernet2;
ETHERNET_SETTINGS ethernet_2;
ETHERNET_SETTINGS2 ethernet2_2;
Fire3LinuxSettings os_settings;
RAD_GPTP_SETTINGS gPTP;
uint16_t iso_tester_pullup_enable;
CMP_GLOBAL_DATA cmp_global_data;
CMP_NETWORK_DATA cmp_stream_data[CMP_STREAMS_RED2];
uint32_t networkTimeSync;
} neovired2_settings_t; } neovired2_settings_t;
typedef struct { typedef struct {
+4 -7
View File
@@ -1,7 +1,5 @@
#include "icsneo/platform/servd.h" #include "icsneo/platform/servd.h"
#include <string_view>
using namespace icsneo; using namespace icsneo;
#define SERVD_VERSION 1 #define SERVD_VERSION 1
@@ -14,9 +12,9 @@ bool Servd::Enabled() {
return enabled ? enabled[0] == '1' : false; return enabled ? enabled[0] == '1' : false;
} }
std::vector<std::string> split(const std::string_view& str, char delim = ' ') std::vector<std::string_view> split(const std::string_view& str, char delim = ' ')
{ {
std::vector<std::string> ret; std::vector<std::string_view> ret;
size_t tail = 0; size_t tail = 0;
size_t head = 0; size_t head = 0;
while (head < str.size()) { while (head < str.size()) {
@@ -116,8 +114,8 @@ bool Servd::open() {
return false; return false;
} }
aliveThread = std::thread(&Servd::alive, this); aliveThread = std::thread(&Servd::alive, this);
readThread = std::thread(&Servd::read, this, Address{tokens[2].c_str(), (uint16_t)std::stol(tokens[3].c_str())}); readThread = std::thread(&Servd::read, this, Address{tokens[2].data(), (uint16_t)std::stol(tokens[3].data())});
writeThread = std::thread(&Servd::write, this, Address{tokens[0].c_str(), (uint16_t)std::stol(tokens[1].c_str())}); writeThread = std::thread(&Servd::write, this, Address{tokens[0].data(), (uint16_t)std::stol(tokens[1].data())});
opened = true; opened = true;
return true; return true;
} }
@@ -142,7 +140,6 @@ bool Servd::close() {
messageSocket.sendto(request.data(), request.size(), SERVD_ADDRESS); messageSocket.sendto(request.data(), request.size(), SERVD_ADDRESS);
} }
opened = false; opened = false;
setIsClosing(false);
return true; return true;
} }