use std::fmt;
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcErr {
Ok = 0,
AlreadyInitialized = 1,
NotInitialized = 2,
Timeout = 3,
NoSlaves = 4,
Nok = 5,
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcState {
None = 0x00,
Init = 0x01,
PreOp = 0x02,
Boot = 0x03,
SafeOp = 0x04,
OP = 0x08,
Ack = 0x10,
}
impl EcState {
pub fn from_value(v: u8) -> Self {
match v & 0x0F {
0x00 => Self::None,
0x01 => Self::Init,
0x02 => Self::PreOp,
0x03 => Self::Boot,
0x04 => Self::SafeOp,
0x08 => Self::OP,
_ => Self::None,
}
}
pub fn has_error(raw: u8) -> bool {
(raw & 0x10) != 0
}
pub fn format(raw: u8) -> String {
let base = Self::from_value(raw);
let name = match base {
Self::None => "None",
Self::Init => "Init",
Self::PreOp => "PreOp",
Self::Boot => "Boot",
Self::SafeOp => "SafeOp",
Self::OP => "OP",
Self::Ack => "Ack",
};
if Self::has_error(raw) {
format!("{}+Error", name)
} else {
name.to_string()
}
}
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcLinkState {
Disconnected = 0,
Connected = 1,
PrimaryOnly = 3,
SecondaryOnly = 4,
}
impl EcLinkState {
pub fn from_value(v: u8) -> Self {
match v {
0 => Self::Disconnected,
1 => Self::Connected,
3 => Self::PrimaryOnly,
4 => Self::SecondaryOnly,
_ => Self::Disconnected,
}
}
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RingMode {
Inactive = 0,
Dual = 1,
Degraded = 2,
}
impl RingMode {
pub fn from_value(v: i32) -> Self {
match v {
0 => Self::Inactive,
1 => Self::Dual,
2 => Self::Degraded,
_ => Self::Inactive,
}
}
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcBufState {
Empty = 0x00,
Alloc = 0x01,
Tx = 0x02,
Rcvd = 0x03,
Complete = 0x04,
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcDataType {
Boolean = 0x0001,
Integer8 = 0x0002,
Integer16 = 0x0003,
Integer32 = 0x0004,
Unsigned8 = 0x0005,
Unsigned16 = 0x0006,
Unsigned32 = 0x0007,
Real32 = 0x0008,
VisibleString = 0x0009,
OctetString = 0x000A,
UnicodeString = 0x000B,
TimeOfDay = 0x000C,
TimeDifference = 0x000D,
Domain = 0x000F,
Integer24 = 0x0010,
Real64 = 0x0011,
Integer40 = 0x0012,
Integer48 = 0x0013,
Integer56 = 0x0014,
Integer64 = 0x0015,
Unsigned24 = 0x0016,
Unsigned40 = 0x0018,
Unsigned48 = 0x0019,
Unsigned56 = 0x001A,
Unsigned64 = 0x001B,
Bit1 = 0x0030,
Bit2 = 0x0031,
Bit3 = 0x0032,
Bit4 = 0x0033,
Bit5 = 0x0034,
Bit6 = 0x0035,
Bit7 = 0x0036,
Bit8 = 0x0037,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcCmdType {
Nop = 0x00,
Aprd = 0x01,
Apwr = 0x02,
Aprw = 0x03,
Fprd = 0x04,
Fpwr = 0x05,
Fprw = 0x06,
Brd = 0x07,
Bwr = 0x08,
Brw = 0x09,
Lrd = 0x0A,
Lwr = 0x0B,
Lrw = 0x0C,
Armw = 0x0D,
Frmw = 0x0E,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcEcmdType {
Nop = 0x0000,
Read = 0x0100,
Write = 0x0201,
Reload = 0x0300,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LogLevel {
Info = 0,
Debug = 1,
Warn = 2,
Error = 3,
Fatal = 4,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcALState {
NoError = 0x0000,
UnspecifiedError = 0x0001,
NoMemory = 0x0002,
InvalidDeviceSetup = 0x0003,
InvalidRevision = 0x0004,
SiiEepromMismatch = 0x0006,
FirmwareUpdateFailed = 0x0007,
LicenseError = 0x000E,
InvalidStateChange = 0x0011,
UnknownRequestedState = 0x0012,
BootstrapNotSupported = 0x0013,
NoValidFirmware = 0x0014,
InvalidMailboxConfig = 0x0015,
InvalidMailBoxConfig = 0x0016,
InvalidSyncManagerConfig = 0x0017,
NoValidInputs = 0x0018,
NoValidOutputs = 0x0019,
SyncError = 0x001A,
SyncManagerWatchdog = 0x001B,
InvalidSyncManagerTypes = 0x001C,
InvalidOutputConfig = 0x001D,
InvalidInputConfig = 0x001E,
InvalidWatchdogConfig = 0x001F,
NeedsColdStart = 0x0020,
NeedsInit = 0x0021,
NeedsPreOp = 0x0022,
NeedsSafeOp = 0x0023,
InvalidInputMapping = 0x0024,
InvalidOutputMapping = 0x0025,
InconsistentSettings = 0x0026,
FreerunNotSupported = 0x0027,
SyncNotSupported = 0x0028,
FreerunNeeds3Buffer = 0x0029,
BackgroundWatchdog = 0x002A,
NoValidIO = 0x002B,
FatalSyncError = 0x002C,
NoSyncError = 0x002D,
CycleTimeTooSmall = 0x002E,
InvalidDcSyncConfig = 0x0030,
InvalidDcLatch = 0x0031,
PllError = 0x0032,
DcSyncIOError = 0x0033,
DcSyncTimeout = 0x0034,
InvalidDcSyncCycle = 0x0035,
InvalidSync0Cycle = 0x0036,
InvalidSync1Cycle = 0x0037,
MailboxAoe = 0x0041,
MailboxEoe = 0x0042,
MailboxCoe = 0x0043,
MailboxFoe = 0x0044,
MailboxSoe = 0x0045,
MailboxVoe = 0x004F,
EepromNoAccess = 0x0050,
EepromError = 0x0051,
ExternalHardwareNotReady = 0x0052,
SlaveRestarted = 0x0060,
DeviceIdUpdated = 0x0061,
ModuleIdentListMismatch = 0x0070,
SupplyVoltageTooLow = 0x0080,
SupplyVoltageTooHigh = 0x0081,
TemperatureTooLow = 0x0082,
TemperatureTooHigh = 0x0083,
AppControllerAvailable = 0x00F0,
Unknown = 0xFFFF,
}
impl EcALState {
pub fn from_value(v: i32) -> Self {
match v {
0x0000 => Self::NoError,
0x0001 => Self::UnspecifiedError,
0x0002 => Self::NoMemory,
0x0003 => Self::InvalidDeviceSetup,
0x0004 => Self::InvalidRevision,
0x0006 => Self::SiiEepromMismatch,
0x0007 => Self::FirmwareUpdateFailed,
0x000E => Self::LicenseError,
0x0011 => Self::InvalidStateChange,
0x0012 => Self::UnknownRequestedState,
0x0013 => Self::BootstrapNotSupported,
0x0014 => Self::NoValidFirmware,
0x0015 => Self::InvalidMailboxConfig,
0x0016 => Self::InvalidMailBoxConfig,
0x0017 => Self::InvalidSyncManagerConfig,
0x0018 => Self::NoValidInputs,
0x0019 => Self::NoValidOutputs,
0x001A => Self::SyncError,
0x001B => Self::SyncManagerWatchdog,
0x001C => Self::InvalidSyncManagerTypes,
0x001D => Self::InvalidOutputConfig,
0x001E => Self::InvalidInputConfig,
0x001F => Self::InvalidWatchdogConfig,
0x0020 => Self::NeedsColdStart,
0x0021 => Self::NeedsInit,
0x0022 => Self::NeedsPreOp,
0x0023 => Self::NeedsSafeOp,
0x0024 => Self::InvalidInputMapping,
0x0025 => Self::InvalidOutputMapping,
0x0026 => Self::InconsistentSettings,
0x0027 => Self::FreerunNotSupported,
0x0028 => Self::SyncNotSupported,
0x0029 => Self::FreerunNeeds3Buffer,
0x002A => Self::BackgroundWatchdog,
0x002B => Self::NoValidIO,
0x002C => Self::FatalSyncError,
0x002D => Self::NoSyncError,
0x002E => Self::CycleTimeTooSmall,
0x0030 => Self::InvalidDcSyncConfig,
0x0031 => Self::InvalidDcLatch,
0x0032 => Self::PllError,
0x0033 => Self::DcSyncIOError,
0x0034 => Self::DcSyncTimeout,
0x0035 => Self::InvalidDcSyncCycle,
0x0036 => Self::InvalidSync0Cycle,
0x0037 => Self::InvalidSync1Cycle,
0x0041 => Self::MailboxAoe,
0x0042 => Self::MailboxEoe,
0x0043 => Self::MailboxCoe,
0x0044 => Self::MailboxFoe,
0x0045 => Self::MailboxSoe,
0x004F => Self::MailboxVoe,
0x0050 => Self::EepromNoAccess,
0x0051 => Self::EepromError,
0x0052 => Self::ExternalHardwareNotReady,
0x0060 => Self::SlaveRestarted,
0x0061 => Self::DeviceIdUpdated,
0x0070 => Self::ModuleIdentListMismatch,
0x0080 => Self::SupplyVoltageTooLow,
0x0081 => Self::SupplyVoltageTooHigh,
0x0082 => Self::TemperatureTooLow,
0x0083 => Self::TemperatureTooHigh,
0x00F0 => Self::AppControllerAvailable,
_ => Self::Unknown,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ALErrorCategory {
None,
Transient,
Configuration,
Hardware,
Unknown,
}
pub fn classify_al_error(code: u16) -> ALErrorCategory {
match code {
0x0000 => ALErrorCategory::None,
0x0011 |
0x001B |
0x001D |
0x0032 |
0x0033 |
0x0034
=> ALErrorCategory::Transient,
0x0015 |
0x0016 |
0x0017 |
0x0018 |
0x0019 |
0x001A |
0x001C |
0x001E |
0x001F |
0x0030 |
0x0031
=> ALErrorCategory::Configuration,
0x0042 |
0x0043 |
0x0050 |
0x0051 |
0x0060
=> ALErrorCategory::Hardware,
_ => {
if code >= 0x0040 && code <= 0x005F {
ALErrorCategory::Hardware
} else {
ALErrorCategory::Unknown
}
}
}
}
#[derive(Debug, Clone)]
pub struct DiagnosticMessage {
pub sub_index: u8,
pub diag_code: u32,
pub flags: u16,
pub text_index: u16,
pub raw_data: Vec<u8>,
}
impl fmt::Display for DiagnosticMessage {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Diag[{}]: Code=0x{:08X}, Flags=0x{:04X}",
self.sub_index, self.diag_code, self.flags)
}
}
#[derive(Debug, Clone, Default)]
pub struct SlaveErrorCounters {
pub slave_index: i32,
pub port0_crc_errors: u32,
pub port1_crc_errors: u32,
pub port2_crc_errors: u32,
pub port3_crc_errors: u32,
pub frame_errors: u32,
pub lost_frames: u32,
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MailboxError {
NoError = 0x0000,
SyntaxError = 0x0001,
ProtocolNotSupported = 0x0002,
WrongChannelField = 0x0003,
ServiceNotSupported = 0x0004,
InvalidMailboxHeader = 0x0005,
DataTooShort = 0x0006,
NoMemoryInSlave = 0x0007,
InconsistentDataLength = 0x0008,
UnknownError = 0xFFFF,
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MailboxType {
ErrorMailbox = 0x00,
ADSOverEtherCAT = 0x01,
EthernetOverEtherCAT = 0x02,
CANopenOverEtherCAT = 0x03,
FileOverEtherCAT = 0x04,
ServoOverEtherCAT = 0x05,
VendorOverEtherCAT = 0x0F,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct CoEObjectAccess(pub u16);
impl CoEObjectAccess {
pub const NONE: Self = Self(0x00);
pub const READ_PRE_OP: Self = Self(0x01);
pub const READ_SAFE_OP: Self = Self(0x02);
pub const READ_OP: Self = Self(0x04);
pub const WRITE_PRE_OP: Self = Self(0x08);
pub const WRITE_SAFE_OP: Self = Self(0x10);
pub const WRITE_OP: Self = Self(0x20);
pub const READ_ANY: Self = Self(0x07);
pub const WRITE_ANY: Self = Self(0x38);
pub const READ_WRITE_ALL: Self = Self(0x3F);
pub fn contains(self, other: Self) -> bool {
(self.0 & other.0) == other.0
}
pub fn union(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
#[repr(u32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SDOError {
NoError = 0x00000000,
ToggleBitNotChanged = 0x05030000,
SDOProtocolTimeout = 0x05040000,
InvalidCommandSpecifier = 0x05040001,
OutOfMemory = 0x05040005,
UnsupportedAccess = 0x06010000,
ReadWriteOnlyError = 0x06010001,
WriteReadOnlyError = 0x06010002,
SubindexWriteError = 0x06010003,
CompleteAccessNotSupported = 0x06010004,
ObjectLengthExceeded = 0x06010005,
ObjectMappedToRxPDO = 0x06010006,
ObjectDoesNotExist = 0x06020000,
CannotBeMappedToPDO = 0x06040041,
ExceedsPDOLength = 0x06040042,
ParameterIncompatibility = 0x06040043,
InternalIncompatibility = 0x06040047,
HardwareAccessError = 0x06060000,
DataTypeMismatch = 0x06070010,
DataTypeTooHigh = 0x06070012,
DataTypeTooLow = 0x06070013,
SubindexDoesNotExist = 0x06090011,
ValueRangeExceeded = 0x06090030,
ValueTooHigh = 0x06090031,
ValueTooLow = 0x06090032,
ModuleIdentListMismatch = 0x06090033,
MaxLessThanMin = 0x06090036,
GeneralError = 0x08000000,
DataTransferError = 0x08000020,
LocalControlError = 0x08000021,
DeviceStateError = 0x08000022,
DictionaryError = 0x08000023,
UnknownError = 0xFFFFFFFF,
}
impl SDOError {
pub fn from_u32(val: u32) -> Self {
match val {
0x00000000 => Self::NoError,
0x05030000 => Self::ToggleBitNotChanged,
0x05040000 => Self::SDOProtocolTimeout,
0x05040001 => Self::InvalidCommandSpecifier,
0x05040005 => Self::OutOfMemory,
0x06010000 => Self::UnsupportedAccess,
0x06010001 => Self::ReadWriteOnlyError,
0x06010002 => Self::WriteReadOnlyError,
0x06010003 => Self::SubindexWriteError,
0x06010004 => Self::CompleteAccessNotSupported,
0x06010005 => Self::ObjectLengthExceeded,
0x06010006 => Self::ObjectMappedToRxPDO,
0x06020000 => Self::ObjectDoesNotExist,
0x06040041 => Self::CannotBeMappedToPDO,
0x06040042 => Self::ExceedsPDOLength,
0x06040043 => Self::ParameterIncompatibility,
0x06040047 => Self::InternalIncompatibility,
0x06060000 => Self::HardwareAccessError,
0x06070010 => Self::DataTypeMismatch,
0x06070012 => Self::DataTypeTooHigh,
0x06070013 => Self::DataTypeTooLow,
0x06090011 => Self::SubindexDoesNotExist,
0x06090030 => Self::ValueRangeExceeded,
0x06090031 => Self::ValueTooHigh,
0x06090032 => Self::ValueTooLow,
0x06090033 => Self::ModuleIdentListMismatch,
0x06090036 => Self::MaxLessThanMin,
0x08000000 => Self::GeneralError,
0x08000020 => Self::DataTransferError,
0x08000021 => Self::LocalControlError,
0x08000022 => Self::DeviceStateError,
0x08000023 => Self::DictionaryError,
_ => Self::UnknownError,
}
}
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SoEError {
NoError = 0x0000,
NoIDN = 0x1001,
InvalidAccessToElement1 = 0x1009,
NoName = 0x2001,
NameTransmissionTooShort = 0x2002,
NameTransmissionTooLong = 0x2003,
NameCannotBeChanged = 0x2004,
NameWriteProtected = 0x2005,
AttributeTransmissionTooShort = 0x3002,
AttributeTransmissionTooLong = 0x3003,
AttributeCannotBeChanged = 0x3004,
AttributeWriteProtected = 0x3005,
NoUnits = 0x4001,
UnitTransmissionTooShort = 0x4002,
UnitTransmissionTooLong = 0x4003,
UnitCannotBeChanged = 0x4004,
UnitWriteProtected = 0x4005,
NoMinimumInputValue = 0x5001,
MinimumInputValueTransmissionTooShort = 0x5002,
MinimumInputValueTransmissionTooLong = 0x5003,
MinimumInputValueCannotBeChanged = 0x5004,
MinimumInputValueWriteProtected = 0x5005,
NoMaximumInputValue = 0x6001,
MaximumInputValueTransmissionTooShort = 0x6002,
MaximumInputValueTransmissionTooLong = 0x6003,
MaximumInputValueCannotBeChanged = 0x6004,
MaximumInputValueWriteProtected = 0x6005,
NoOperationData = 0x7001,
OperationDataTransmissionTooShort = 0x7002,
OperationDataTransmissionTooLong = 0x7003,
OperationDataCannotBeChanged = 0x7004,
OperationDataWriteProtectedByState = 0x7005,
OperationDataSmallerThanMinimum = 0x7006,
OperationDataGreaterThanMaximum = 0x7007,
InvalidOperationDataConfiguredIDNNotSupported = 0x7008,
OperationDataWriteProtectedByPassword = 0x7009,
OperationDataCyclicallyWriteProtected = 0x700A,
InvalidIndirectAddressing = 0x700B,
OperationDataWriteProtectedBySettings = 0x700C,
Reserved700D = 0x700D,
ProcedureCommandAlreadyActive = 0x7010,
ProcedureCommandNotInterruptible = 0x7011,
ProcedureCommandNotExecutableState = 0x7012,
ProcedureCommandNotExecutableInvalidParameters = 0x7013,
NoDataState = 0x7014,
NoDefaultValue = 0x8001,
DefaultValueTransmissionTooLong = 0x8002,
DefaultValueTransmissionTooShort = 0x8003,
DefaultValueCannotBeChanged = 0x8004,
DefaultValueWriteProtected = 0x8005,
InvalidDriveNumber = 0x800A,
GeneralError = 0x800B,
NoElementAddressed = 0x800C,
Unknown = 0xFFFF,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcCommType {
MailboxTx = 0,
MailboxRx = 1,
SdoRead = 2,
SdoWrite = 3,
Pdo = 4,
Register = 5,
Eeprom = 6,
Dc = 7,
Count = 8,
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcPortType {
NotUsed = 0,
MII = 1,
EBUS = 2,
EBUSEnhanced = 3,
}
impl fmt::Display for EcPortType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let desc = match self {
Self::NotUsed => "未使用",
Self::MII => "MII",
Self::EBUS => "EBUS",
Self::EBUSEnhanced => "EBUS+",
};
write!(f, "{}", desc)
}
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcTopologyType {
NoLink = 0,
EndPoint = 1,
Line = 2,
Fork = 3,
Cross = 4,
}
impl fmt::Display for EcTopologyType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let desc = match self {
Self::NoLink => "无链接 (No Link)",
Self::EndPoint => "端点 (End Point)",
Self::Line => "中间节点 (Line)",
Self::Fork => "分支点 (Fork)",
Self::Cross => "交叉点 (Cross)",
};
write!(f, "{}", desc)
}
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcPdiType {
None = 0x00,
DigitalInput4 = 0x01,
DigitalOutput4 = 0x02,
DigitalIO2x2 = 0x03,
DigitalIO = 0x04,
SPISlave = 0x05,
OverloadOutput = 0x06,
EscSyncManager = 0x07,
UCAsync16 = 0x08,
UCAsync8 = 0x09,
UCSync16 = 0x0A,
UCSync8 = 0x0B,
DigitalIO32 = 0x10,
DigitalIO24x8 = 0x11,
DigitalIO16x16 = 0x12,
DigitalIO8x24 = 0x13,
OnChipBus = 0x80,
Unknown = 0xFF,
}
impl fmt::Display for EcPdiType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let desc = match self {
Self::None => "无PDI (Interface deactivated)",
Self::DigitalInput4 => "4个数字输入",
Self::DigitalOutput4 => "4个数字输出",
Self::DigitalIO2x2 => "2个数字输入 + 2个数字输出",
Self::DigitalIO => "数字I/O",
Self::SPISlave => "SPI从站",
Self::OverloadOutput => "过载保护输出",
Self::EscSyncManager => "ESC同步管理器",
Self::UCAsync16 => "uC async. 16bit",
Self::UCAsync8 => "uC async. 8bit",
Self::UCSync16 => "uC sync. 16bit",
Self::UCSync8 => "uC sync. 8bit",
Self::DigitalIO32 => "32个数字输入/输出",
Self::DigitalIO24x8 => "24个数字输入 + 8个数字输出",
Self::DigitalIO16x16 => "16个数字输入 + 16个数字输出",
Self::DigitalIO8x24 => "8个数字输入 + 24个数字输出",
Self::OnChipBus => "On-chip bus",
Self::Unknown => "未知类型",
};
write!(f, "{}", desc)
}
}
#[repr(u16)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcDeviceType {
Undefined = 0,
Static = 1,
InputNoMailbox = 2,
OutputNoMailbox = 3,
InputWithMailbox = 4,
OutputWithMailbox = 5,
IONoMailbox = 6,
IOWithMailbox = 7,
}
impl fmt::Display for EcDeviceType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let desc = match self {
Self::Undefined => "未定义",
Self::Static => "静态设备(无IO映射)",
Self::InputNoMailbox => "输入设备(无邮箱)",
Self::OutputNoMailbox => "输出设备(无邮箱)",
Self::InputWithMailbox => "输入设备(有邮箱)",
Self::OutputWithMailbox => "输出设备(有邮箱)",
Self::IONoMailbox => "输入输出设备(无邮箱)",
Self::IOWithMailbox => "输入输出设备(有邮箱)",
};
write!(f, "{}", desc)
}
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcSyncManagerType {
NotUsed = 0,
MailboxOut = 1,
MailboxIn = 2,
ProcessDataOut = 3,
ProcessDataIn = 4,
}
impl fmt::Display for EcSyncManagerType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let desc = match self {
Self::NotUsed => "未使用",
Self::MailboxOut => "邮箱输出",
Self::MailboxIn => "邮箱输入",
Self::ProcessDataOut => "过程数据输出",
Self::ProcessDataIn => "过程数据输入",
};
write!(f, "{}", desc)
}
}
#[repr(u8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcFmmuType {
NotUsed = 0,
Output = 1,
Input = 2,
SyncManagerStatus = 3,
}
impl fmt::Display for EcFmmuType {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let desc = match self {
Self::NotUsed => "未使用",
Self::Output => "输出",
Self::Input => "输入",
Self::SyncManagerStatus => "同步管理器状态",
};
write!(f, "{}", desc)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EcCoEDetails(pub u8);
impl EcCoEDetails {
pub const NONE: Self = Self(0x00);
pub const SDO: Self = Self(0x01);
pub const SDO_INFO: Self = Self(0x02);
pub const PDO_ASSIGN: Self = Self(0x04);
pub const PDO_CONFIG: Self = Self(0x08);
pub const STARTUP: Self = Self(0x10);
pub const COMPLETE_ACCESS: Self = Self(0x20);
pub fn contains(self, other: Self) -> bool {
(self.0 & other.0) == other.0
}
pub fn union(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct EcEoEDetails(pub u8);
impl EcEoEDetails {
pub const NONE: Self = Self(0x00);
pub const SEND_FRAME: Self = Self(0x01);
pub const RECEIVE_FRAME: Self = Self(0x02);
pub const SET_IP_PARAM: Self = Self(0x04);
pub const GET_IP_PARAM: Self = Self(0x08);
pub fn contains(self, other: Self) -> bool {
(self.0 & other.0) == other.0
}
pub fn union(self, other: Self) -> Self {
Self(self.0 | other.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EcStateFormat {
Short,
Long,
WithHex,
}
pub fn format_ec_state(state: u8, format: EcStateFormat) -> String {
let (short, long) = match state & 0x0F {
0x01 => ("INIT", "Init"),
0x02 => ("PREOP", "Pre-Operational"),
0x03 => ("BOOT", "Bootstrap"),
0x04 => ("SAFEOP", "Safe-Operational"),
0x08 => ("OP", "Operational"),
_ => ("???", "Unknown"),
};
let err = if state & 0x10 != 0 { "+ERR" } else { "" };
match format {
EcStateFormat::Short => format!("{}{}", short, err),
EcStateFormat::Long => format!("{}{}", long, err),
EcStateFormat::WithHex => format!("{}{} (0x{:02X})", short, err, state),
}
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DcSyncMode {
FreeRun = 0,
SmSynchron = 1,
DcSynchron = 2,
DcSynchron01 = 3,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StartupTransition {
IP = 0,
PS = 1,
SO = 2,
OS = 3,
SP = 4,
PI = 5,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StartupWriteTiming {
BeforeTransition = 0,
AfterTransition = 1,
}
pub mod esm_timeouts {
pub const INIT_TO_PRE_OP: i32 = 2000;
pub const PRE_OP_TO_SAFE_OP: i32 = 3000;
pub const SAFE_OP_TO_OP: i32 = 8000;
pub const OP_TO_SAFE_OP: i32 = 200;
pub const SAFE_OP_TO_PRE_OP: i32 = 200;
pub const PRE_OP_TO_INIT: i32 = 200;
pub const TO_BOOT: i32 = 3000;
pub const BOOT_TO_INIT: i32 = 3000;
pub const SDO_TIMEOUT: i32 = 3000;
pub const MAILBOX_TIMEOUT: i32 = 5000;
pub const STATE_STABILIZE_DELAY: i32 = 100;
pub fn get_transition_timeout(current: u8, target: u8) -> i32 {
match (current, target) {
(0x01, 0x02) => INIT_TO_PRE_OP,
(0x02, 0x04) => PRE_OP_TO_SAFE_OP,
(0x04, 0x08) => SAFE_OP_TO_OP,
(0x08, 0x04) => OP_TO_SAFE_OP,
(0x04, 0x02) => SAFE_OP_TO_PRE_OP,
(0x02, 0x01) => PRE_OP_TO_INIT,
(_, 0x03) => TO_BOOT,
(0x03, 0x01) => BOOT_TO_INIT,
_ => 3000,
}
}
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StateCiA402 {
NotReadyToSwitchOn = 0,
SwitchOnDisabled = 1,
ReadyToSwitchOn = 2,
SwitchedOn = 3,
OperationEnabled = 4,
QuickStopActive = 5,
FaultReactionActive = 6,
Fault = 7,
Unknown = 99,
}
#[repr(i8)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ModeCiA402 {
PP = 1,
VL = 2,
PV = 3,
PT = 4,
HM = 6,
IP = 7,
CSP = 8,
CSV = 9,
CST = 10,
CSTCA = 11,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LogCategory {
Error = 0,
Warning = 1,
Message = 2,
Mailbox = 3,
PDO = 4,
Debug = 5,
Local = 6,
}
#[repr(i32)]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum LicenseStatus {
NotVerified = 0,
Verifying = 1,
Verified = 2,
Failed = 3,
Expired = 4,
MachineIdMismatch = 5,
}