Lely core libraries  2.2.5
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 = 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 
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  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_HAVE_VCI
can_msg::flags
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
can_msg::data
uint_least8_t data[CAN_MSG_MAX_LEN]
The frame payload (in case of a data frame).
Definition: msg.h:102
CAN_STATE_BUSOFF
@ CAN_STATE_BUSOFF
The bus off state (TX/RX error count >= 256).
Definition: err.h:34
CAN_MASK_EID
#define CAN_MASK_EID
The mask used to extract the 29-bit Extended Identifier from a CAN frame.
Definition: msg.h:34
CAN_STATE_ACTIVE
@ CAN_STATE_ACTIVE
The error active state (TX/RX error count < 128).
Definition: err.h:30
letoh32
uint_least32_t letoh32(uint_least32_t x)
Converts a 32-bit unsigned integer from little-endian to host byte order.
Definition: endian.h:396
CAN_MASK_BID
#define CAN_MASK_BID
The mask used to extract the 11-bit Base Identifier from a CAN frame.
Definition: msg.h:31
CAN_ERROR_BIT
@ CAN_ERROR_BIT
A single bit error.
Definition: err.h:44
string.h
can_msg
A CAN or CAN FD format frame.
Definition: msg.h:87
can_msg::len
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
MIN
#define MIN(a, b)
Returns the minimum of a and b.
Definition: util.h:57
CAN_STATE_PASSIVE
@ CAN_STATE_PASSIVE
The error passive state (TX/RX error count < 256).
Definition: err.h:32
CAN_ERROR_ACK
@ CAN_ERROR_ACK
An acknowledgment error.
Definition: err.h:52
CANMSG_is_error
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...
CAN_ERROR_OTHER
@ CAN_ERROR_OTHER
One or more other errors.
Definition: err.h:54
can_msg2CANMSG
int can_msg2CANMSG(const struct can_msg *src, void *dst)
Converts a can_msg frame to an IXXAT VCI CAN message.
CAN_ERROR_FORM
@ CAN_ERROR_FORM
A form error.
Definition: err.h:50
can_error
can_error
The error flags of a CAN bus, which are not mutually exclusive.
Definition: err.h:42
CAN_MAX_LEN
#define CAN_MAX_LEN
The maximum number of bytes in the payload of a CAN format frame.
Definition: msg.h:72
set_errnum
void set_errnum(errnum_t errnum)
Sets the current (thread-specific) platform-independent error number to errnum.
Definition: errnum.h:375
errnum.h
can.h
ERRNUM_INVAL
@ ERRNUM_INVAL
Invalid argument.
Definition: errnum.h:129
can_state
can_state
The states of a CAN node, depending on the TX/RX error count.
Definition: err.h:28
vci.h
CAN_ERROR_STUFF
@ CAN_ERROR_STUFF
A bit stuffing error.
Definition: err.h:46
CAN_ERROR_CRC
@ CAN_ERROR_CRC
A CRC sequence error.
Definition: err.h:48
CAN_FLAG_RTR
@ CAN_FLAG_RTR
The Remote Transmission Request (RTR) flag (unavailable in CAN FD format frames).
Definition: msg.h:48
htole32
uint_least32_t htole32(uint_least32_t x)
Converts a 32-bit unsigned integer from host to little-endian byte order.
Definition: endian.h:383
CAN_FLAG_IDE
@ CAN_FLAG_IDE
The Identifier Extension (IDE) flag.
Definition: msg.h:43
CANMSG2can_msg
int CANMSG2can_msg(const void *src, struct can_msg *dst)
Converts an IXXAT VCI CAN message to a can_msg frame.
can_msg::id
uint_least32_t id
The identifier (11 or 29 bits, depending on the CAN_FLAG_IDE flag).
Definition: msg.h:89
endian.h