File: structures.py

package info (click to toggle)
python-can 4.5.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,372 kB
  • sloc: python: 25,840; makefile: 38; sh: 20
file content (307 lines) | stat: -rw-r--r-- 10,540 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
"""
Ctypes wrapper module for IXXAT Virtual CAN Interface V4 on win32 systems

Copyright (C) 2016 Giuseppe Corbelli <giuseppe.corbelli@weightpack.com>
"""

import ctypes


class LUID(ctypes.Structure):
    _fields_ = [("LowPart", ctypes.c_uint32), ("HighPart", ctypes.c_int32)]


PLUID = ctypes.POINTER(LUID)


class VCIID(ctypes.Union):
    _fields_ = [("AsLuid", LUID), ("AsInt64", ctypes.c_int64)]


PVCIID = ctypes.POINTER(VCIID)


class GUID(ctypes.Structure):
    _fields_ = [
        ("Data1", ctypes.c_uint32),
        ("Data2", ctypes.c_uint16),
        ("Data3", ctypes.c_uint16),
        ("Data4", ctypes.c_char * 8),
    ]


class VCIDEVICEINFO(ctypes.Structure):
    class UniqueHardwareId(ctypes.Union):
        _fields_ = [("AsChar", ctypes.c_char * 16), ("AsGuid", GUID)]

    _fields_ = [
        ("VciObjectId", VCIID),
        ("DeviceClass", GUID),
        ("DriverMajorVersion", ctypes.c_uint8),
        ("DriverMinorVersion", ctypes.c_uint8),
        ("DriverBuildVersion", ctypes.c_uint16),
        ("HardwareBranchVersion", ctypes.c_uint8),
        ("HardwareMajorVersion", ctypes.c_uint8),
        ("HardwareMinorVersion", ctypes.c_uint8),
        ("HardwareBuildVersion", ctypes.c_uint8),
        ("UniqueHardwareId", UniqueHardwareId),
        ("Description", ctypes.c_char * 128),
        ("Manufacturer", ctypes.c_char * 126),
        ("DriverReleaseVersion", ctypes.c_uint16),
    ]

    def __str__(self):
        return (
            f"Mfg: {self.Manufacturer}, "
            f"Dev: {self.Description} "
            f"HW: {self.HardwareBranchVersion}"
            f".{self.HardwareMajorVersion}"
            f".{self.HardwareMinorVersion}"
            f".{self.HardwareBuildVersion} "
            f"Drv: {self.DriverReleaseVersion}"
            f".{self.DriverMajorVersion}"
            f".{self.DriverMinorVersion}"
            f".{self.DriverBuildVersion}"
        )


PVCIDEVICEINFO = ctypes.POINTER(VCIDEVICEINFO)


class CANLINESTATUS(ctypes.Structure):
    _fields_ = [
        # current CAN operating mode. Value is a logical combination of
        # one or more CAN_OPMODE_xxx constants
        ("bOpMode", ctypes.c_uint8),
        ("bBtReg0", ctypes.c_uint8),  # current bus timing register 0 value
        ("bBtReg1", ctypes.c_uint8),  # current bus timing register 1 value
        ("bBusLoad", ctypes.c_uint8),  # average bus load in percent (0..100)
        ("dwStatus", ctypes.c_uint32),  # status of the CAN controller (see CAN_STATUS_)
    ]


PCANLINESTATUS = ctypes.POINTER(CANLINESTATUS)


class CANCHANSTATUS(ctypes.Structure):
    _fields_ = [
        ("sLineStatus", CANLINESTATUS),  # current CAN line status
        ("fActivated", ctypes.c_uint32),  # TRUE if the channel is activated
        ("fRxOverrun", ctypes.c_uint32),  # TRUE if receive FIFO overrun occurred
        ("bRxFifoLoad", ctypes.c_uint8),  # receive FIFO load in percent (0..100)
        ("bTxFifoLoad", ctypes.c_uint8),  # transmit FIFO load in percent (0..100)
    ]


PCANCHANSTATUS = ctypes.POINTER(CANCHANSTATUS)


class CANCAPABILITIES(ctypes.Structure):
    _fields_ = [
        ("wCtrlType", ctypes.c_uint16),
        ("wBusCoupling", ctypes.c_uint16),
        ("dwFeatures", ctypes.c_uint32),
        ("dwClockFreq", ctypes.c_uint32),
        ("dwTscDivisor", ctypes.c_uint32),
        ("dwCmsDivisor", ctypes.c_uint32),
        ("dwCmsMaxTicks", ctypes.c_uint32),
        ("dwDtxDivisor", ctypes.c_uint32),
        ("dwDtxMaxTicks", ctypes.c_uint32),
    ]


PCANCAPABILITIES = ctypes.POINTER(CANCAPABILITIES)


class CANMSGINFO(ctypes.Union):
    class Bytes(ctypes.Structure):
        _fields_ = [
            ("bType", ctypes.c_uint8),  # type (see CAN_MSGTYPE_ constants)
            (
                "bAddFlags",
                ctypes.c_uint8,
            ),  # extended flags (see CAN_MSGFLAGS2_ constants). AKA bFlags2 in VCI v4
            ("bFlags", ctypes.c_uint8),  # flags (see CAN_MSGFLAGS_ constants)
            ("bAccept", ctypes.c_uint8),  # accept code (see CAN_ACCEPT_ constants)
        ]

    class Bits(ctypes.Structure):
        _fields_ = [
            ("type", ctypes.c_uint32, 8),  # type (see CAN_MSGTYPE_ constants)
            ("ssm", ctypes.c_uint32, 1),  # single shot mode
            ("hpm", ctypes.c_uint32, 1),  # high priority message
            ("edl", ctypes.c_uint32, 1),  # extended data length
            ("fdr", ctypes.c_uint32, 1),  # fast data bit rate
            ("esi", ctypes.c_uint32, 1),  # error state indicator
            ("res", ctypes.c_uint32, 3),  # reserved set to 0
            ("dlc", ctypes.c_uint32, 4),  # data length code
            ("ovr", ctypes.c_uint32, 1),  # data overrun
            ("srr", ctypes.c_uint32, 1),  # self reception request
            ("rtr", ctypes.c_uint32, 1),  # remote transmission request
            (
                "ext",
                ctypes.c_uint32,
                1,
            ),  # extended frame format (0=standard, 1=extended)
            ("afc", ctypes.c_uint32, 8),  # accept code (see CAN_ACCEPT_ constants)
        ]

    _fields_ = [("Bytes", Bytes), ("Bits", Bits)]


PCANMSGINFO = ctypes.POINTER(CANMSGINFO)


class CANMSG(ctypes.Structure):
    _fields_ = [
        ("dwTime", ctypes.c_uint32),
        # CAN ID of the message in Intel format (aligned right) without RTR bit.
        ("dwMsgId", ctypes.c_uint32),
        ("uMsgInfo", CANMSGINFO),
        ("abData", ctypes.c_uint8 * 8),
    ]

    def __str__(self) -> str:
        return """ID: 0x{:04x}{} DLC: {:02d} DATA: {}""".format(
            self.dwMsgId,
            "[RTR]" if self.uMsgInfo.Bits.rtr else "",
            self.uMsgInfo.Bits.dlc,
            memoryview(self.abData)[: self.uMsgInfo.Bits.dlc].hex(sep=" "),
        )


PCANMSG = ctypes.POINTER(CANMSG)


class CANCYCLICTXMSG(ctypes.Structure):
    _fields_ = [
        ("wCycleTime", ctypes.c_uint16),
        ("bIncrMode", ctypes.c_uint8),
        ("bByteIndex", ctypes.c_uint8),
        ("dwMsgId", ctypes.c_uint32),
        ("uMsgInfo", CANMSGINFO),
        ("abData", ctypes.c_uint8 * 8),
    ]


PCANCYCLICTXMSG = ctypes.POINTER(CANCYCLICTXMSG)


class CANBTP(ctypes.Structure):
    _fields_ = [
        ("dwMode", ctypes.c_uint32),  # timing mode (see CAN_BTMODE_ const)
        ("dwBPS", ctypes.c_uint32),  # bits per second or prescaler (see CAN_BTMODE_RAW)
        ("wTS1", ctypes.c_uint16),  # length of time segment 1 in quanta
        ("wTS2", ctypes.c_uint16),  # length of time segment 2 in quanta
        ("wSJW", ctypes.c_uint16),  # re-synchronization jump width im quanta
        (
            "wTDO",
            ctypes.c_uint16,
        ),  # transceiver delay offset (SSP offset) in quanta (0 = disabled, 0xFFFF = simplified SSP positioning)
    ]

    def __str__(self):
        return "dwMode=%d, dwBPS=%d, wTS1=%d,  wTS2=%d, wSJW=%d, wTDO=%d" % (
            self.dwMode,
            self.dwBPS,
            self.wTS1,
            self.wTS2,
            self.wSJW,
            self.wTDO,
        )


PCANBTP = ctypes.POINTER(CANBTP)


class CANCAPABILITIES2(ctypes.Structure):
    _fields_ = [
        ("wCtrlType", ctypes.c_uint16),  # Type of CAN controller (see CAN_CTRL_ const)
        ("wBusCoupling", ctypes.c_uint16),  # Type of Bus coupling (see CAN_BUSC_ const)
        (
            "dwFeatures",
            ctypes.c_uint32,
        ),  # supported features (see CAN_FEATURE_ constants)
        ("dwCanClkFreq", ctypes.c_uint32),  # CAN clock frequency [Hz]
        ("sSdrRangeMin", CANBTP),  # minimum bit timing values for standard bit rate
        ("sSdrRangeMax", CANBTP),  # maximum bit timing values for standard bit rate
        ("sFdrRangeMin", CANBTP),  # minimum bit timing values for fast data bit rate
        ("sFdrRangeMax", CANBTP),  # maximum bit timing values for fast data bit rate
        (
            "dwTscClkFreq",
            ctypes.c_uint32,
        ),  # clock frequency of the time stamp counter [Hz]
        ("dwTscDivisor", ctypes.c_uint32),  # divisor for the message time stamp counter
        (
            "dwCmsClkFreq",
            ctypes.c_uint32,
        ),  # clock frequency of cyclic message scheduler [Hz]
        ("dwCmsDivisor", ctypes.c_uint32),  # divisor for the cyclic message scheduler
        (
            "dwCmsMaxTicks",
            ctypes.c_uint32,
        ),  # maximum tick count value of the cyclic message
        (
            "dwDtxClkFreq",
            ctypes.c_uint32,
        ),  # clock frequency of the delayed message transmitter [Hz]
        (
            "dwDtxDivisor",
            ctypes.c_uint32,
        ),  # divisor for the delayed message transmitter
        (
            "dwDtxMaxTicks",
            ctypes.c_uint32,
        ),  # maximum tick count value of the delayed message transmitter
    ]


PCANCAPABILITIES2 = ctypes.POINTER(CANCAPABILITIES2)


class CANLINESTATUS2(ctypes.Structure):
    _fields_ = [
        ("bOpMode", ctypes.c_uint8),  # current CAN operating mode
        ("bExMode", ctypes.c_uint8),  # current CAN extended operating mode
        ("bBusLoad", ctypes.c_uint8),  # average bus load in percent (0..100)
        ("bReserved", ctypes.c_uint8),  # reserved set to 0
        ("sBtpSdr", ctypes.c_uint8),  # standard bit rate timing
        ("sBtpFdr", ctypes.c_uint8),  # fast data bit rate timing
        ("dwStatus", ctypes.c_uint32),  # status of the CAN controller (see CAN_STATUS_)
    ]


PCANLINESTATUS2 = ctypes.POINTER(CANLINESTATUS2)


class CANMSG2(ctypes.Structure):
    _fields_ = [
        ("dwTime", ctypes.c_uint32),  # time stamp for receive message
        ("rsvd", ctypes.c_uint32),  # reserved (set to 0)
        ("dwMsgId", ctypes.c_uint32),  # CAN message identifier (INTEL format)
        ("uMsgInfo", CANMSGINFO),  # message information (bit field)
        ("abData", ctypes.c_uint8 * 64),  # message data
    ]


PCANMSG2 = ctypes.POINTER(CANMSG2)


class CANCYCLICTXMSG2(ctypes.Structure):
    _fields_ = [
        ("wCycleTime", ctypes.c_uint16),  # cycle time for the message in ticks
        (
            "bIncrMode",
            ctypes.c_uint8,
        ),  # auto increment mode (see CAN_CTXMSG_INC_ const)
        (
            "bByteIndex",
            ctypes.c_uint8,
        ),  # index of the byte within abData[] to increment
        ("dwMsgId", ctypes.c_uint32),  # message identifier (INTEL format)
        ("uMsgInfo", CANMSGINFO),  # message information (bit field)
        ("abData", ctypes.c_uint8 * 64),  # message data
    ]


PCANCYCLICTXMSG2 = ctypes.POINTER(CANCYCLICTXMSG2)