Hardware Abstraction Layer for FreeRTOS
can.h
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
2 /*
3  * Author: Andreas Werner <kernel@andy89.org>
4  * Date: 2018
5  */
6 #ifndef CAN_H_
7 #define CAN_H_
8 #include <stdint.h>
9 #include <stdbool.h>
10 #include <system.h>
11 #include <FreeRTOS.h>
12 #include <semphr.h>
13 #include <hal.h>
14 #include <gpio.h>
28 struct can;
37 struct can_filter {
41  uint32_t id;
45  uint32_t mask;
46 };
47 #ifdef CONFIG_CAN_FD
48 # define CAN_MAX_LENGTH 64
49 #else
50 
53 # define CAN_MAX_LENGTH 8
54 #endif
55 
58 struct can_msg {
64  uint32_t ts;
68  uint32_t id;
74  uint8_t length;
78  uint8_t data[CAN_MAX_LENGTH];
79 };
80 
81 /* special address description flags for the CAN_ID */
82 #define CAN_EFF_FLAG BIT(31) /* EFF/SFF is set in the MSB */
83 #define CAN_RTR_FLAG BIT(30) /* remote transmission request */
84 
85 /* valid bits in CAN ID for frame formats */
86 #define CAN_SFF_MASK 0x000007FFUL /* standard frame format (SFF) */
87 #define CAN_EFF_MASK 0x1FFFFFFFUL /* extended frame format (EFF) */
88 
89 typedef uint32_t can_error_t;
90 typedef uint64_t can_errorData_t;
91 
95 #define CAN_ERR_CRTL BIT64(0)
96 #define CAN_ERR_CTRL_OFFSET 0
97 
100 #define CAN_ERR_CRTL_UNSPEC BIT64(CAN_ERR_CTRL_OFFSET + 0)
101 
104 #define CAN_ERR_CRTL_RX_OVERFLOW BIT64(CAN_ERR_CTRL_OFFSET + 1)
105 
108 #define CAN_ERR_CRTL_TX_OVERFLOW BIT64(CAN_ERR_CTRL_OFFSET + 2)
109 
112 #define CAN_ERR_CRTL_RX_WARNING BIT64(CAN_ERR_CTRL_OFFSET + 3)
113 /*
114  * Reached warning level for TX errors
115  */
116 #define CAN_ERR_CRTL_TX_WARNING BIT64(CAN_ERR_CTRL_OFFSET + 4)
117 
120 #define CAN_ERR_CRTL_RX_PASSIVE BIT64(CAN_ERR_CTRL_OFFSET + 5)
121 
126 #define CAN_ERR_CRTL_TX_PASSIVE BIT64(CAN_ERR_CTRL_OFFSET + 6)
127 
132 #define CAN_ERR_CRTL_ACTIVE BIT64(CAN_ERR_CTRL_OFFSET + 7)
133 
136 #define CAN_ERR_PROT BIT64(1)
137 #define CAN_ERR_PROT_OFFSET 8
138 
141 #define CAN_ERR_PROT_UNSPEC BIT64(CAN_ERR_PROT_OFFSET + 0)
142 
145 #define CAN_ERR_PROT_BIT BIT64(CAN_ERR_PROT_OFFSET + 1)
146 
149 #define CAN_ERR_PROT_FORM BIT64(CAN_ERR_PROT_OFFSET + 2)
150 
153 #define CAN_ERR_PROT_STUFF BIT64(CAN_ERR_PROT_OFFSET + 3)
154 
157 #define CAN_ERR_PROT_BIT0 BIT64(CAN_ERR_PROT_OFFSET + 4)
158 
161 #define CAN_ERR_PROT_BIT1 BIT64(CAN_ERR_PROT_OFFSET + 5)
162 
165 #define CAN_ERR_PROT_OVERLOAD BIT64(CAN_ERR_PROT_OFFSET + 6)
166 
169 #define CAN_ERR_PROT_ACTIVE BIT64(CAN_ERR_PROT_OFFSET + 7)
170 
173 #define CAN_ERR_PROT_TX BIT64(CAN_ERR_PROT_OFFSET + 8)
174 
175 #define CAN_ERR_PROT_LOC_OFFSET 24
176 
179 #define CAN_ERR_PROT_LOC_UNSPEC BIT64(CAN_ERR_PROT_LOC_OFFSET + 0)
180 
184 #define CAN_ERR_PROT_LOC_SOF BIT64(CAN_ERR_PROT_LOC_OFFSET + 1)
185 
189 #define CAN_ERR_PROT_LOC_ID28_21 BIT64(CAN_ERR_PROT_LOC_OFFSET + 2)
190 
194 #define CAN_ERR_PROT_LOC_ID20_18 BIT64(CAN_ERR_PROT_LOC_OFFSET + 3)
195 
199 #define CAN_ERR_PROT_LOC_SRTR BIT64(CAN_ERR_PROT_LOC_OFFSET + 4)
200 
204 #define CAN_ERR_PROT_LOC_IDE BIT64(CAN_ERR_PROT_LOC_OFFSET + 5)
205 
209 #define CAN_ERR_PROT_LOC_ID17_13 BIT64(CAN_ERR_PROT_LOC_OFFSET + 6)
210 
214 #define CAN_ERR_PROT_LOC_ID12_05 BIT64(CAN_ERR_PROT_LOC_OFFSET + 7)
215 
219 #define CAN_ERR_PROT_LOC_ID04_00 BIT64(CAN_ERR_PROT_LOC_OFFSET + 8)
220 
224 #define CAN_ERR_PROT_LOC_RTR BIT64(CAN_ERR_PROT_LOC_OFFSET + 9)
225 
229 #define CAN_ERR_PROT_LOC_RES1 BIT64(CAN_ERR_PROT_LOC_OFFSET + 10)
230 
234 #define CAN_ERR_PROT_LOC_RES0 BIT64(CAN_ERR_PROT_LOC_OFFSET + 11)
235 
239 #define CAN_ERR_PROT_LOC_DLC BIT64(CAN_ERR_PROT_LOC_OFFSET + 12)
240 
244 #define CAN_ERR_PROT_LOC_DATA BIT64(CAN_ERR_PROT_LOC_OFFSET + 13)
245 
249 #define CAN_ERR_PROT_LOC_CRC_SEQ BIT64(CAN_ERR_PROT_LOC_OFFSET + 14)
250 
254 #define CAN_ERR_PROT_LOC_CRC_DEL BIT64(CAN_ERR_PROT_LOC_OFFSET + 15)
255 
259 #define CAN_ERR_PROT_LOC_ACK BIT64(CAN_ERR_PROT_LOC_OFFSET + 16)
260 
264 #define CAN_ERR_PROT_LOC_ACK_DEL BIT64(CAN_ERR_PROT_LOC_OFFSET + 17)
265 
269 #define CAN_ERR_PROT_LOC_EOF BIT64(CAN_ERR_PROT_LOC_OFFSET + 18)
270 
274 #define CAN_ERR_PROT_LOC_INTERM BIT64(CAN_ERR_PROT_LOC_OFFSET + 19)
275 
279 #define CAN_ERR_TRX BIT64(2)
280 #define CAN_ERR_TRX_OFFSET 48
281 
284 #define CAN_ERR_TRX_UNSPEC BIT64(CAN_ERR_TRX_OFFSET + 0)
285 
288 #define CAN_ERR_TRX_CANH_NO_WIRE BIT64(CAN_ERR_TRX_OFFSET + 1)
289 
292 #define CAN_ERR_TRX_CANH_SHORT_TO_BAT BIT64(CAN_ERR_TRX_OFFSET + 2)
293 
296 #define CAN_ERR_TRX_CANH_SHORT_TO_VCC BIT64(CAN_ERR_TRX_OFFSET + 3)
297 
301 #define CAN_ERR_TRX_CANH_SHORT_TO_GND BIT64(CAN_ERR_TRX_OFFSET + 4)
302 
305 #define CAN_ERR_TRX_CANL_NO_WIRE BIT64(CAN_ERR_TRX_OFFSET + 5)
306 
309 #define CAN_ERR_TRX_CANL_SHORT_TO_BAT BIT64(CAN_ERR_TRX_OFFSET + 6)
310 
313 #define CAN_ERR_TRX_CANL_SHORT_TO_VCC BIT64(CAN_ERR_TRX_OFFSET + 7)
314 
317 #define CAN_ERR_TRX_CANL_SHORT_TO_GND BIT64(CAN_ERR_TRX_OFFSET + 8)
318 
321 #define CAN_ERR_TRX_CANL_SHORT_TO_CANH BIT64(CAN_ERR_TRX_OFFSET + 9)
322 
325 #define CAN_ERR_ACK BIT64(3)
326 
329 #define CAN_ERR_BUSOFF BIT64(4)
330 
333 #define CAN_ERR_BUSERROR BIT64(5)
334 
337 #define CAN_ERR_RESTARTED BIT64(6)
338 
339 #ifdef CONFIG_CAN_MULTI
340 
343 struct can_ops {
344  struct can *(*can_init)(uint32_t index, uint32_t bitrate, struct gpio_pin *pin, bool pinHigh, bool (*callback)(struct can *can, can_error_t error, can_errorData_t data, void *userData), void *data);
345  int32_t (*can_deinit)(struct can *can);
346  int32_t (*can_setCallback)(struct can *can, int32_t filterID, bool (*callback)(struct can *can, struct can_msg *msg, void *data), void *data);
347  int32_t (*can_registerFilter)(struct can *can, struct can_filter *filter);
348  int32_t (*can_deregisterFilter)(struct can *can, int32_t filterID);
349  int32_t (*can_send)(struct can *can, struct can_msg *msg, TickType_t waittime);
350  int32_t (*can_recv)(struct can *can, int32_t filterID, struct can_msg *msg, TickType_t waittime);
351  int32_t (*can_sendISR)(struct can *can, struct can_msg *msg);
352  int32_t (*can_recvISR)(struct can *can, int32_t filterID, struct can_msg *msg);
353  int32_t (*can_up)(struct can *can);
354  int32_t (*can_down)(struct can *can);
355 };
356 #endif
357 
360 struct can_generic {
365  bool init;
366 #ifdef CONFIG_INSTANCE_NAME
367 
370  const char *name;
371 #endif
372 #ifdef CONFIG_CAN_THREAD_SAVE
373 
377 #endif
378 #ifdef CONFIG_CAN_MULTI
379 
382  const struct can_ops *ops;
383 #endif
384 };
385 #ifndef CONFIG_CAN_MULTI
386 
396 struct can *can_init(uint32_t index, uint32_t bitrate, struct gpio_pin *pin, bool pinHigh, bool (*callback)(struct can *can, can_error_t error, can_errorData_t data, void *userData), void *data);
397 
403 int32_t can_deinit(struct can *can);
404 
415 int32_t can_setCallback(struct can *can, int32_t filterID, bool (*callback)(struct can *can, struct can_msg *msg, void *data), void *data);
424 int32_t can_registerFilter(struct can *can, struct can_filter *filter);
431 int32_t can_deregisterFilter(struct can *can, int32_t filterID);
432 
440 int32_t can_send(struct can *can, struct can_msg *msg, TickType_t waittime);
449 int32_t can_recv(struct can *can, int32_t filterID, struct can_msg *msg, TickType_t waittime);
456 int32_t can_sendISR(struct can *can, struct can_msg *msg);
464 int32_t can_recvISR(struct can *can, int32_t filterID, struct can_msg *msg);
465 
471 int32_t can_up(struct can *can);
472 
478 int32_t can_down(struct can *can);
479 
480 #else
481 inline struct can *can_init(uint32_t index, uint32_t bitrate, struct gpio_pin *pin, bool pinHigh, bool (*callback)(struct can *can, can_error_t error, can_errorData_t data, void *userData), void *data) {
483  struct can_generic *a = (struct can_generic *) HAL_GET_DEV(can, index);
484  if (a == NULL) {
485  return NULL;
486  }
487  return a->ops->can_init(index, bitrate, pin, pinHigh, callback, data, userData);
488 }
489 inline int32_t can_deinit(struct can *can) {
490  struct can_generic *a = (struct can_generic *) can;
491  return a->ops->can_deinit(can);
492 }
493 inline int32_t can_setCallback(struct can *can, int32_t filterID, bool (*callback)(struct can *can, struct can_msg *msg, void *data), void *data) {
494  struct can_generic *a = (struct can_generic *) can;
495  return a->ops->can_setCallback(can, filterID, callback, data);
496 }
497 inline int32_t can_registerFilter(struct can *can, struct can_filter *filter) {
498  struct can_generic *a = (struct can_generic *) can;
499  return a->ops->can_registerFilter(can, filter);
500 }
501 inline int32_t can_deregisterFilter(struct can *can, int32_t filterID) {
502  struct can_generic *a = (struct can_generic *) can;
503  return a->ops->can_deregisterFilter(can, filterID);
504 }
505 inline int32_t can_send(struct can *can, struct can_msg *msg, TickType_t waittime) {
506  struct can_generic *a = (struct can_generic *) can;
507  return a->ops->can_send(can, msg, waittime);
508 }
509 inline int32_t can_recv(struct can *can, int32_t filterID, struct can_msg *msg, TickType_t waittime) {
510  struct can_generic *a = (struct can_generic *) can;
511  return a->ops->can_recv(can, filterID, msg, waittime);
512 }
513 inline int32_t can_sendISR(struct can *can, struct can_msg *msg) {
514  struct can_generic *a = (struct can_generic *) can;
515  return a->ops->can_sendISR(can, msg);
516 }
517 inline int32_t can_recvISR(struct can *can, int32_t filterID, struct can_msg *msg) {
518  struct can_generic *a = (struct can_generic *) can;
519  return a->ops->can_recvISR(can, filterID, msg);
520 }
521 inline int32_t can_up(struct can *can) {
522  struct can_generic *a = (struct can_generic *) can;
523  return a->ops->can_up(can);
524 }
525 inline int32_t can_down(struct can *can) {
526  struct can_generic *a = (struct can_generic *) can;
527  return a->ops->can_down(can);
528 }
529 #endif
530 
531 #endif
can_send
int32_t can_send(struct can *can, struct can_msg *msg, TickType_t waittime)
can_msg::id
uint32_t id
Definition: can.h:68
OS_DEFINE_MUTEX_RECURSIVE
#define OS_DEFINE_MUTEX_RECURSIVE(name)
Definition: os.h:59
hal.h
can_filter::mask
uint32_t mask
Definition: can.h:45
CAN_MAX_LENGTH
#define CAN_MAX_LENGTH
Definition: can.h:53
can_msg
Definition: can.h:58
can_up
int32_t can_up(struct can *can)
can_deinit
int32_t can_deinit(struct can *can)
can_registerFilter
int32_t can_registerFilter(struct can *can, struct can_filter *filter)
can_recvISR
int32_t can_recvISR(struct can *can, int32_t filterID, struct can_msg *msg)
can_recv
int32_t can_recv(struct can *can, int32_t filterID, struct can_msg *msg, TickType_t waittime)
HAL_DEFINE_GLOBAL_ARRAY
#define HAL_DEFINE_GLOBAL_ARRAY(gns)
Definition: hal.h:149
can_down
int32_t can_down(struct can *can)
can_filter
Definition: can.h:37
can_filter::id
uint32_t id
Definition: can.h:41
HAL_GET_DEV
#define HAL_GET_DEV(gns, index)
Definition: hal.h:182
can_error_t
uint32_t can_error_t
Definition: can.h:89
can_errorData_t
uint64_t can_errorData_t
Definition: can.h:90
can_generic::init
bool init
Definition: can.h:365
can_deregisterFilter
int32_t can_deregisterFilter(struct can *can, int32_t filterID)
can_msg::length
uint8_t length
Definition: can.h:74
system.h
can_msg::data
uint8_t data[CAN_MAX_LENGTH]
Definition: can.h:78
can_msg::ts
uint32_t ts
Definition: can.h:64
gpio.h
can_setCallback
int32_t can_setCallback(struct can *can, int32_t filterID, bool(*callback)(struct can *can, struct can_msg *msg, void *data), void *data)
can_init
struct can * can_init(uint32_t index, uint32_t bitrate, struct gpio_pin *pin, bool pinHigh, bool(*callback)(struct can *can, can_error_t error, can_errorData_t data, void *userData), void *data)
can_generic
Definition: can.h:360
can_sendISR
int32_t can_sendISR(struct can *can, struct can_msg *msg)