Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions can/interfaces/systec/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1 @@
"""
"""

from can.interfaces.systec.ucanbus import UcanBus
157 changes: 86 additions & 71 deletions can/interfaces/systec/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,92 +1,107 @@
from typing import Dict

from abc import ABC, abstractmethod

from .constants import ReturnCode
from can import CanError


class UcanException(CanError):
""" Base class for USB can errors. """
class UcanException(CanError, ABC):
"""Base class for USB can errors."""

def __init__(self, result, func, arguments):
self.result = result.value
self.result = result
self.func = func
self.arguments = arguments
self.return_msgs = {}
super().__init__()

def __str__(self):
message = self.return_msgs.get(self.result, "unknown")
return f"Function {self.func.__name__} returned {self.result}: {message}"
message = self._error_message_mapping.get(result, "unknown")
super().__init__(
message=f"Function {func.__name__} (called with {arguments}): {message}",
error_code=result.value,
)

@property
@abstractmethod
def _error_message_mapping(self) -> Dict[ReturnCode, str]:
...


class UcanError(UcanException):
""" Exception class for errors from USB-CAN-library. """
"""Exception class for errors from USB-CAN-library."""

def __init__(self, result, func, arguments):
super().__init__(result, func, arguments)
self.return_msgs = {
ReturnCode.ERR_RESOURCE: "could not created a resource (memory, handle, ...)",
ReturnCode.ERR_MAXMODULES: "the maximum number of opened modules is reached",
ReturnCode.ERR_HWINUSE: "the specified module is already in use",
ReturnCode.ERR_ILLVERSION: "the software versions of the module and library are incompatible",
ReturnCode.ERR_ILLHW: "the module with the specified device number is not connected "
"(or used by an other application)",
ReturnCode.ERR_ILLHANDLE: "wrong USB-CAN-Handle handed over to the function",
ReturnCode.ERR_ILLPARAM: "wrong parameter handed over to the function",
ReturnCode.ERR_BUSY: "instruction can not be processed at this time",
ReturnCode.ERR_TIMEOUT: "no answer from module",
ReturnCode.ERR_IOFAILED: "a request to the driver failed",
ReturnCode.ERR_DLL_TXFULL: "a CAN message did not fit into the transmit buffer",
ReturnCode.ERR_MAXINSTANCES: "maximum number of applications is reached",
ReturnCode.ERR_CANNOTINIT: "CAN interface is not yet initialized",
ReturnCode.ERR_DISCONECT: "USB-CANmodul was disconnected",
ReturnCode.ERR_NOHWCLASS: "the needed device class does not exist",
ReturnCode.ERR_ILLCHANNEL: "illegal CAN channel",
ReturnCode.ERR_RESERVED1: "reserved",
ReturnCode.ERR_ILLHWTYPE: "the API function can not be used with this hardware",
}
_ERROR_MESSAGES = {
ReturnCode.ERR_RESOURCE: "could not created a resource (memory, handle, ...)",
ReturnCode.ERR_MAXMODULES: "the maximum number of opened modules is reached",
ReturnCode.ERR_HWINUSE: "the specified module is already in use",
ReturnCode.ERR_ILLVERSION: "the software versions of the module and library are incompatible",
ReturnCode.ERR_ILLHW: "the module with the specified device number is not connected "
"(or used by an other application)",
ReturnCode.ERR_ILLHANDLE: "wrong USB-CAN-Handle handed over to the function",
ReturnCode.ERR_ILLPARAM: "wrong parameter handed over to the function",
ReturnCode.ERR_BUSY: "instruction can not be processed at this time",
ReturnCode.ERR_TIMEOUT: "no answer from module",
ReturnCode.ERR_IOFAILED: "a request to the driver failed",
ReturnCode.ERR_DLL_TXFULL: "a CAN message did not fit into the transmit buffer",
ReturnCode.ERR_MAXINSTANCES: "maximum number of applications is reached",
ReturnCode.ERR_CANNOTINIT: "CAN interface is not yet initialized",
ReturnCode.ERR_DISCONECT: "USB-CANmodul was disconnected",
ReturnCode.ERR_NOHWCLASS: "the needed device class does not exist",
ReturnCode.ERR_ILLCHANNEL: "illegal CAN channel",
ReturnCode.ERR_RESERVED1: "reserved",
ReturnCode.ERR_ILLHWTYPE: "the API function can not be used with this hardware",
}

@property
def _error_message_mapping(self) -> Dict[ReturnCode, str]:
return UcanError._ERROR_MESSAGES


class UcanCmdError(UcanException):
""" Exception class for errors from firmware in USB-CANmodul."""
"""Exception class for errors from firmware in USB-CANmodul."""

def __init__(self, result, func, arguments):
super().__init__(result, func, arguments)
self.return_msgs = {
ReturnCode.ERRCMD_NOTEQU: "the received response does not match to the transmitted command",
ReturnCode.ERRCMD_REGTST: "no access to the CAN controller",
ReturnCode.ERRCMD_ILLCMD: "the module could not interpret the command",
ReturnCode.ERRCMD_EEPROM: "error while reading the EEPROM",
ReturnCode.ERRCMD_RESERVED1: "reserved",
ReturnCode.ERRCMD_RESERVED2: "reserved",
ReturnCode.ERRCMD_RESERVED3: "reserved",
ReturnCode.ERRCMD_ILLBDR: "illegal baud rate value specified in BTR0/BTR1 for systec "
"USB-CANmoduls",
ReturnCode.ERRCMD_NOTINIT: "CAN channel is not initialized",
ReturnCode.ERRCMD_ALREADYINIT: "CAN channel is already initialized",
ReturnCode.ERRCMD_ILLSUBCMD: "illegal sub-command specified",
ReturnCode.ERRCMD_ILLIDX: "illegal index specified (e.g. index for cyclic CAN messages)",
ReturnCode.ERRCMD_RUNNING: "cyclic CAN message(s) can not be defined because transmission of "
"cyclic CAN messages is already running",
}
_ERROR_MESSAGES = {
ReturnCode.ERRCMD_NOTEQU: "the received response does not match to the transmitted command",
ReturnCode.ERRCMD_REGTST: "no access to the CAN controller",
ReturnCode.ERRCMD_ILLCMD: "the module could not interpret the command",
ReturnCode.ERRCMD_EEPROM: "error while reading the EEPROM",
ReturnCode.ERRCMD_RESERVED1: "reserved",
ReturnCode.ERRCMD_RESERVED2: "reserved",
ReturnCode.ERRCMD_RESERVED3: "reserved",
ReturnCode.ERRCMD_ILLBDR: "illegal baud rate value specified in BTR0/BTR1 for systec "
"USB-CANmoduls",
ReturnCode.ERRCMD_NOTINIT: "CAN channel is not initialized",
ReturnCode.ERRCMD_ALREADYINIT: "CAN channel is already initialized",
ReturnCode.ERRCMD_ILLSUBCMD: "illegal sub-command specified",
ReturnCode.ERRCMD_ILLIDX: "illegal index specified (e.g. index for cyclic CAN messages)",
ReturnCode.ERRCMD_RUNNING: "cyclic CAN message(s) can not be defined because transmission of "
"cyclic CAN messages is already running",
}

@property
def _error_message_mapping(self) -> Dict[ReturnCode, str]:
return UcanCmdError._ERROR_MESSAGES


class UcanWarning(UcanException):
""" Exception class for warnings, the function has been executed anyway. """
"""Exception class for warnings, the function has been executed anyway."""

def __init__(self, result, func, arguments):
super().__init__(result, func, arguments)
self.return_msgs = {
ReturnCode.WARN_NODATA: "no CAN messages received",
ReturnCode.WARN_SYS_RXOVERRUN: "overrun in receive buffer of the kernel driver",
ReturnCode.WARN_DLL_RXOVERRUN: "overrun in receive buffer of the USB-CAN-library",
ReturnCode.WARN_RESERVED1: "reserved",
ReturnCode.WARN_RESERVED2: "reserved",
ReturnCode.WARN_FW_TXOVERRUN: "overrun in transmit buffer of the firmware (but this CAN message "
"was successfully stored in buffer of the ibrary)",
ReturnCode.WARN_FW_RXOVERRUN: "overrun in receive buffer of the firmware (but this CAN message "
"was successfully read)",
ReturnCode.WARN_FW_TXMSGLOST: "reserved",
ReturnCode.WARN_NULL_PTR: "pointer is NULL",
ReturnCode.WARN_TXLIMIT: "not all CAN messages could be stored to the transmit buffer in "
"USB-CAN-library",
ReturnCode.WARN_BUSY: "reserved",
}
_ERROR_MESSAGES = {
ReturnCode.WARN_NODATA: "no CAN messages received",
ReturnCode.WARN_SYS_RXOVERRUN: "overrun in receive buffer of the kernel driver",
ReturnCode.WARN_DLL_RXOVERRUN: "overrun in receive buffer of the USB-CAN-library",
ReturnCode.WARN_RESERVED1: "reserved",
ReturnCode.WARN_RESERVED2: "reserved",
ReturnCode.WARN_FW_TXOVERRUN: "overrun in transmit buffer of the firmware (but this CAN message "
"was successfully stored in buffer of the ibrary)",
ReturnCode.WARN_FW_RXOVERRUN: "overrun in receive buffer of the firmware (but this CAN message "
"was successfully read)",
ReturnCode.WARN_FW_TXMSGLOST: "reserved",
ReturnCode.WARN_NULL_PTR: "pointer is NULL",
ReturnCode.WARN_TXLIMIT: "not all CAN messages could be stored to the transmit buffer in "
"USB-CAN-library",
ReturnCode.WARN_BUSY: "reserved",
}

@property
def _error_message_mapping(self) -> Dict[ReturnCode, str]:
return UcanWarning._ERROR_MESSAGES
10 changes: 10 additions & 0 deletions can/interfaces/systec/ucan.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
from ctypes import byref
from ctypes import c_wchar_p as LPWSTR

from ...exceptions import CanInterfaceNotImplementedError

from .constants import *
from .structures import *
from .exceptions import *
Expand Down Expand Up @@ -110,6 +112,7 @@ def check_result(result, func, arguments):
return result


_UCAN_INITIALIZED = False
if os.name != "nt":
log.warning("SYSTEC ucan library does not work on %s platform.", sys.platform)
else:
Expand Down Expand Up @@ -310,6 +313,8 @@ def check_result(result, func, arguments):
UcanEnableCyclicCanMsg.argtypes = [Handle, BYTE, DWORD]
UcanEnableCyclicCanMsg.errcheck = check_result

_UCAN_INITIALIZED = True

except Exception as ex:
log.warning("Cannot load SYSTEC ucan library: %s.", ex)

Expand All @@ -323,6 +328,11 @@ class UcanServer:
_connect_control_ref = None

def __init__(self):
if not _UCAN_INITIALIZED:
raise CanInterfaceNotImplementedError(
"The interface could not be loaded on the current platform"
)

self._handle = Handle(INVALID_HANDLE)
self._is_initialized = False
self._hw_is_initialized = False
Expand Down
Loading