Lely core libraries  1.9.2
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 #ifdef 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 
54 int
55 CANMSG_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 
92 int
93 CANMSG2can_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 = ldle_u32(&msg->dwMsgId) & CAN_MASK_EID;
108  dst->flags |= CAN_FLAG_IDE;
109  } else {
110  dst->id = ldle_u32(&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 
121 int
122 can_msg2CANMSG(const struct can_msg *src, void *dst)
123 {
124  assert(src);
125  CANMSG *msg = dst;
126  assert(msg);
127 
128 #ifndef 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  stle_u32(&msg->dwMsgId, src->id & CAN_MASK_EID);
140  msg->uMsgInfo.Bits.ext = 1;
141  } else {
142  stle_u32(&msg->dwMsgId, 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_HAVE_VCI
A CAN or CAN FD format frame.
Definition: msg.h:88
void stle_u32(void *ptr, uint_least32_t x)
Stores a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:534
uint_least32_t id
The identifier (11 or 29 bits, depending on the CAN_FLAG_IDE flag).
Definition: msg.h:90
#define CAN_MASK_EID
The mask used to extract the 29-bit Extended Identifier from a CAN frame.
Definition: msg.h:34
A bit stuffing error.
Definition: can.h:41
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:101
This header file is part of the C11 and POSIX compatibility library; it includes <string.h> and defines any missing functionality.
A form error.
Definition: can.h:45
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:375
can_state
The states of a CAN node, depending on the TX/RX error count.
Definition: can.h:27
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...
The error passive state (TX/RX error count < 256).
Definition: can.h:31
#define MIN(a, b)
Returns the minimum of a and b.
Definition: util.h:57
#define CAN_MASK_BID
The mask used to extract the 11-bit Base Identifier from a CAN frame.
Definition: msg.h:31
uint_least8_t data[CAN_MSG_MAX_LEN]
The frame payload (in case of a data frame).
Definition: msg.h:103
This is the internal header file of the CAN library.
This header file is part of the utilities library; it contains the native and platform-independent er...
#define CAN_FLAG_IDE
The Identifier Extension (IDE) flag.
Definition: msg.h:41
#define CAN_FLAG_EDL
The Extended Data Length (EDL) flag.
Definition: msg.h:55
This header file is part of the utilities library; it contains the byte order (endianness) function d...
The bus off state (TX/RX error count >= 256).
Definition: can.h:33
The error active state (TX/RX error count < 128).
Definition: can.h:29
int can_msg2CANMSG(const struct can_msg *src, void *dst)
Converts a can_msg frame to an IXXAT VCI CAN message.
Invalid argument.
Definition: errnum.h:129
uint_least8_t flags
The flags (any combination of CAN_FLAG_IDE, CAN_FLAG_RTR, CAN_FLAG_EDL, CAN_FLAG_BRS and CAN_FLAG_ESI...
Definition: msg.h:95
An acknowledgment error.
Definition: can.h:47
int CANMSG2can_msg(const void *src, struct can_msg *dst)
Converts an IXXAT VCI CAN message to a can_msg frame.
#define CAN_FLAG_RTR
The Remote Transmission Request (RTR) flag (unavailable in CAN FD format frames). ...
Definition: msg.h:47
This header file is part of the CAN library; it contains the IXXAT VCI V4 interface declarations...
One or more other errors.
Definition: can.h:49
A CRC sequence error.
Definition: can.h:43
#define CAN_MAX_LEN
The maximum number of bytes in the payload of a CAN format frame.
Definition: msg.h:73
A single bit error.
Definition: can.h:39
can_error
The error flags of a CAN bus, which are not mutually exclusive.
Definition: can.h:37
uint_least32_t ldle_u32(const void *ptr)
Loads a 32-bit unsigned integer in little-endian byte order.
Definition: endian.h:541