Compare commits

...

10 Commits

Author SHA1 Message Date
vits71 9e66d7f850
Merge 739ff4d637 into 89047447a6 2025-03-14 14:52:21 -04:00
Kyle Schwarz 89047447a6 Bindings: Python: Add DoIP Ethernet Activation 2025-03-10 10:50:25 -04:00
Kyle Schwarz f97fd75b8d Docs: icsneopy: Add TC10 example 2025-03-03 17:06:22 -05:00
Yasser Yassine ea5f11268c RADMoon2: Enable communication for MDIO 2025-02-26 02:40:01 +00:00
Yasser Yassine 759cb2436d Device: RM2 & RM3: Update settings 2025-02-25 22:45:08 +00:00
Kyle Schwarz 771d82826f CI: Delay GitHub push 2025-02-20 15:31:45 -05:00
Yaroslav Stetsyk b7330a2cea RADMoon3: Add TC10 2025-02-20 19:24:33 +00:00
Kyle Schwarz fb3778f91b Bindings: Python: Rework disk bindings 2025-02-20 12:04:16 -05:00
vits71 739ff4d637
Merge branch 'intrepidcs:master' into Npcap-fix 2025-01-11 23:15:28 +01:00
Vít Šembera e233233b94 Fixed Npcap related errors in PCAPDLL::PCAPDLL() 2024-07-18 13:26:39 +02:00
14 changed files with 134 additions and 24 deletions

View File

@ -408,6 +408,8 @@ push github:
image: alpine:latest image: alpine:latest
rules: rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: delayed
start_in: 10 minutes
dependencies: dependencies:
- deploy python/pypi - deploy python/pypi
needs: needs:

View File

@ -13,7 +13,7 @@ option(LIBICSNEO_BUILD_ICSNEOC "Build dynamic C library" ON)
option(LIBICSNEO_BUILD_ICSNEOC_STATIC "Build static C library" ON) option(LIBICSNEO_BUILD_ICSNEOC_STATIC "Build static C library" ON)
option(LIBICSNEO_BUILD_ICSNEOLEGACY "Build icsnVC40 compatibility library" ON) option(LIBICSNEO_BUILD_ICSNEOLEGACY "Build icsnVC40 compatibility library" ON)
option(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC "Build static icsnVC40 compatibility library" ON) option(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC "Build static icsnVC40 compatibility library" ON)
set(LIBICSNEO_NPCAP_INCLUDE_DIR "" CACHE STRING "Npcap include directory; set to build with Npcap") set(LIBICSNEO_NPCAP_INCLUDE_DIR "C:/Users/Vit/source/repos/npcap-sdk-1.13/Include" CACHE STRING "Npcap include directory; set to build with Npcap")
# Device Drivers # Device Drivers
# You almost certainly don't want firmio for your build, # You almost certainly don't want firmio for your build,

View File

@ -21,6 +21,7 @@ pybind11_add_module(icsneopy
icsneopy/api/version.cpp icsneopy/api/version.cpp
icsneopy/device/devicetype.cpp icsneopy/device/devicetype.cpp
icsneopy/communication/network.cpp icsneopy/communication/network.cpp
icsneopy/communication/io.cpp
icsneopy/communication/message/message.cpp icsneopy/communication/message/message.cpp
icsneopy/communication/message/canmessage.cpp icsneopy/communication/message/canmessage.cpp
icsneopy/communication/message/canerrormessage.cpp icsneopy/communication/message/canerrormessage.cpp
@ -44,7 +45,7 @@ install(TARGETS icsneopy LIBRARY DESTINATION icsneopy)
find_program(STUBGEN_EXE stubgen) find_program(STUBGEN_EXE stubgen)
if(STUBGEN_EXE) if(STUBGEN_EXE)
add_custom_command(TARGET icsneopy POST_BUILD COMMAND stubgen -m icsneopy -o .) add_custom_command(TARGET icsneopy POST_BUILD COMMAND stubgen -v -p icsneopy -o .)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/icsneopy.pyi py.typed DESTINATION icsneopy) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/icsneopy.pyi py.typed DESTINATION icsneopy)
endif() endif()

View File

@ -0,0 +1,19 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/io.h"
namespace icsneo {
void init_io(pybind11::module_& m) {
pybind11::enum_<IO>(m, "IO")
.value("EthernetActivation", IO::EthernetActivation)
.value("USBHostPower", IO::USBHostPower)
.value("BackupPowerEnabled", IO::BackupPowerEnabled)
.value("BackupPowerGood", IO::BackupPowerGood)
.value("Misc", IO::Misc)
.value("EMisc", IO::EMisc);
}
} // namespace icsneo

View File

@ -19,6 +19,7 @@ void init_device(pybind11::module_& m) {
.def("disable_message_polling", &Device::disableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("disable_message_polling", &Device::disableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("enable_message_polling", &Device::enableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("enable_message_polling", &Device::enableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_current_message_count", &Device::getCurrentMessageCount) .def("get_current_message_count", &Device::getCurrentMessageCount)
.def("get_digital_io", &Device::getDigitalIO, pybind11::arg("type"), pybind11::arg("number"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_gptp_status", &Device::getGPTPStatus, pybind11::arg("timeout") = std::chrono::milliseconds(100), pybind11::call_guard<pybind11::gil_scoped_release>()) .def("get_gptp_status", &Device::getGPTPStatus, pybind11::arg("timeout") = std::chrono::milliseconds(100), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_messages", [](Device& device) { return device.getMessages(); }, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("get_messages", [](Device& device) { return device.getMessages(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_polling_message_limit", &Device::getPollingMessageLimit) .def("get_polling_message_limit", &Device::getPollingMessageLimit)
@ -42,6 +43,7 @@ void init_device(pybind11::module_& m) {
.def("remove_message_callback", &Device::removeMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("remove_message_callback", &Device::removeMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("request_tc10_sleep", &Device::requestTC10Sleep, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("request_tc10_sleep", &Device::requestTC10Sleep, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("request_tc10_wake", &Device::requestTC10Wake, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("request_tc10_wake", &Device::requestTC10Wake, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_digital_io", pybind11::overload_cast<IO, size_t, bool>(&Device::setDigitalIO), pybind11::arg("type"), pybind11::arg("number"), pybind11::arg("value"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_polling_message_limit", &Device::setPollingMessageLimit) .def("set_polling_message_limit", &Device::setPollingMessageLimit)
.def("set_rtc", &Device::setRTC, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("set_rtc", &Device::setRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("start_script", &Device::startScript, pybind11::call_guard<pybind11::gil_scoped_release>()) .def("start_script", &Device::startScript, pybind11::call_guard<pybind11::gil_scoped_release>())

View File

@ -6,8 +6,14 @@
namespace icsneo { namespace icsneo {
// binding namespace workaround to avoid submodules
struct DiskNamespace {
using Access = icsneo::Disk::Access;
using MemoryType = icsneo::Disk::MemoryType;
};
void init_diskdriver(pybind11::module_& m) { void init_diskdriver(pybind11::module_& m) {
auto disk = m.def_submodule("disk"); pybind11::class_<DiskNamespace> disk(m, "Disk");
pybind11::enum_<Disk::Access>(disk, "Access") pybind11::enum_<Disk::Access>(disk, "Access")
.value("None", Disk::Access::None) .value("None", Disk::Access::None)
.value("EntireCard", Disk::Access::EntireCard) .value("EntireCard", Disk::Access::EntireCard)

View File

@ -10,6 +10,7 @@ void init_event(pybind11::module_&);
void init_eventcallback(pybind11::module_&); void init_eventcallback(pybind11::module_&);
void init_eventmanager(pybind11::module_&); void init_eventmanager(pybind11::module_&);
void init_network(pybind11::module_&); void init_network(pybind11::module_&);
void init_io(pybind11::module_&);
void init_devicetype(pybind11::module_&); void init_devicetype(pybind11::module_&);
void init_message(pybind11::module_&); void init_message(pybind11::module_&);
void init_canmessage(pybind11::module_&); void init_canmessage(pybind11::module_&);
@ -39,6 +40,7 @@ PYBIND11_MODULE(icsneopy, m) {
init_version(m); init_version(m);
init_devicetype(m); init_devicetype(m);
init_network(m); init_network(m);
init_io(m);
init_message(m); init_message(m);
init_canmessage(m); init_canmessage(m);
init_canerrormessage(m); init_canerrormessage(m);

View File

@ -88,3 +88,76 @@ Monitor Ethernet Status
time.sleep(1) time.sleep(1)
main() main()
TC10
====
.. code-block:: python
import icsneopy
import time
devices: list[icsneopy.Device] = icsneopy.find_all_devices()
device: icsneopy.Device = devices[0]
print(f"using {device} for TC10")
device.open()
netid = icsneopy.Network.NetID.OP_Ethernet1
if device.supports_tc10():
# initial
status = device.get_tc10_status(netid)
print(f"initial status: wake: {status.wakeStatus}, sleep: {status.sleepStatus}")
time.sleep(1)
# sleep
device.request_tc10_sleep(netid)
print("waiting 1s for sleep to occur")
time.sleep(1)
status = device.get_tc10_status(netid)
print(f"post sleep status: wake: {status.wakeStatus}, sleep: {status.sleepStatus}")
# wake
device.request_tc10_wake(netid)
print("waiting 1s for wake to occur")
time.sleep(1)
status = device.get_tc10_status(netid)
print(f"post wake status: wake: {status.wakeStatus}, sleep: {status.sleepStatus}")
else:
print(f"{device} does not support TC10")
DoIP Ethernet Activation
========================
.. code-block:: python
import icsneopy
import time
devs = icsneopy.find_all_devices()
dev = devs[0]
dev.open()
# the device must be online for digital I/O
dev.go_online()
print(f"initial state: {dev.get_digital_io(icsneopy.IO.EthernetActivation, 1)}")
dev.set_digital_io(icsneopy.IO.EthernetActivation, 1, True)
print(f"after setting to true: {dev.get_digital_io(icsneopy.IO.EthernetActivation, 1)}")
# allow for observing the change
time.sleep(2)
dev.set_digital_io(icsneopy.IO.EthernetActivation, 1, False)
print(f"after setting to false: {dev.get_digital_io(icsneopy.IO.EthernetActivation, 1)}")
# allow for observing the change
time.sleep(2)

View File

@ -848,6 +848,13 @@ protected:
neodevice_t& getWritableNeoDevice() { return data; } neodevice_t& getWritableNeoDevice() { return data; }
enum class LEDState : uint8_t {
Offline = 0x04,
CoreMiniRunning = 0x08, // This should override "offline" if the CoreMini is running
Online = 0x10
};
LEDState ledState;
void updateLEDState();
private: private:
neodevice_t data; neodevice_t data;
std::shared_ptr<ResetStatusMessage> latestResetStatus; std::shared_ptr<ResetStatusMessage> latestResetStatus;
@ -876,14 +883,6 @@ private:
APIEvent::Type getCommunicationNotEstablishedError(); APIEvent::Type getCommunicationNotEstablishedError();
enum class LEDState : uint8_t {
Offline = 0x04,
CoreMiniRunning = 0x08, // This should override "offline" if the CoreMini is running
Online = 0x10
};
LEDState ledState;
void updateLEDState();
size_t pollingMessageLimit = 20000; size_t pollingMessageLimit = 20000;
moodycamel::BlockingConcurrentQueue<std::shared_ptr<Message>> pollingContainer; moodycamel::BlockingConcurrentQueue<std::shared_ptr<Message>> pollingContainer;
void enforcePollingMessageLimit(); void enforcePollingMessageLimit();

View File

@ -48,24 +48,19 @@ public:
return Device::getProductName(); return Device::getProductName();
} }
// RADMoon 2 does not go online, you can only set settings and
// view PHY information (when supported)
bool goOnline() override { bool goOnline() override {
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); if(!com->sendCommand(Command::EnableNetworkCommunication, true))
return false; return false;
}
updateLEDState();
bool goOffline() override { online = true;
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); return true;
return false;
} }
bool getEthPhyRegControlSupported() const override { return true; } bool getEthPhyRegControlSupported() const override { return true; }
virtual uint8_t getPhyAddrOrPort() const = 0; virtual uint8_t getPhyAddrOrPort() const = 0;
bool isOnlineSupported() const override { return false; }
protected: protected:
using Device::Device; using Device::Device;

View File

@ -27,6 +27,10 @@ typedef struct {
uint16_t pc_com_mode; uint16_t pc_com_mode;
TIMESYNC_ICSHARDWARE_SETTINGS timeSyncSettings; TIMESYNC_ICSHARDWARE_SETTINGS timeSyncSettings;
uint16_t hwComLatencyTestEn; uint16_t hwComLatencyTestEn;
RAD_GPTP_SETTINGS gPTP;
uint64_t network_enables_5;
} radmoon2_settings_t; } radmoon2_settings_t;
#pragma pack(pop) #pragma pack(pop)

View File

@ -19,6 +19,7 @@ public:
static std::vector<Network> supportedNetworks = { static std::vector<Network> supportedNetworks = {
Network::NetID::Ethernet, Network::NetID::Ethernet,
Network::NetID::OP_Ethernet1, Network::NetID::OP_Ethernet1,
Network::NetID::MDIO1
}; };
return supportedNetworks; return supportedNetworks;
} }
@ -29,6 +30,8 @@ public:
bool supportsComponentVersions() const override { return true; } bool supportsComponentVersions() const override { return true; }
bool supportsTC10() const override { return true; }
protected: protected:
RADMoon3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { RADMoon3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
initialize<RADMoon3Settings>(makeDriver); initialize<RADMoon3Settings>(makeDriver);

View File

@ -27,6 +27,7 @@ typedef struct {
uint16_t enableLatencyTest : 1; uint16_t enableLatencyTest : 1;
uint16_t reserved : 15; uint16_t reserved : 15;
} flags; // 2 } flags; // 2
uint64_t network_enables_5;
} radmoon3_settings_t; } radmoon3_settings_t;
#pragma pack(pop) #pragma pack(pop)

View File

@ -34,9 +34,12 @@ PCAPDLL::PCAPDLL()
int len = GetSystemDirectory(dllPath, 480); // be safe int len = GetSystemDirectory(dllPath, 480); // be safe
if (len) { if (len) {
_tcscat_s(dllPath, 512, TEXT("\\Npcap")); _tcscat_s(dllPath, 512, TEXT("\\Npcap"));
cookie = AddDllDirectory(dllPath); WCHAR dllPath_w[512] = { 0 };
if (mbstowcs(dllPath_w, dllPath, 512)) {
cookie = AddDllDirectory(dllPath_w);
}
} }
dll = LoadLibraryEx(TEXT("wpcap.dll"), nullptr, LOAD_LIBRARY_SEARCH_USER_DIRS); dll = LoadLibraryEx(TEXT("wpcap.dll"), nullptr, LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
if (cookie) if (cookie)
RemoveDllDirectory(cookie); RemoveDllDirectory(cookie);