Commit 1b935223 authored by Alexander Wachter's avatar Alexander Wachter Committed by Anas Nashif
Browse files

drivers: can: Extend attach_isr with void *arg and pass to the isr cb



This commit extends the CAN api attach_isr function by an argument
that is passed to the isr callback.
With this extension it is possible to distinguish between filter matches
when they use the same callback.

Signed-off-by: default avatarAlexander Wachter <alexander.wachter@student.tugraz.at>
parent c4284ba7
Loading
Loading
Loading
Loading
+39 −59
Original line number Diff line number Diff line
@@ -177,41 +177,6 @@ const int mcp2515_set_mode(struct device *dev, u8_t mcp2515_mode)
	return 0;
}

static int mcp2515_attach(struct device *dev, const struct zcan_filter *filter,
			  void *response_ptr, u8_t is_type_msgq)
{
	struct mcp2515_data *dev_data = DEV_DATA(dev);
	int filter_idx = 0;

	__ASSERT(response_ptr != NULL, "response_ptr can not be null");

	k_mutex_lock(&dev_data->filter_mutex, K_FOREVER);

	/* find free filter */
	while ((BIT(filter_idx) & dev_data->filter_usage)
	       && (filter_idx < CONFIG_CAN_MCP2515_MAX_FILTER)) {
		filter_idx++;
	}

	/* setup filter */
	if (filter_idx < CONFIG_CAN_MCP2515_MAX_FILTER) {
		dev_data->filter_usage |= BIT(filter_idx);
		if (is_type_msgq) {
			dev_data->filter_response_type |= BIT(filter_idx);
		} else {
			dev_data->filter_response_type &= ~BIT(filter_idx);
		}
		dev_data->filter[filter_idx] = *filter;
		dev_data->filter_response[filter_idx] = response_ptr;
	} else {
		filter_idx = CAN_NO_FREE_FILTER;
	}

	k_mutex_unlock(&dev_data->filter_mutex);

	return filter_idx;
}

static int mcp2515_configure(struct device *dev, enum can_mode mode,
			     u32_t bitrate)
{
@@ -300,7 +265,7 @@ static int mcp2515_configure(struct device *dev, enum can_mode mode,
				mcp2515_convert_canmode_to_mcp2515mode(mode));
}

int mcp2515_send(struct device *dev, const struct zcan_frame *msg,
static int mcp2515_send(struct device *dev, const struct zcan_frame *msg,
		 s32_t timeout, can_tx_callback_t callback)
{
	struct mcp2515_data *dev_data = DEV_DATA(dev);
@@ -349,19 +314,41 @@ int mcp2515_send(struct device *dev, const struct zcan_frame *msg,
	return 0;
}

int mcp2515_attach_msgq(struct device *dev, struct k_msgq *msgq,
static int mcp2515_attach_isr(struct device *dev, can_rx_callback_t rx_cb,
			      void *cb_arg,
			      const struct zcan_filter *filter)
{
	return mcp2515_attach(dev, filter, (void *) msgq, 1);
	struct mcp2515_data *dev_data = DEV_DATA(dev);
	int filter_idx = 0;

	__ASSERT(rx_cb != NULL, "response_ptr can not be null");

	k_mutex_lock(&dev_data->filter_mutex, K_FOREVER);

	/* find free filter */
	while ((BIT(filter_idx) & dev_data->filter_usage)
	       && (filter_idx < CONFIG_CAN_MCP2515_MAX_FILTER)) {
		filter_idx++;
	}

int mcp2515_attach_isr(struct device *dev, can_rx_callback_t isr,
		       const struct zcan_filter *filter)
{
	return mcp2515_attach(dev, filter, (void *) isr, 0);
	/* setup filter */
	if (filter_idx < CONFIG_CAN_MCP2515_MAX_FILTER) {
		dev_data->filter_usage |= BIT(filter_idx);

		dev_data->filter[filter_idx] = *filter;
		dev_data->rx_cb[filter_idx] = rx_cb;
		dev_data->cb_arg[filter_idx] = cb_arg;

	} else {
		filter_idx = CAN_NO_FREE_FILTER;
	}

	k_mutex_unlock(&dev_data->filter_mutex);

	return filter_idx;
}

void mcp2515_detach(struct device *dev, int filter_nr)
static void mcp2515_detach(struct device *dev, int filter_nr)
{
	struct mcp2515_data *dev_data = DEV_DATA(dev);

@@ -398,6 +385,8 @@ static void mcp2515_rx_filter(struct device *dev, struct zcan_frame *msg)
{
	struct mcp2515_data *dev_data = DEV_DATA(dev);
	u8_t filter_idx = 0U;
	can_rx_callback_t callback;
	struct zcan_frame tmp_msg;

	k_mutex_lock(&dev_data->filter_mutex, K_FOREVER);

@@ -411,17 +400,11 @@ static void mcp2515_rx_filter(struct device *dev, struct zcan_frame *msg)
			continue; /* filter did not match */
		}

		if (dev_data->filter_response_type & BIT(filter_idx)) {
			struct k_msgq *msg_q =
				dev_data->filter_response[filter_idx];
		callback = dev_data->rx_cb[filter_idx];
		/*Make a temporary copy in case the user modifies the message*/
		tmp_msg = *msg;

			k_msgq_put(msg_q, msg, K_NO_WAIT);
		} else {
			can_rx_callback_t callback =
				dev_data->filter_response[filter_idx];

			callback(msg);
		}
		callback(&tmp_msg, dev_data->cb_arg[filter_idx]);
	}

	k_mutex_unlock(&dev_data->filter_mutex);
@@ -517,7 +500,6 @@ static void mcp2515_int_gpio_callback(struct device *dev,
static const struct can_driver_api can_api_funcs = {
	.configure = mcp2515_configure,
	.send = mcp2515_send,
	.attach_msgq = mcp2515_attach_msgq,
	.attach_isr = mcp2515_attach_isr,
	.detach = mcp2515_detach
};
@@ -601,8 +583,7 @@ static int mcp2515_init(struct device *dev)
			NULL, NULL, K_PRIO_COOP(dev_cfg->int_thread_priority),
			0, K_NO_WAIT);

	(void)memset(dev_data->filter_response, 0,
		     sizeof(dev_data->filter_response));
	(void)memset(dev_data->rx_cb, 0, sizeof(dev_data->rx_cb));
	(void)memset(dev_data->filter, 0, sizeof(dev_data->filter));

	ret = mcp2515_configure(dev, CAN_NORMAL_MODE, dev_cfg->bus_speed);
@@ -622,7 +603,6 @@ static struct mcp2515_data mcp2515_data_1 = {
	.tx_cb[2].cb = NULL,
	.tx_busy_map = 0U,
	.filter_usage = 0U,
	.filter_response_type = 0U,
};

static const struct mcp2515_config mcp2515_config_1 = {
+2 −2
Original line number Diff line number Diff line
@@ -46,8 +46,8 @@ struct mcp2515_data {
	/* filter data */
	struct k_mutex filter_mutex;
	u32_t filter_usage;
	u32_t filter_response_type;
	void *filter_response[CONFIG_CAN_MCP2515_MAX_FILTER];
	can_rx_callback_t rx_cb[CONFIG_CAN_MCP2515_MAX_FILTER];
	void *cb_arg[CONFIG_CAN_MCP2515_MAX_FILTER];
	struct zcan_filter filter[CONFIG_CAN_MCP2515_MAX_FILTER];
};

+13 −3
Original line number Diff line number Diff line
@@ -81,7 +81,7 @@ void can_stm32_rx_isr_handler(CAN_TypeDef *can, struct can_stm32_data *data)
			} else {
				can_rx_callback_t callback =
					data->rx_response[filter_match_index];
				callback(&msg);
				callback(&msg, data->cb_arg[filter_match_index]);
			}
		}

@@ -302,6 +302,8 @@ static int can_stm32_init(struct device *dev)
	data->filter_usage = (1ULL << CAN_MAX_NUMBER_OF_FILTERS) - 1ULL;
	(void)memset(data->rx_response, 0,
		     sizeof(void *) * CONFIG_CAN_MAX_FILTER);
	(void)memset(data->cb_arg, 0,
		     sizeof(void *) * CONFIG_CAN_MAX_FILTER);
	data->response_type = 0U;

	clock = device_get_binding(STM32_CLOCK_CONTROL_NAME);
@@ -713,6 +715,10 @@ static inline int can_stm32_set_filter(const struct zcan_filter *filter,
						start_index,
						shift_width);

			res |= can_stm32_shift_arr(device_data->cb_arg,
						   start_index,
						   shift_width);

			if (filter_index_new >= CONFIG_CAN_MAX_FILTER || res) {
				LOG_INF("No space for a new filter!");
				filter_nr = CAN_NO_FREE_FILTER;
@@ -748,6 +754,7 @@ done:


static inline int can_stm32_attach(struct device *dev, void *response_ptr,
				   void *cb_arg,
				   const struct zcan_filter *filter,
				   int *filter_index)
{
@@ -760,6 +767,7 @@ static inline int can_stm32_attach(struct device *dev, void *response_ptr,
	filter_nr = can_stm32_set_filter(filter, data, can, &filter_index_tmp);
	if (filter_nr != CAN_NO_FREE_FILTER) {
		data->rx_response[filter_index_tmp] = response_ptr;
		data->cb_arg[filter_index_tmp] = cb_arg;
	}

	*filter_index = filter_index_tmp;
@@ -774,13 +782,14 @@ int can_stm32_attach_msgq(struct device *dev, struct k_msgq *msgq,
	struct can_stm32_data *data = DEV_DATA(dev);

	k_mutex_lock(&data->set_filter_mutex, K_FOREVER);
	filter_nr = can_stm32_attach(dev, msgq, filter, &filter_index);
	filter_nr = can_stm32_attach(dev, msgq, NULL, filter, &filter_index);
	data->response_type |= (1ULL << filter_index);
	k_mutex_unlock(&data->set_filter_mutex);
	return filter_nr;
}

int can_stm32_attach_isr(struct device *dev, can_rx_callback_t isr,
			 void *cb_arg,
			 const struct zcan_filter *filter)
{
	struct can_stm32_data *data = DEV_DATA(dev);
@@ -788,7 +797,7 @@ int can_stm32_attach_isr(struct device *dev, can_rx_callback_t isr,
	int filter_index;

	k_mutex_lock(&data->set_filter_mutex, K_FOREVER);
	filter_nr = can_stm32_attach(dev, isr, filter, &filter_index);
	filter_nr = can_stm32_attach(dev, isr, cb_arg, filter, &filter_index);
	data->response_type &= ~(1ULL << filter_index);
	k_mutex_unlock(&data->set_filter_mutex);
	return filter_nr;
@@ -839,6 +848,7 @@ void can_stm32_detach(struct device *dev, int filter_nr)

	can->FMR &= ~(CAN_FMR_FINIT);
	data->rx_response[filter_index] = NULL;
	data->cb_arg[filter_index] = NULL;
	data->response_type &= ~(1ULL << filter_index);

	k_mutex_unlock(&data->set_filter_mutex);
+1 −0
Original line number Diff line number Diff line
@@ -64,6 +64,7 @@ struct can_stm32_data {
	u64_t filter_usage;
	u64_t response_type;
	void *rx_response[CONFIG_CAN_MAX_FILTER];
	void *cb_arg[CONFIG_CAN_MAX_FILTER];
};

struct can_stm32_config {
+11 −7
Original line number Diff line number Diff line
@@ -218,9 +218,10 @@ typedef void (*can_tx_callback_t)(u32_t error_flags);
 * @brief Define the application callback handler function signature
 *        for receiving.
 *
 * @param received message
 * @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);
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);
@@ -233,6 +234,7 @@ 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);
@@ -363,6 +365,7 @@ static inline int z_impl_can_attach_msgq(struct device *dev,
 * *
 * @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.
 *
@@ -371,12 +374,13 @@ static inline int z_impl_can_attach_msgq(struct device *dev,
 */
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, filter);
	return api->attach_isr(dev, isr, callback_arg, filter);
}

/**
Loading