123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977 |
- #ifndef ZEPHYR_INCLUDE_DRIVERS_CAN_H_
- #define ZEPHYR_INCLUDE_DRIVERS_CAN_H_
- #include <zephyr/types.h>
- #include <device.h>
- #include <string.h>
- #include <sys/util.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- #define CAN_EX_ID (1 << 31)
- #define CAN_MAX_STD_ID (0x7FF)
- #define CAN_STD_ID_MASK CAN_MAX_STD_ID
- #define CAN_EXT_ID_MASK (0x1FFFFFFF)
- #define CAN_MAX_DLC (8)
- #define CANFD_MAX_DLC CONFIG_CANFD_MAX_DLC
- #ifndef CONFIG_CANFD_MAX_DLC
- #define CAN_MAX_DLEN 8
- #else
- #if CONFIG_CANFD_MAX_DLC <= 8
- #define CAN_MAX_DLEN CONFIG_CANFD_MAX_DLC
- #elif CONFIG_CANFD_MAX_DLC <= 12
- #define CAN_MAX_DLEN CONFIG_CANFD_MAX_DLC + (CONFIG_CANFD_MAX_DLC - 8) * 4
- #elif CONFIG_CANFD_MAX_DLC == 13
- #define CAN_MAX_DLEN 32
- #elif CONFIG_CANFD_MAX_DLC == 14
- #define CAN_MAX_DLEN 48
- #elif CONFIG_CANFD_MAX_DLC == 15
- #define CAN_MAX_DLEN 64
- #endif
- #endif
- #define CAN_TX_OK (0)
- #define CAN_TX_ERR (-2)
- #define CAN_TX_ARB_LOST (-3)
- #define CAN_TX_BUS_OFF (-4)
- #define CAN_TX_UNKNOWN (-5)
- #define CAN_TX_EINVAL (-22)
- #define CAN_NO_FREE_FILTER (-1)
- #define CAN_TIMEOUT (-1)
- #define CAN_DEFINE_MSGQ(name, size) \
- K_MSGQ_DEFINE(name, sizeof(struct zcan_frame), size, 4)
- enum can_ide {
- CAN_STANDARD_IDENTIFIER,
- CAN_EXTENDED_IDENTIFIER
- };
- enum can_rtr {
- CAN_DATAFRAME,
- CAN_REMOTEREQUEST
- };
- enum can_mode {
-
- CAN_NORMAL_MODE,
-
- CAN_SILENT_MODE,
-
- CAN_LOOPBACK_MODE,
-
- CAN_SILENT_LOOPBACK_MODE
- };
- enum can_state {
- CAN_ERROR_ACTIVE,
- CAN_ERROR_PASSIVE,
- CAN_BUS_OFF,
- CAN_BUS_UNKNOWN
- };
- typedef uint32_t canid_t;
- struct can_frame {
-
- canid_t can_id;
-
- uint8_t can_dlc;
-
- uint8_t pad;
- uint8_t res0;
- uint8_t res1;
-
-
- uint8_t data[CAN_MAX_DLEN];
- };
- struct can_filter {
- canid_t can_id;
- canid_t can_mask;
- };
- struct zcan_frame {
-
- uint32_t id : 29;
-
- uint32_t fd : 1;
-
- uint32_t rtr : 1;
-
- uint32_t id_type : 1;
-
- uint8_t dlc;
-
- uint8_t brs : 1;
-
- uint8_t res : 7;
- #if defined(CONFIG_CAN_RX_TIMESTAMP)
-
- uint16_t timestamp;
- #else
-
- uint8_t res0;
- uint8_t res1;
-
- #endif
-
- union {
- uint8_t data[CAN_MAX_DLEN];
- uint32_t data_32[ceiling_fraction(CAN_MAX_DLEN, sizeof(uint32_t))];
- };
- };
- struct zcan_filter {
-
- uint32_t id : 29;
- uint32_t res0 : 1;
-
- uint32_t rtr : 1;
-
- uint32_t id_type : 1;
-
- uint32_t id_mask : 29;
- uint32_t res1 : 1;
-
- uint32_t rtr_mask : 1;
- uint32_t res2 : 1;
- };
- struct can_bus_err_cnt {
- uint8_t tx_err_cnt;
- uint8_t rx_err_cnt;
- };
- #define CAN_SJW_NO_CHANGE 0
- struct can_timing {
-
- uint16_t sjw;
-
- uint16_t prop_seg;
-
- uint16_t phase_seg1;
-
- uint16_t phase_seg2;
-
- uint16_t prescaler;
- };
- typedef void (*can_tx_callback_t)(uint32_t error_flags, void *arg);
- typedef void (*can_rx_callback_t)(struct zcan_frame *msg, void *arg);
- typedef void(*can_state_change_isr_t)(enum can_state state,
- struct can_bus_err_cnt err_cnt);
- typedef int (*can_set_timing_t)(const struct device *dev,
- const struct can_timing *timing,
- const struct can_timing *timing_data);
- typedef int (*can_set_mode_t)(const struct device *dev, enum can_mode mode);
- typedef int (*can_send_t)(const struct device *dev,
- const struct zcan_frame *msg,
- k_timeout_t timeout, can_tx_callback_t callback_isr,
- void *callback_arg);
- typedef int (*can_attach_msgq_t)(const struct device *dev,
- struct k_msgq *msg_q,
- const struct zcan_filter *filter);
- typedef int (*can_attach_isr_t)(const struct device *dev,
- can_rx_callback_t isr,
- void *callback_arg,
- const struct zcan_filter *filter);
- typedef void (*can_detach_t)(const struct device *dev, int filter_id);
- typedef int (*can_recover_t)(const struct device *dev, k_timeout_t timeout);
- typedef enum can_state (*can_get_state_t)(const struct device *dev,
- struct can_bus_err_cnt *err_cnt);
- typedef void(*can_register_state_change_isr_t)(const struct device *dev,
- can_state_change_isr_t isr);
- typedef int (*can_get_core_clock_t)(const struct device *dev, uint32_t *rate);
- #ifndef CONFIG_CAN_WORKQ_FRAMES_BUF_CNT
- #define CONFIG_CAN_WORKQ_FRAMES_BUF_CNT 4
- #endif
- struct can_frame_buffer {
- struct zcan_frame buf[CONFIG_CAN_WORKQ_FRAMES_BUF_CNT];
- uint16_t head;
- uint16_t tail;
- };
- struct zcan_work {
- struct k_work work_item;
- struct k_work_q *work_queue;
- struct can_frame_buffer buf;
- can_rx_callback_t cb;
- void *cb_arg;
- };
- __subsystem struct can_driver_api {
- can_set_mode_t set_mode;
- can_set_timing_t set_timing;
- can_send_t send;
- can_attach_isr_t attach_isr;
- can_detach_t detach;
- #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
- can_recover_t recover;
- #endif
- can_get_state_t get_state;
- can_register_state_change_isr_t register_state_change_isr;
- can_get_core_clock_t get_core_clock;
-
- struct can_timing timing_min;
-
- struct can_timing timing_max;
- #ifdef CONFIG_CAN_FD_MODE
-
- struct can_timing timing_min_data;
-
- struct can_timing timing_max_data;
- #endif
- };
- static inline uint8_t can_dlc_to_bytes(uint8_t dlc)
- {
- static const uint8_t dlc_table[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 12,
- 16, 20, 24, 32, 48, 64};
- return dlc > 0x0F ? 64 : dlc_table[dlc];
- }
- static inline uint8_t can_bytes_to_dlc(uint8_t num_bytes)
- {
- return num_bytes <= 8 ? num_bytes :
- num_bytes <= 12 ? 9 :
- num_bytes <= 16 ? 10 :
- num_bytes <= 20 ? 11 :
- num_bytes <= 24 ? 12 :
- num_bytes <= 32 ? 13 :
- num_bytes <= 48 ? 14 :
- 15;
- }
- __syscall int can_send(const struct device *dev, const struct zcan_frame *msg,
- k_timeout_t timeout, can_tx_callback_t callback_isr,
- void *callback_arg);
- static inline int z_impl_can_send(const struct device *dev,
- const struct zcan_frame *msg,
- k_timeout_t timeout,
- can_tx_callback_t callback_isr,
- void *callback_arg)
- {
- const struct can_driver_api *api =
- (const struct can_driver_api *)dev->api;
- return api->send(dev, msg, timeout, callback_isr, callback_arg);
- }
- static inline int can_write(const struct device *dev, const uint8_t *data,
- uint8_t length,
- uint32_t id, enum can_rtr rtr, k_timeout_t timeout)
- {
- struct zcan_frame msg;
- if (length > 8) {
- return -EINVAL;
- }
- msg.id = id;
- if (id > CAN_MAX_STD_ID) {
- msg.id_type = CAN_EXTENDED_IDENTIFIER;
- } else {
- msg.id_type = CAN_STANDARD_IDENTIFIER;
- }
- msg.dlc = length;
- msg.rtr = rtr;
- memcpy(msg.data, data, length);
- return can_send(dev, &msg, timeout, NULL, NULL);
- }
- int can_attach_workq(const struct device *dev, struct k_work_q *work_q,
- struct zcan_work *work,
- can_rx_callback_t callback, void *callback_arg,
- const struct zcan_filter *filter);
- __syscall int can_attach_msgq(const struct device *dev, struct k_msgq *msg_q,
- const struct zcan_filter *filter);
- static inline int can_attach_isr(const struct device *dev,
- can_rx_callback_t isr,
- void *callback_arg,
- const struct zcan_filter *filter)
- {
- const struct can_driver_api *api =
- (const struct can_driver_api *)dev->api;
- return api->attach_isr(dev, isr, callback_arg, filter);
- }
- __syscall void can_detach(const struct device *dev, int filter_id);
- static inline void z_impl_can_detach(const struct device *dev, int filter_id)
- {
- const struct can_driver_api *api =
- (const struct can_driver_api *)dev->api;
- return api->detach(dev, filter_id);
- }
- __syscall int can_get_core_clock(const struct device *dev, uint32_t *rate);
- static inline int z_impl_can_get_core_clock(const struct device *dev,
- uint32_t *rate)
- {
- const struct can_driver_api *api =
- (const struct can_driver_api *)dev->api;
- return api->get_core_clock(dev, rate);
- }
- int can_calc_timing(const struct device *dev, struct can_timing *res,
- uint32_t bitrate, uint16_t sample_pnt);
- #ifdef CONFIG_CAN_FD_MODE
- int can_calc_timing_data(const struct device *dev, struct can_timing *res,
- uint32_t bitrate, uint16_t sample_pnt);
- #endif
- int can_calc_prescaler(const struct device *dev, struct can_timing *timing,
- uint32_t bitrate);
- __syscall int can_set_mode(const struct device *dev, enum can_mode mode);
- static inline int z_impl_can_set_mode(const struct device *dev,
- enum can_mode mode)
- {
- const struct can_driver_api *api =
- (const struct can_driver_api *)dev->api;
- return api->set_mode(dev, mode);
- }
- __syscall int can_set_timing(const struct device *dev,
- const struct can_timing *timing,
- const struct can_timing *timing_data);
- static inline int z_impl_can_set_timing(const struct device *dev,
- const struct can_timing *timing,
- const struct can_timing *timing_data)
- {
- const struct can_driver_api *api =
- (const struct can_driver_api *)dev->api;
- return api->set_timing(dev, timing, timing_data);
- }
- static inline int can_set_bitrate(const struct device *dev,
- uint32_t bitrate,
- uint32_t bitrate_data)
- {
- struct can_timing timing;
- #ifdef CONFIG_CAN_FD_MODE
- struct can_timing timing_data;
- #endif
- int ret;
- ret = can_calc_timing(dev, &timing, bitrate, 875);
- if (ret < 0) {
- return -EINVAL;
- }
- timing.sjw = CAN_SJW_NO_CHANGE;
- #ifdef CONFIG_CAN_FD_MODE
- ret = can_calc_timing_data(dev, &timing_data, bitrate_data, 875);
- if (ret < 0) {
- return -EINVAL;
- }
- timing_data.sjw = CAN_SJW_NO_CHANGE;
- return can_set_timing(dev, &timing, &timing_data);
- #else
- return can_set_timing(dev, &timing, NULL);
- #endif
- }
- static inline int can_configure(const struct device *dev, enum can_mode mode,
- uint32_t bitrate)
- {
- if (bitrate > 0) {
- int err = can_set_bitrate(dev, bitrate, 0);
- if (err != 0) {
- return err;
- }
- }
- return can_set_mode(dev, mode);
- }
- __syscall enum can_state can_get_state(const struct device *dev,
- struct can_bus_err_cnt *err_cnt);
- static inline
- enum can_state z_impl_can_get_state(const struct device *dev,
- struct can_bus_err_cnt *err_cnt)
- {
- const struct can_driver_api *api =
- (const struct can_driver_api *)dev->api;
- return api->get_state(dev, err_cnt);
- }
- #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
- __syscall int can_recover(const struct device *dev, k_timeout_t timeout);
- static inline int z_impl_can_recover(const struct device *dev,
- k_timeout_t timeout)
- {
- const struct can_driver_api *api =
- (const struct can_driver_api *)dev->api;
- return api->recover(dev, timeout);
- }
- #else
- static inline int z_impl_can_recover(const struct device *dev,
- k_timeout_t timeout)
- {
- return 0;
- }
- #endif
- static inline
- void can_register_state_change_isr(const struct device *dev,
- can_state_change_isr_t isr)
- {
- const struct can_driver_api *api =
- (const struct can_driver_api *)dev->api;
- return api->register_state_change_isr(dev, isr);
- }
- static inline void can_copy_frame_to_zframe(const struct can_frame *frame,
- struct zcan_frame *zframe)
- {
- zframe->id_type = (frame->can_id & BIT(31)) >> 31;
- zframe->rtr = (frame->can_id & BIT(30)) >> 30;
- zframe->id = frame->can_id & BIT_MASK(29);
- zframe->dlc = frame->can_dlc;
- memcpy(zframe->data, frame->data, sizeof(zframe->data));
- }
- static inline void can_copy_zframe_to_frame(const struct zcan_frame *zframe,
- struct can_frame *frame)
- {
- frame->can_id = (zframe->id_type << 31) | (zframe->rtr << 30) |
- zframe->id;
- frame->can_dlc = zframe->dlc;
- memcpy(frame->data, zframe->data, sizeof(frame->data));
- }
- static inline
- void can_copy_filter_to_zfilter(const struct can_filter *filter,
- struct zcan_filter *zfilter)
- {
- zfilter->id_type = (filter->can_id & BIT(31)) >> 31;
- zfilter->rtr = (filter->can_id & BIT(30)) >> 30;
- zfilter->id = filter->can_id & BIT_MASK(29);
- zfilter->rtr_mask = (filter->can_mask & BIT(30)) >> 30;
- zfilter->id_mask = filter->can_mask & BIT_MASK(29);
- }
- static inline
- void can_copy_zfilter_to_filter(const struct zcan_filter *zfilter,
- struct can_filter *filter)
- {
- filter->can_id = (zfilter->id_type << 31) |
- (zfilter->rtr << 30) | zfilter->id;
- filter->can_mask = (zfilter->rtr_mask << 30) |
- (zfilter->id_type << 31) | zfilter->id_mask;
- }
- #ifdef __cplusplus
- }
- #endif
- #include <syscalls/can.h>
- #endif
|