From c0c9396d443dcfd345f1a56a04ab2e16b74d6b08 Mon Sep 17 00:00:00 2001 From: Anas Nashif Date: Tue, 25 Jun 2019 15:53:46 -0400 Subject: [PATCH] cleanup: include/: move can.h to drivers/can.h move can.h to drivers/can.h and create a shim for backward-compatibility. No functional changes to the headers. A warning in the shim can be controlled with CONFIG_COMPAT_INCLUDES. Related to #16539 Signed-off-by: Anas Nashif --- drivers/can/can_common.c | 2 +- drivers/can/can_handlers.c | 2 +- drivers/can/can_loopback.c | 2 +- drivers/can/can_loopback.h | 2 +- drivers/can/can_mcp2515.h | 2 +- drivers/can/can_mcux_flexcan.c | 2 +- drivers/can/can_stm32.c | 2 +- drivers/can/can_stm32.h | 2 +- include/can.h | 540 +--------------------------- include/drivers/can.h | 547 +++++++++++++++++++++++++++++ include/net/socket_can.h | 2 +- samples/drivers/CAN/src/main.c | 2 +- tests/drivers/can/api/src/main.c | 2 +- tests/drivers/can/stm32/src/main.c | 2 +- tests/subsys/can/frame/src/main.c | 2 +- 15 files changed, 564 insertions(+), 549 deletions(-) create mode 100644 include/drivers/can.h diff --git a/drivers/can/can_common.c b/drivers/can/can_common.c index e13858eab73..eb49b4169ea 100644 --- a/drivers/can/can_common.c +++ b/drivers/can/can_common.c @@ -4,7 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #define LOG_LEVEL CONFIG_CAN_LOG_LEVEL diff --git a/drivers/can/can_handlers.c b/drivers/can/can_handlers.c index 7e53971c6a4..d6f0e9d9651 100644 --- a/drivers/can/can_handlers.c +++ b/drivers/can/can_handlers.c @@ -5,7 +5,7 @@ */ #include -#include +#include Z_SYSCALL_HANDLER(can_configure, dev, mode, bitrate) { diff --git a/drivers/can/can_loopback.c b/drivers/can/can_loopback.c index 747b18a98ab..bf4637b6cac 100644 --- a/drivers/can/can_loopback.c +++ b/drivers/can/can_loopback.c @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include "can_loopback.h" #include diff --git a/drivers/can/can_loopback.h b/drivers/can/can_loopback.h index 4c76d942bc5..238f5c28119 100644 --- a/drivers/can/can_loopback.h +++ b/drivers/can/can_loopback.h @@ -8,7 +8,7 @@ #ifndef ZEPHYR_DRIVERS_CAN_LOOPBACK_CAN_H_ #define ZEPHYR_DRIVERS_CAN_LOOPBACK_CAN_H_ -#include +#include #define DEV_DATA(dev) ((struct can_loopback_data *const)(dev)->driver_data) #define DEV_CFG(dev) \ diff --git a/drivers/can/can_mcp2515.h b/drivers/can/can_mcp2515.h index d5d12e8757f..fc8924ff317 100644 --- a/drivers/can/can_mcp2515.h +++ b/drivers/can/can_mcp2515.h @@ -8,7 +8,7 @@ #ifndef _MCP2515_H_ #define _MCP2515_H_ -#include +#include #define MCP2515_TX_CNT 3 #define MCP2515_FRAME_LEN 13 diff --git a/drivers/can/can_mcux_flexcan.c b/drivers/can/can_mcux_flexcan.c index 9cbeff62515..8a607caf929 100644 --- a/drivers/can/can_mcux_flexcan.c +++ b/drivers/can/can_mcux_flexcan.c @@ -6,7 +6,7 @@ #include #include -#include +#include #include #include #include diff --git a/drivers/can/can_stm32.c b/drivers/can/can_stm32.c index babd9088dac..a3d24faa5b3 100644 --- a/drivers/can/can_stm32.c +++ b/drivers/can/can_stm32.c @@ -12,7 +12,7 @@ #include #include #include -#include +#include #include "can_stm32.h" #include diff --git a/drivers/can/can_stm32.h b/drivers/can/can_stm32.h index 48921895868..0ba94e12c0b 100644 --- a/drivers/can/can_stm32.h +++ b/drivers/can/can_stm32.h @@ -8,7 +8,7 @@ #ifndef ZEPHYR_DRIVERS_CAN_STM32_CAN_H_ #define ZEPHYR_DRIVERS_CAN_STM32_CAN_H_ -#include +#include #define DEV_DATA(dev) ((struct can_stm32_data *const)(dev)->driver_data) #define DEV_CFG(dev) \ diff --git a/include/can.h b/include/can.h index 99bcfc914b6..bd3ef6a3155 100644 --- a/include/can.h +++ b/include/can.h @@ -1,547 +1,15 @@ -/** - * @file - * - * @brief Public APIs for the CAN drivers. - */ - /* - * Copyright (c) 2018 Alexander Wachter + * Copyright (c) 2019 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ - #ifndef ZEPHYR_INCLUDE_CAN_H_ #define ZEPHYR_INCLUDE_CAN_H_ -/** - * @brief CAN Interface - * @defgroup can_interface CAN Interface - * @ingroup io_interfaces - * @{ - */ - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { +#ifndef CONFIG_COMPAT_INCLUDES +#warning "This header file has moved, include instead." #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 CAN_MAX_DLEN 8 - -/* CAN_TX_* are the error flags from tx_callback and send.*/ -/** send successfully */ -#define CAN_TX_OK (0) -/** general send error */ -#define CAN_TX_ERR (-2) -/** bus arbitration lost during sending */ -#define CAN_TX_ARB_LOST (-3) -/** controller is in bus off state */ -#define CAN_TX_BUS_OFF (-4) -/** unexpected error */ -#define CAN_TX_UNKNOWN (-5) - -/** attach_* failed because there is no unused filter left*/ -#define CAN_NO_FREE_FILTER (-1) - -/** operation timed out*/ -#define CAN_TIMEOUT (-1) - -/** - * @brief Statically define and initialize a can message queue. - * - * The message queue's ring buffer contains space for @a size messages. - * - * @param name Name of the message queue. - * @param size Number of can messages. - */ -#define CAN_DEFINE_MSGQ(name, size) \ - K_MSGQ_DEFINE(name, sizeof(struct zcan_frame), size, 4) - -/** - * @brief can_ide enum - * Define if the message has a standard (11bit) or extended (29bit) - * identifier - */ -enum can_ide { - CAN_STANDARD_IDENTIFIER, - CAN_EXTENDED_IDENTIFIER -}; - -/** - * @brief can_rtr enum - * Define if the message is a data or remote frame - */ -enum can_rtr { - CAN_DATAFRAME, - CAN_REMOTEREQUEST -}; - -/** - * @brief can_mode enum - * Defines the mode of the can controller - */ -enum can_mode { - /*Normal mode*/ - CAN_NORMAL_MODE, - /*Controller is not allowed to send dominant bits*/ - CAN_SILENT_MODE, - /*Controller is in loopback mode (receive own messages)*/ - CAN_LOOPBACK_MODE, - /*Combination of loopback and silent*/ - CAN_SILENT_LOOPBACK_MODE -}; - -/* - * Controller Area Network Identifier structure for Linux compatibility. - * - * The fields in this type are: - * - * bit 0-28 : CAN identifier (11/29 bit) - * bit 29 : error message frame flag (0 = data frame, 1 = error message) - * bit 30 : remote transmission request flag (1 = rtr frame) - * bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit) - */ -typedef u32_t canid_t; - -/** - * @brief CAN frame structure that is compatible with Linux. This is mainly - * used by Socket CAN code. - * - * @details Used to pass CAN messages from userspace to the socket CAN and vice - * versa. - */ -struct can_frame { - /** 32 bit CAN_ID + EFF/RTR/ERR flags */ - canid_t can_id; - - /** The length of the message */ - u8_t can_dlc; - - /** @cond INTERNAL_HIDDEN */ - u8_t pad; /* padding */ - u8_t res0; /* reserved / padding */ - u8_t res1; /* reserved / padding */ - /** @endcond */ - - /** The message data */ - u8_t data[CAN_MAX_DLEN]; -}; - -/** - * @brief CAN filter that is compatible with Linux. This is mainly used by - * Socket CAN code. - * - * @details A filter matches, when "received_can_id & mask == can_id & mask" - */ -struct can_filter { - canid_t can_id; - canid_t can_mask; -}; - -/** - * @brief CAN message structure - * - * Used to pass can messages from userspace to the driver and - * from driver to userspace - * - */ -struct zcan_frame { - /** Indicates the identifier type (standard or extended) - * use can_ide enum for assignment - */ - u32_t id_type : 1; - /** Set the message to a transmission request instead of data frame - * use can_rtr enum for assignment - */ - u32_t rtr : 1; - /** Message identifier*/ - union { - u32_t std_id : 11; - u32_t ext_id : 29; - }; - /** The length of the message (max. 8) in byte */ - u8_t dlc; - /** The message data*/ - union { - u8_t data[8]; - u32_t data_32[2]; - }; -} __packed; - -/** - * @brief CAN filter structure - * - * Used to pass can identifier filter information to the driver. - * rtr_mask and *_id_mask are used to mask bits of the rtr and id fields. - * If the mask bit is 0, the value of the corresponding bit in the id or rtr - * field don't care for the filter matching. - * - */ -struct zcan_filter { - /** Indicates the identifier type (standard or extended) - * use can_ide enum for assignment - */ - u32_t id_type : 1; - /** target state of the rtr bit */ - u32_t rtr : 1; - /** target state of the identifier */ - union { - u32_t std_id : 11; - u32_t ext_id : 29; - }; - /** rtr bit mask */ - u32_t rtr_mask : 1; - /** identifier mask*/ - union { - u32_t std_id_mask : 11; - u32_t ext_id_mask : 29; - }; -} __packed; - -/** - * @typedef can_tx_callback_t - * @brief Define the application callback handler function signature - * - * @param error_flags status of the performed send operation - * @param arg argument that was passed when the message was sent - */ -typedef void (*can_tx_callback_t)(u32_t error_flags, void *arg); - -/** - * @typedef can_rx_callback_t - * @brief Define the application callback handler function signature - * for receiving. - * - * @param msg received message - * @param arg argument that was passed when the filter was attached - */ -typedef void (*can_rx_callback_t)(struct zcan_frame *msg, void *arg); - -typedef int (*can_configure_t)(struct device *dev, enum can_mode mode, - u32_t bitrate); - -typedef int (*can_send_t)(struct device *dev, const struct zcan_frame *msg, - s32_t timeout, can_tx_callback_t callback_isr, - void *callback_arg); - - -typedef int (*can_attach_msgq_t)(struct device *dev, struct k_msgq *msg_q, - const struct zcan_filter *filter); - -typedef int (*can_attach_isr_t)(struct device *dev, can_rx_callback_t isr, - void *callback_arg, - const struct zcan_filter *filter); - -typedef void (*can_detach_t)(struct device *dev, int filter_id); - -#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]; - u16_t head; - u16_t tail; -}; - -/** - * @brief CAN work structure - * - * Used to attach a work queue to a filter. - */ -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; -}; - -struct can_driver_api { - can_configure_t configure; - can_send_t send; - can_attach_isr_t attach_isr; - can_detach_t detach; -}; - -/** - * @brief Perform data transfer to CAN bus. - * - * This routine provides a generic interface to perform data transfer - * to the can bus. Use can_write() for simple write. - * * - * @param dev Pointer to the device structure for the driver instance. - * @param msg Message to transfer. - * @param timeout Waiting for empty tx mailbox timeout in ms or K_FOREVER. - * @param callback_isr Is called when message was sent or a transmission error - * occurred. If NULL, this function is blocking until - * message is sent. This must be NULL if called from user - * mode. - * @param callback_arg This will be passed whenever the isr is called. - * - * @retval 0 If successful. - * @retval CAN_TX_* on failure. - */ -__syscall int can_send(struct device *dev, const struct zcan_frame *msg, - s32_t timeout, can_tx_callback_t callback_isr, - void *callback_arg); - -static inline int z_impl_can_send(struct device *dev, - const struct zcan_frame *msg, - s32_t timeout, can_tx_callback_t callback_isr, - void *callback_arg) -{ - const struct can_driver_api *api = - (const struct can_driver_api *)dev->driver_api; - - return api->send(dev, msg, timeout, callback_isr, callback_arg); -} - -/* - * Derived can APIs -- all implemented in terms of can_send() - */ - -/** - * @brief Write a set amount of data to the can bus. - * - * This routine writes a set amount of data synchronously. - * - * @param dev Pointer to the device structure for the driver instance. - * @param data Data to send. - * @param length Number of bytes to write (max. 8). - * @param id Identifier of the can message. - * @param rtr Send remote transmission request or data frame - * @param timeout Waiting for empty tx mailbox timeout in ms or K_FOREVER - * - * @retval 0 If successful. - * @retval -EIO General input / output error. - * @retval -EINVAL if length > 8. - */ -static inline int can_write(struct device *dev, const u8_t *data, u8_t length, - u32_t id, enum can_rtr rtr, s32_t timeout) -{ - struct zcan_frame msg; - - if (length > 8) { - return -EINVAL; - } - - if (id > CAN_MAX_STD_ID) { - msg.id_type = CAN_EXTENDED_IDENTIFIER; - msg.ext_id = id & CAN_EXT_ID_MASK; - } else { - msg.id_type = CAN_STANDARD_IDENTIFIER; - msg.std_id = id; - } - - msg.dlc = length; - msg.rtr = rtr; - memcpy(msg.data, data, length); - - return can_send(dev, &msg, timeout, NULL, NULL); -} - -/** - * @brief Attach a CAN work queue to a single or group of identifiers. - * - * This routine attaches a work queue to identifiers specified by a filter. - * Whenever the filter matches, the message is pushed to the buffer - * of the zcan_work structure and the work element is put to the workqueue. - * If a message passes more than one filter the priority of the match - * is hardware dependent. - * A CAN work queue can be attached to more than one filter. - * The work queue must be initialized before and the caller must have - * appropriate permissions on it. - * - * @param dev Pointer to the device structure for the driver instance. - * @param work_q Pointer to the already initialized work queue. - * @param work Pointer to a zcan_work. The work will be initialized. - * @param callback This function is called by workq whenever a message arrives. - * @param callback_arg Is passed to the callback when called. - * @param filter Pointer to a zcan_filter structure defining the id - * filtering. - * - * @retval filter id on success. - * @retval CAN_NO_FREE_FILTER if there is no filter left. - */ -int can_attach_workq(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); - -/** - * @brief Attach a message queue to a single or group of identifiers. - * - * This routine attaches a message queue to identifiers specified by - * a filter. Whenever the filter matches, the message is pushed to the queue - * If a message passes more than one filter the priority of the match - * is hardware dependent. - * A message queue can be attached to more than one filter. - * The message queue must me initialized before, and the caller must have - * appropriate permissions on it. - * - * @param dev Pointer to the device structure for the driver instance. - * @param msg_q Pointer to the already initialized message queue. - * @param filter Pointer to a zcan_filter structure defining the id - * filtering. - * - * @retval filter id on success. - * @retval CAN_NO_FREE_FILTER if there is no filter left. - */ -__syscall int can_attach_msgq(struct device *dev, struct k_msgq *msg_q, - const struct zcan_filter *filter); - -/** - * @brief Attach an isr callback function to a single or group of identifiers. - * - * This routine attaches an isr callback to identifiers specified by - * a filter. Whenever the filter matches, the callback function is called - * with isr context. - * If a message passes more than one filter the priority of the match - * is hardware dependent. - * A callback function can be attached to more than one filter. - * * - * @param dev Pointer to the device structure for the driver instance. - * @param isr Callback function pointer. - * @param callback_arg This will be passed whenever the isr is called. - * @param filter Pointer to a zcan_filter structure defining the id - * filtering. - * - * @retval filter id on success. - * @retval CAN_NO_FREE_FILTER if there is no filter left. - */ -static inline int can_attach_isr(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->driver_api; - - return api->attach_isr(dev, isr, callback_arg, filter); -} - -/** - * @brief Detach an isr or message queue from the identifier filtering. - * - * This routine detaches an isr callback or message queue from the identifier - * filtering. - * * - * @param dev Pointer to the device structure for the driver instance. - * @param filter_id filter id returned by can_attach_isr or can_attach_msgq. - * - * @retval none - */ -__syscall void can_detach(struct device *dev, int filter_id); - -static inline void z_impl_can_detach(struct device *dev, int filter_id) -{ - const struct can_driver_api *api = - (const struct can_driver_api *)dev->driver_api; - - return api->detach(dev, filter_id); -} - -/** - * @brief Configure operation of a host controller. - * - * @param dev Pointer to the device structure for the driver instance. - * @param mode Operation mode - * @param bitrate bus-speed in Baud/s - * - * @retval 0 If successful. - * @retval -EIO General input / output error, failed to configure device. - */ -__syscall int can_configure(struct device *dev, enum can_mode mode, - u32_t bitrate); - -static inline int z_impl_can_configure(struct device *dev, enum can_mode mode, - u32_t bitrate) -{ - const struct can_driver_api *api = - (const struct can_driver_api *)dev->driver_api; - - return api->configure(dev, mode, bitrate); -} - -/** - * @brief Converter that translates between can_frame and zcan_frame structs. - * - * @param frame Pointer to can_frame struct. - * @param zframe Pointer to zcan_frame struct. - */ -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->ext_id = frame->can_id & BIT_MASK(29); - zframe->dlc = frame->can_dlc; - memcpy(zframe->data, frame->data, sizeof(zframe->data)); -} - -/** - * @brief Converter that translates between zcan_frame and can_frame structs. - * - * @param zframe Pointer to zcan_frame struct. - * @param frame Pointer to can_frame struct. - */ -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->ext_id; - frame->can_dlc = zframe->dlc; - memcpy(frame->data, zframe->data, sizeof(frame->data)); -} - -/** - * @brief Converter that translates between can_filter and zcan_frame_filter - * structs. - * - * @param filter Pointer to can_filter struct. - * @param zfilter Pointer to zcan_frame_filter struct. - */ -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->ext_id = filter->can_id & BIT_MASK(29); - zfilter->rtr_mask = (filter->can_mask & BIT(30)) >> 30; - zfilter->ext_id_mask = filter->can_mask & BIT_MASK(29); -} - -/** - * @brief Converter that translates between zcan_filter and can_filter - * structs. - * - * @param zfilter Pointer to zcan_filter struct. - * @param filter Pointer to can_filter struct. - */ -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->ext_id; - filter->can_mask = (zfilter->rtr_mask << 30) | - (zfilter->id_type << 31) | zfilter->ext_id_mask; -} - -#ifdef __cplusplus -} -#endif -/** - * @} - */ -#include +#include #endif /* ZEPHYR_INCLUDE_CAN_H_ */ diff --git a/include/drivers/can.h b/include/drivers/can.h new file mode 100644 index 00000000000..7798a9b5e8c --- /dev/null +++ b/include/drivers/can.h @@ -0,0 +1,547 @@ +/** + * @file + * + * @brief Public APIs for the CAN drivers. + */ + +/* + * Copyright (c) 2018 Alexander Wachter + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_DRIVERS_CAN_H_ +#define ZEPHYR_INCLUDE_DRIVERS_CAN_H_ + +/** + * @brief CAN Interface + * @defgroup can_interface CAN Interface + * @ingroup io_interfaces + * @{ + */ + +#include +#include +#include + +#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 CAN_MAX_DLEN 8 + +/* CAN_TX_* are the error flags from tx_callback and send.*/ +/** send successfully */ +#define CAN_TX_OK (0) +/** general send error */ +#define CAN_TX_ERR (-2) +/** bus arbitration lost during sending */ +#define CAN_TX_ARB_LOST (-3) +/** controller is in bus off state */ +#define CAN_TX_BUS_OFF (-4) +/** unexpected error */ +#define CAN_TX_UNKNOWN (-5) + +/** attach_* failed because there is no unused filter left*/ +#define CAN_NO_FREE_FILTER (-1) + +/** operation timed out*/ +#define CAN_TIMEOUT (-1) + +/** + * @brief Statically define and initialize a can message queue. + * + * The message queue's ring buffer contains space for @a size messages. + * + * @param name Name of the message queue. + * @param size Number of can messages. + */ +#define CAN_DEFINE_MSGQ(name, size) \ + K_MSGQ_DEFINE(name, sizeof(struct zcan_frame), size, 4) + +/** + * @brief can_ide enum + * Define if the message has a standard (11bit) or extended (29bit) + * identifier + */ +enum can_ide { + CAN_STANDARD_IDENTIFIER, + CAN_EXTENDED_IDENTIFIER +}; + +/** + * @brief can_rtr enum + * Define if the message is a data or remote frame + */ +enum can_rtr { + CAN_DATAFRAME, + CAN_REMOTEREQUEST +}; + +/** + * @brief can_mode enum + * Defines the mode of the can controller + */ +enum can_mode { + /*Normal mode*/ + CAN_NORMAL_MODE, + /*Controller is not allowed to send dominant bits*/ + CAN_SILENT_MODE, + /*Controller is in loopback mode (receive own messages)*/ + CAN_LOOPBACK_MODE, + /*Combination of loopback and silent*/ + CAN_SILENT_LOOPBACK_MODE +}; + +/* + * Controller Area Network Identifier structure for Linux compatibility. + * + * The fields in this type are: + * + * bit 0-28 : CAN identifier (11/29 bit) + * bit 29 : error message frame flag (0 = data frame, 1 = error message) + * bit 30 : remote transmission request flag (1 = rtr frame) + * bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit) + */ +typedef u32_t canid_t; + +/** + * @brief CAN frame structure that is compatible with Linux. This is mainly + * used by Socket CAN code. + * + * @details Used to pass CAN messages from userspace to the socket CAN and vice + * versa. + */ +struct can_frame { + /** 32 bit CAN_ID + EFF/RTR/ERR flags */ + canid_t can_id; + + /** The length of the message */ + u8_t can_dlc; + + /** @cond INTERNAL_HIDDEN */ + u8_t pad; /* padding */ + u8_t res0; /* reserved / padding */ + u8_t res1; /* reserved / padding */ + /** @endcond */ + + /** The message data */ + u8_t data[CAN_MAX_DLEN]; +}; + +/** + * @brief CAN filter that is compatible with Linux. This is mainly used by + * Socket CAN code. + * + * @details A filter matches, when "received_can_id & mask == can_id & mask" + */ +struct can_filter { + canid_t can_id; + canid_t can_mask; +}; + +/** + * @brief CAN message structure + * + * Used to pass can messages from userspace to the driver and + * from driver to userspace + * + */ +struct zcan_frame { + /** Indicates the identifier type (standard or extended) + * use can_ide enum for assignment + */ + u32_t id_type : 1; + /** Set the message to a transmission request instead of data frame + * use can_rtr enum for assignment + */ + u32_t rtr : 1; + /** Message identifier*/ + union { + u32_t std_id : 11; + u32_t ext_id : 29; + }; + /** The length of the message (max. 8) in byte */ + u8_t dlc; + /** The message data*/ + union { + u8_t data[8]; + u32_t data_32[2]; + }; +} __packed; + +/** + * @brief CAN filter structure + * + * Used to pass can identifier filter information to the driver. + * rtr_mask and *_id_mask are used to mask bits of the rtr and id fields. + * If the mask bit is 0, the value of the corresponding bit in the id or rtr + * field don't care for the filter matching. + * + */ +struct zcan_filter { + /** Indicates the identifier type (standard or extended) + * use can_ide enum for assignment + */ + u32_t id_type : 1; + /** target state of the rtr bit */ + u32_t rtr : 1; + /** target state of the identifier */ + union { + u32_t std_id : 11; + u32_t ext_id : 29; + }; + /** rtr bit mask */ + u32_t rtr_mask : 1; + /** identifier mask*/ + union { + u32_t std_id_mask : 11; + u32_t ext_id_mask : 29; + }; +} __packed; + +/** + * @typedef can_tx_callback_t + * @brief Define the application callback handler function signature + * + * @param error_flags status of the performed send operation + * @param arg argument that was passed when the message was sent + */ +typedef void (*can_tx_callback_t)(u32_t error_flags, void *arg); + +/** + * @typedef can_rx_callback_t + * @brief Define the application callback handler function signature + * for receiving. + * + * @param msg received message + * @param arg argument that was passed when the filter was attached + */ +typedef void (*can_rx_callback_t)(struct zcan_frame *msg, void *arg); + +typedef int (*can_configure_t)(struct device *dev, enum can_mode mode, + u32_t bitrate); + +typedef int (*can_send_t)(struct device *dev, const struct zcan_frame *msg, + s32_t timeout, can_tx_callback_t callback_isr, + void *callback_arg); + + +typedef int (*can_attach_msgq_t)(struct device *dev, struct k_msgq *msg_q, + const struct zcan_filter *filter); + +typedef int (*can_attach_isr_t)(struct device *dev, can_rx_callback_t isr, + void *callback_arg, + const struct zcan_filter *filter); + +typedef void (*can_detach_t)(struct device *dev, int filter_id); + +#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]; + u16_t head; + u16_t tail; +}; + +/** + * @brief CAN work structure + * + * Used to attach a work queue to a filter. + */ +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; +}; + +struct can_driver_api { + can_configure_t configure; + can_send_t send; + can_attach_isr_t attach_isr; + can_detach_t detach; +}; + +/** + * @brief Perform data transfer to CAN bus. + * + * This routine provides a generic interface to perform data transfer + * to the can bus. Use can_write() for simple write. + * * + * @param dev Pointer to the device structure for the driver instance. + * @param msg Message to transfer. + * @param timeout Waiting for empty tx mailbox timeout in ms or K_FOREVER. + * @param callback_isr Is called when message was sent or a transmission error + * occurred. If NULL, this function is blocking until + * message is sent. This must be NULL if called from user + * mode. + * @param callback_arg This will be passed whenever the isr is called. + * + * @retval 0 If successful. + * @retval CAN_TX_* on failure. + */ +__syscall int can_send(struct device *dev, const struct zcan_frame *msg, + s32_t timeout, can_tx_callback_t callback_isr, + void *callback_arg); + +static inline int z_impl_can_send(struct device *dev, + const struct zcan_frame *msg, + s32_t timeout, can_tx_callback_t callback_isr, + void *callback_arg) +{ + const struct can_driver_api *api = + (const struct can_driver_api *)dev->driver_api; + + return api->send(dev, msg, timeout, callback_isr, callback_arg); +} + +/* + * Derived can APIs -- all implemented in terms of can_send() + */ + +/** + * @brief Write a set amount of data to the can bus. + * + * This routine writes a set amount of data synchronously. + * + * @param dev Pointer to the device structure for the driver instance. + * @param data Data to send. + * @param length Number of bytes to write (max. 8). + * @param id Identifier of the can message. + * @param rtr Send remote transmission request or data frame + * @param timeout Waiting for empty tx mailbox timeout in ms or K_FOREVER + * + * @retval 0 If successful. + * @retval -EIO General input / output error. + * @retval -EINVAL if length > 8. + */ +static inline int can_write(struct device *dev, const u8_t *data, u8_t length, + u32_t id, enum can_rtr rtr, s32_t timeout) +{ + struct zcan_frame msg; + + if (length > 8) { + return -EINVAL; + } + + if (id > CAN_MAX_STD_ID) { + msg.id_type = CAN_EXTENDED_IDENTIFIER; + msg.ext_id = id & CAN_EXT_ID_MASK; + } else { + msg.id_type = CAN_STANDARD_IDENTIFIER; + msg.std_id = id; + } + + msg.dlc = length; + msg.rtr = rtr; + memcpy(msg.data, data, length); + + return can_send(dev, &msg, timeout, NULL, NULL); +} + +/** + * @brief Attach a CAN work queue to a single or group of identifiers. + * + * This routine attaches a work queue to identifiers specified by a filter. + * Whenever the filter matches, the message is pushed to the buffer + * of the zcan_work structure and the work element is put to the workqueue. + * If a message passes more than one filter the priority of the match + * is hardware dependent. + * A CAN work queue can be attached to more than one filter. + * The work queue must be initialized before and the caller must have + * appropriate permissions on it. + * + * @param dev Pointer to the device structure for the driver instance. + * @param work_q Pointer to the already initialized work queue. + * @param work Pointer to a zcan_work. The work will be initialized. + * @param callback This function is called by workq whenever a message arrives. + * @param callback_arg Is passed to the callback when called. + * @param filter Pointer to a zcan_filter structure defining the id + * filtering. + * + * @retval filter id on success. + * @retval CAN_NO_FREE_FILTER if there is no filter left. + */ +int can_attach_workq(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); + +/** + * @brief Attach a message queue to a single or group of identifiers. + * + * This routine attaches a message queue to identifiers specified by + * a filter. Whenever the filter matches, the message is pushed to the queue + * If a message passes more than one filter the priority of the match + * is hardware dependent. + * A message queue can be attached to more than one filter. + * The message queue must me initialized before, and the caller must have + * appropriate permissions on it. + * + * @param dev Pointer to the device structure for the driver instance. + * @param msg_q Pointer to the already initialized message queue. + * @param filter Pointer to a zcan_filter structure defining the id + * filtering. + * + * @retval filter id on success. + * @retval CAN_NO_FREE_FILTER if there is no filter left. + */ +__syscall int can_attach_msgq(struct device *dev, struct k_msgq *msg_q, + const struct zcan_filter *filter); + +/** + * @brief Attach an isr callback function to a single or group of identifiers. + * + * This routine attaches an isr callback to identifiers specified by + * a filter. Whenever the filter matches, the callback function is called + * with isr context. + * If a message passes more than one filter the priority of the match + * is hardware dependent. + * A callback function can be attached to more than one filter. + * * + * @param dev Pointer to the device structure for the driver instance. + * @param isr Callback function pointer. + * @param callback_arg This will be passed whenever the isr is called. + * @param filter Pointer to a zcan_filter structure defining the id + * filtering. + * + * @retval filter id on success. + * @retval CAN_NO_FREE_FILTER if there is no filter left. + */ +static inline int can_attach_isr(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->driver_api; + + return api->attach_isr(dev, isr, callback_arg, filter); +} + +/** + * @brief Detach an isr or message queue from the identifier filtering. + * + * This routine detaches an isr callback or message queue from the identifier + * filtering. + * * + * @param dev Pointer to the device structure for the driver instance. + * @param filter_id filter id returned by can_attach_isr or can_attach_msgq. + * + * @retval none + */ +__syscall void can_detach(struct device *dev, int filter_id); + +static inline void z_impl_can_detach(struct device *dev, int filter_id) +{ + const struct can_driver_api *api = + (const struct can_driver_api *)dev->driver_api; + + return api->detach(dev, filter_id); +} + +/** + * @brief Configure operation of a host controller. + * + * @param dev Pointer to the device structure for the driver instance. + * @param mode Operation mode + * @param bitrate bus-speed in Baud/s + * + * @retval 0 If successful. + * @retval -EIO General input / output error, failed to configure device. + */ +__syscall int can_configure(struct device *dev, enum can_mode mode, + u32_t bitrate); + +static inline int z_impl_can_configure(struct device *dev, enum can_mode mode, + u32_t bitrate) +{ + const struct can_driver_api *api = + (const struct can_driver_api *)dev->driver_api; + + return api->configure(dev, mode, bitrate); +} + +/** + * @brief Converter that translates between can_frame and zcan_frame structs. + * + * @param frame Pointer to can_frame struct. + * @param zframe Pointer to zcan_frame struct. + */ +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->ext_id = frame->can_id & BIT_MASK(29); + zframe->dlc = frame->can_dlc; + memcpy(zframe->data, frame->data, sizeof(zframe->data)); +} + +/** + * @brief Converter that translates between zcan_frame and can_frame structs. + * + * @param zframe Pointer to zcan_frame struct. + * @param frame Pointer to can_frame struct. + */ +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->ext_id; + frame->can_dlc = zframe->dlc; + memcpy(frame->data, zframe->data, sizeof(frame->data)); +} + +/** + * @brief Converter that translates between can_filter and zcan_frame_filter + * structs. + * + * @param filter Pointer to can_filter struct. + * @param zfilter Pointer to zcan_frame_filter struct. + */ +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->ext_id = filter->can_id & BIT_MASK(29); + zfilter->rtr_mask = (filter->can_mask & BIT(30)) >> 30; + zfilter->ext_id_mask = filter->can_mask & BIT_MASK(29); +} + +/** + * @brief Converter that translates between zcan_filter and can_filter + * structs. + * + * @param zfilter Pointer to zcan_filter struct. + * @param filter Pointer to can_filter struct. + */ +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->ext_id; + filter->can_mask = (zfilter->rtr_mask << 30) | + (zfilter->id_type << 31) | zfilter->ext_id_mask; +} + +#ifdef __cplusplus +} +#endif +/** + * @} + */ +#include + +#endif /* ZEPHYR_INCLUDE_DRIVERS_CAN_H_ */ diff --git a/include/net/socket_can.h b/include/net/socket_can.h index 2eaceac32f2..ba1f3e4dcd9 100644 --- a/include/net/socket_can.h +++ b/include/net/socket_can.h @@ -20,7 +20,7 @@ extern "C" { #include #include #include -#include +#include /** * @brief Socket CAN library diff --git a/samples/drivers/CAN/src/main.c b/samples/drivers/CAN/src/main.c index 65ece21e0e6..3daf5ed8e70 100644 --- a/samples/drivers/CAN/src/main.c +++ b/samples/drivers/CAN/src/main.c @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #define TX_THREAD_STACK_SIZE 512 diff --git a/tests/drivers/can/api/src/main.c b/tests/drivers/can/api/src/main.c index a6550a3e411..69970f09ee3 100644 --- a/tests/drivers/can/api/src/main.c +++ b/tests/drivers/can/api/src/main.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include diff --git a/tests/drivers/can/stm32/src/main.c b/tests/drivers/can/stm32/src/main.c index eceeb71b40b..7591d5834da 100644 --- a/tests/drivers/can/stm32/src/main.c +++ b/tests/drivers/can/stm32/src/main.c @@ -3,7 +3,7 @@ * * SPDX-License-Identifier: Apache-2.0 */ -#include +#include #include #include diff --git a/tests/subsys/can/frame/src/main.c b/tests/subsys/can/frame/src/main.c index 9ffbfd88e21..498f886cfbd 100644 --- a/tests/subsys/can/frame/src/main.c +++ b/tests/subsys/can/frame/src/main.c @@ -12,7 +12,7 @@ LOG_MODULE_REGISTER(can_test, LOG_LEVEL_ERR); #include #include #include -#include +#include #include