drivers: can: Extend CAN API for bus-state management.
This commit extends the CAN API with the following functions: - can_get_state - can_recover - can_register_state_change_isr This functions can be used to get the error-counters and the state of the CAN controller. The recover function can be used to recover from bus-off state when automatic recovery is disabled. Signed-off-by: Alexander Wachter <alexander.wachter@student.tugraz.at>
This commit is contained in:
parent
1f046d86a0
commit
c0da8a7901
10 changed files with 598 additions and 56 deletions
|
@ -98,6 +98,17 @@ enum can_mode {
|
|||
CAN_SILENT_LOOPBACK_MODE
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief can_state enum
|
||||
* Defines the possible states of the CAN bus
|
||||
*/
|
||||
enum can_state {
|
||||
CAN_ERROR_ACTIVE,
|
||||
CAN_ERROR_PASSIVE,
|
||||
CAN_BUS_OFF,
|
||||
CAN_BUS_UNKNOWN
|
||||
};
|
||||
|
||||
/*
|
||||
* Controller Area Network Identifier structure for Linux compatibility.
|
||||
*
|
||||
|
@ -212,6 +223,16 @@ struct zcan_filter {
|
|||
};
|
||||
} __packed;
|
||||
|
||||
/**
|
||||
* @brief can bus error count structure
|
||||
*
|
||||
* Used to pass the bus error counters to userspace
|
||||
*/
|
||||
struct can_bus_err_cnt {
|
||||
u8_t tx_err_cnt;
|
||||
u8_t rx_err_cnt;
|
||||
};
|
||||
|
||||
/**
|
||||
* @typedef can_tx_callback_t
|
||||
* @brief Define the application callback handler function signature
|
||||
|
@ -231,6 +252,16 @@ typedef void (*can_tx_callback_t)(u32_t error_flags, void *arg);
|
|||
*/
|
||||
typedef void (*can_rx_callback_t)(struct zcan_frame *msg, void *arg);
|
||||
|
||||
/**
|
||||
* @typedef can_state_change_isr_t
|
||||
* @brief Defines the state change isr handler function signature
|
||||
*
|
||||
* @param state state of the node
|
||||
* @param err_cnt struct with the error counter values
|
||||
*/
|
||||
typedef void(*can_state_change_isr_t)(enum can_state state,
|
||||
struct can_bus_err_cnt err_cnt);
|
||||
|
||||
typedef int (*can_configure_t)(struct device *dev, enum can_mode mode,
|
||||
u32_t bitrate);
|
||||
|
||||
|
@ -248,6 +279,14 @@ typedef int (*can_attach_isr_t)(struct device *dev, can_rx_callback_t isr,
|
|||
|
||||
typedef void (*can_detach_t)(struct device *dev, int filter_id);
|
||||
|
||||
typedef int (*can_recover_t)(struct device *dev, s32_t timeout);
|
||||
|
||||
typedef enum can_state (*can_get_state_t)(struct device *dev,
|
||||
struct can_bus_err_cnt *err_cnt);
|
||||
|
||||
typedef void(*can_register_state_change_isr_t)(struct device *dev,
|
||||
can_state_change_isr_t isr);
|
||||
|
||||
#ifndef CONFIG_CAN_WORKQ_FRAMES_BUF_CNT
|
||||
#define CONFIG_CAN_WORKQ_FRAMES_BUF_CNT 4
|
||||
#endif
|
||||
|
@ -275,6 +314,12 @@ struct can_driver_api {
|
|||
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;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -477,6 +522,74 @@ static inline int z_impl_can_configure(struct device *dev, enum can_mode mode,
|
|||
return api->configure(dev, mode, bitrate);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get current state
|
||||
*
|
||||
* Returns the actual state of the CAN controller.
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance.
|
||||
* @param err_cnt Pointer to the err_cnt destination structure or NULL.
|
||||
*
|
||||
* @retval state
|
||||
*/
|
||||
__syscall enum can_state can_get_state(struct device *dev,
|
||||
struct can_bus_err_cnt *err_cnt);
|
||||
|
||||
static inline
|
||||
enum can_state z_impl_can_get_state(struct device *dev,
|
||||
struct can_bus_err_cnt *err_cnt)
|
||||
{
|
||||
const struct can_driver_api *api = dev->driver_api;
|
||||
|
||||
return api->get_state(dev, err_cnt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Recover from bus-off state
|
||||
*
|
||||
* Recover the CAN controller from bus-off state to error-active state.
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance.
|
||||
* @param timeout Timeout for waiting for the recovery.
|
||||
*
|
||||
* @retval 0 on success.
|
||||
* @retval CAN_TIMEOUT on timeout.
|
||||
*/
|
||||
#ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
|
||||
__syscall int can_recover(struct device *dev, s32_t timeout);
|
||||
|
||||
static inline int z_impl_can_recover(struct device *dev, s32_t timeout)
|
||||
{
|
||||
const struct can_driver_api *api = dev->driver_api;
|
||||
|
||||
return api->recover(dev, timeout);
|
||||
}
|
||||
#else
|
||||
/* This implementation prevents inking errors for auto recovery */
|
||||
static inline int z_impl_can_recover(struct device *dev, s32_t timeout)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
|
||||
|
||||
/**
|
||||
* @brief Register an ISR callback for state change interrupt
|
||||
*
|
||||
* Only one callback can be registered per controller.
|
||||
* Calling this function again, overrides the previos call.
|
||||
*
|
||||
* @param dev Pointer to the device structure for the driver instance.
|
||||
* @param isr Pointer to ISR
|
||||
*/
|
||||
static inline
|
||||
void can_register_state_change_isr(struct device *dev,
|
||||
can_state_change_isr_t isr)
|
||||
{
|
||||
const struct can_driver_api *api = dev->driver_api;
|
||||
|
||||
return api->register_state_change_isr(dev, isr);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Converter that translates between can_frame and zcan_frame structs.
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue