Lely core libraries 2.3.4
vci.c
Go to the documentation of this file.
1
24// Rename error flags to avoid conflicts with definitions in <cantype.h>.
25#define CAN_ERROR_BIT _CAN_ERROR_BIT
26#define CAN_ERROR_STUFF _CAN_ERROR_STUFF
27#define CAN_ERROR_CRC _CAN_ERROR_CRC
28#define CAN_ERROR_FORM _CAN_ERROR_FORM
29#define CAN_ERROR_ACK _CAN_ERROR_ACK
30#define CAN_ERROR_OTHER _CAN_ERROR_OTHER
31
32#include "can.h"
33
34#undef CAN_ERROR_OTHER
35#undef CAN_ERROR_ACK
36#undef CAN_ERROR_FORM
37#undef CAN_ERROR_CRC
38#undef CAN_ERROR_STUFF
39#undef CAN_ERROR_BIT
40
41#if !LELY_NO_STDIO && LELY_HAVE_VCI
42
43#include <lely/can/vci.h>
44#include <lely/util/endian.h>
45#include <lely/util/errnum.h>
46
47#include <assert.h>
48#include <string.h>
49
50#ifdef HAVE_CANTYPE_H
51#include <cantype.h>
52#endif
53
54int
55CANMSG_is_error(const void *msg, enum can_state *pstate, enum can_error *perror)
56{
57 const CANMSG *msg_ = msg;
58 assert(msg);
59
60 if (msg_->uMsgInfo.Bits.type != CAN_MSGTYPE_ERROR)
61 return 0;
62
63 enum can_state state = pstate ? *pstate : 0;
64 enum can_error error = perror ? *perror : 0;
65
66 switch (msg_->abData[0]) {
67 case CAN_ERROR_STUFF: error |= _CAN_ERROR_STUFF; break;
68 case CAN_ERROR_FORM: error |= _CAN_ERROR_FORM; break;
69 case CAN_ERROR_ACK: error |= _CAN_ERROR_ACK; break;
70 case CAN_ERROR_BIT: error |= _CAN_ERROR_BIT; break;
71 case CAN_ERROR_CRC: error |= _CAN_ERROR_CRC; break;
72 case CAN_ERROR_OTHER: error |= _CAN_ERROR_OTHER; break;
73 }
74
75 if (msg_->abData[1] & CAN_STATUS_BUSOFF) {
76 state = CAN_STATE_BUSOFF;
77 } else if (msg_->abData[1] & CAN_STATUS_ERRLIM) {
78 state = CAN_STATE_PASSIVE;
79 } else {
80 state = CAN_STATE_ACTIVE;
81 }
82
83 if (pstate)
84 *pstate = state;
85
86 if (perror)
87 *perror = error;
88
89 return 1;
90}
91
92int
93CANMSG2can_msg(const void *src, struct can_msg *dst)
94{
95 const CANMSG *msg = src;
96 assert(msg);
97 assert(dst);
98
99 if (msg->uMsgInfo.Bits.type != CAN_MSGTYPE_DATA) {
101 return -1;
102 }
103
104 memset(dst, 0, sizeof(*dst));
105 dst->flags = 0;
106 if (msg->uMsgInfo.Bits.ext) {
107 dst->id = letoh32(msg->dwMsgId) & CAN_MASK_EID;
108 dst->flags |= CAN_FLAG_IDE;
109 } else {
110 dst->id = letoh32(msg->dwMsgId) & CAN_MASK_BID;
111 }
112 if (msg->uMsgInfo.Bits.rtr)
113 dst->flags |= CAN_FLAG_RTR;
114 dst->len = MIN(msg->uMsgInfo.Bits.dlc, CAN_MAX_LEN);
115 if (!(dst->flags & CAN_FLAG_RTR))
116 memcpy(dst->data, msg->abData, dst->len);
117
118 return 0;
119}
120
121int
122can_msg2CANMSG(const struct can_msg *src, void *dst)
123{
124 assert(src);
125 CANMSG *msg = dst;
126 assert(msg);
127
128#if !LELY_NO_CANFD
129 if (src->flags & CAN_FLAG_EDL) {
131 return -1;
132 }
133#endif
134
135 memset(msg, 0, sizeof(*msg));
136 msg->dwTime = 0;
137 msg->uMsgInfo.Bits.type = CAN_MSGTYPE_DATA;
138 if (src->flags & CAN_FLAG_IDE) {
139 msg->dwMsgId = htole32(src->id & CAN_MASK_EID);
140 msg->uMsgInfo.Bits.ext = 1;
141 } else {
142 msg->dwMsgId = htole32(src->id & CAN_MASK_BID);
143 }
144 msg->uMsgInfo.Bits.dlc = MIN(src->len, CAN_MAX_LEN);
145 if (src->flags & CAN_FLAG_RTR)
146 msg->uMsgInfo.Bits.rtr = 1;
147 else
148 memcpy(msg->abData, src->data, msg->uMsgInfo.Bits.dlc);
149
150 return 0;
151}
152
153#endif // !LELY_NO_STDIO && LELY_HAVE_VCI
can_error
The error flags of a CAN bus, which are not mutually exclusive.
Definition: err.h:42
@ CAN_ERROR_FORM
A form error.
Definition: err.h:50
@ CAN_ERROR_BIT
A single bit error.
Definition: err.h:44
@ CAN_ERROR_STUFF
A bit stuffing error.
Definition: err.h:46
@ CAN_ERROR_ACK
An acknowledgment error.
Definition: err.h:52
@ CAN_ERROR_CRC
A CRC sequence error.
Definition: err.h:48
@ CAN_ERROR_OTHER
One or more other errors.
Definition: err.h:54
can_state
The states of a CAN node, depending on the TX/RX error count.
Definition: err.h:28
@ CAN_STATE_BUSOFF
The bus off state (TX/RX error count >= 256).
Definition: err.h:34
@ CAN_STATE_PASSIVE
The error passive state (TX/RX error count < 256).
Definition: err.h:32
@ CAN_STATE_ACTIVE
The error active state (TX/RX error count < 128).
Definition: err.h:30
@ CAN_FLAG_IDE
The Identifier Extension (IDE) flag.
Definition: msg.h:43
@ CAN_FLAG_RTR
The Remote Transmission Request (RTR) flag (unavailable in CAN FD format frames).
Definition: msg.h:48
#define CAN_MASK_EID
The mask used to extract the 29-bit Extended Identifier from a CAN frame.
Definition: msg.h:34
#define CAN_MAX_LEN
The maximum number of bytes in the payload of a CAN format frame.
Definition: msg.h:72
#define CAN_MASK_BID
The mask used to extract the 11-bit Base Identifier from a CAN frame.
Definition: msg.h:31
This header file is part of the utilities library; it contains the byte order (endianness) function d...
uint_least32_t htole32(uint_least32_t x)
Converts a 32-bit unsigned integer from host to little-endian byte order.
Definition: endian.h:393
This header file is part of the utilities library; it contains the native and platform-independent er...
@ ERRNUM_INVAL
Invalid argument.
Definition: errnum.h:132
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:424
#define MIN(a, b)
Returns the minimum of a and b.
Definition: util.h:57
This is the internal header file of the CAN bus operation queue functions.
This header file is part of the C11 and POSIX compatibility library; it includes <string....
A CAN or CAN FD format frame.
Definition: msg.h:87
uint_least8_t data[CAN_MSG_MAX_LEN]
The frame payload (in case of a data frame).
Definition: msg.h:102
uint_least32_t id
The identifier (11 or 29 bits, depending on the CAN_FLAG_IDE flag).
Definition: msg.h:89
uint_least8_t flags
The flags (any combination of CAN_FLAG_IDE, CAN_FLAG_RTR, CAN_FLAG_FDF, CAN_FLAG_BRS and CAN_FLAG_ESI...
Definition: msg.h:94
uint_least8_t len
The number of bytes in data (or the requested number of bytes in case of a remote frame).
Definition: msg.h:100
This header file is part of the CAN library; it contains the IXXAT VCI V4 interface declarations.
int CANMSG2can_msg(const void *src, struct can_msg *dst)
Converts an IXXAT VCI CAN message to a can_msg frame.
int CANMSG_is_error(const void *msg, enum can_state *pstate, enum can_error *perror)
Checks if an IXXAT VCI CAN message is an error message and parses the bus state and error flags if it...
int can_msg2CANMSG(const struct can_msg *src, void *dst)
Converts a can_msg frame to an IXXAT VCI CAN message.