1 /*
2  * Copyright (c) 2018 Karsten Koenig
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT microchip_mcp2515
8 
9 #include <zephyr/kernel.h>
10 #include <zephyr/device.h>
11 #include <zephyr/drivers/can/transceiver.h>
12 #include <zephyr/drivers/spi.h>
13 #include <zephyr/drivers/gpio.h>
14 #include <zephyr/logging/log.h>
15 
16 LOG_MODULE_REGISTER(can_mcp2515, CONFIG_CAN_LOG_LEVEL);
17 
18 #include "can_mcp2515.h"
19 
20 /* Timeout for changing mode */
21 #define MCP2515_MODE_CHANGE_TIMEOUT_USEC 1000
22 #define MCP2515_MODE_CHANGE_RETRIES      100
23 #define MCP2515_MODE_CHANGE_DELAY	    \
24 	K_USEC(MCP2515_MODE_CHANGE_TIMEOUT_USEC / MCP2515_MODE_CHANGE_RETRIES)
25 
mcp2515_cmd_soft_reset(const struct device * dev)26 static int mcp2515_cmd_soft_reset(const struct device *dev)
27 {
28 	const struct mcp2515_config *dev_cfg = dev->config;
29 
30 	uint8_t cmd_buf[] = { MCP2515_OPCODE_RESET };
31 
32 	const struct spi_buf tx_buf = {
33 		.buf = cmd_buf, .len = sizeof(cmd_buf),
34 	};
35 	const struct spi_buf_set tx = {
36 		.buffers = &tx_buf, .count = 1U
37 	};
38 
39 	return spi_write_dt(&dev_cfg->bus, &tx);
40 }
41 
mcp2515_cmd_bit_modify(const struct device * dev,uint8_t reg_addr,uint8_t mask,uint8_t data)42 static int mcp2515_cmd_bit_modify(const struct device *dev, uint8_t reg_addr,
43 				  uint8_t mask,
44 				  uint8_t data)
45 {
46 	const struct mcp2515_config *dev_cfg = dev->config;
47 
48 	uint8_t cmd_buf[] = { MCP2515_OPCODE_BIT_MODIFY, reg_addr, mask, data };
49 
50 	const struct spi_buf tx_buf = {
51 		.buf = cmd_buf, .len = sizeof(cmd_buf),
52 	};
53 	const struct spi_buf_set tx = {
54 		.buffers = &tx_buf, .count = 1U
55 	};
56 
57 	return spi_write_dt(&dev_cfg->bus, &tx);
58 }
59 
mcp2515_cmd_write_reg(const struct device * dev,uint8_t reg_addr,uint8_t * buf_data,uint8_t buf_len)60 static int mcp2515_cmd_write_reg(const struct device *dev, uint8_t reg_addr,
61 				 uint8_t *buf_data, uint8_t buf_len)
62 {
63 	const struct mcp2515_config *dev_cfg = dev->config;
64 
65 	uint8_t cmd_buf[] = { MCP2515_OPCODE_WRITE, reg_addr };
66 
67 	struct spi_buf tx_buf[] = {
68 		{ .buf = cmd_buf, .len = sizeof(cmd_buf) },
69 		{ .buf = buf_data, .len = buf_len }
70 	};
71 	const struct spi_buf_set tx = {
72 		.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)
73 	};
74 
75 	return spi_write_dt(&dev_cfg->bus, &tx);
76 }
77 
78 /*
79  * Load TX buffer instruction
80  *
81  * When loading a transmit buffer, reduces the overhead of a normal WRITE
82  * command by placing the Address Pointer at one of six locations, as
83  * selected by parameter abc.
84  *
85  *   0: TX Buffer 0, Start at TXB0SIDH (0x31)
86  *   1: TX Buffer 0, Start at TXB0D0 (0x36)
87  *   2: TX Buffer 1, Start at TXB1SIDH (0x41)
88  *   3: TX Buffer 1, Start at TXB1D0 (0x46)
89  *   4: TX Buffer 2, Start at TXB2SIDH (0x51)
90  *   5: TX Buffer 2, Start at TXB2D0 (0x56)
91  */
mcp2515_cmd_load_tx_buffer(const struct device * dev,uint8_t abc,uint8_t * buf_data,uint8_t buf_len)92 static int mcp2515_cmd_load_tx_buffer(const struct device *dev, uint8_t abc,
93 				      uint8_t *buf_data, uint8_t buf_len)
94 {
95 	const struct mcp2515_config *dev_cfg = dev->config;
96 
97 	__ASSERT(abc <= 5, "abc <= 5");
98 
99 	uint8_t cmd_buf[] = { MCP2515_OPCODE_LOAD_TX_BUFFER | abc };
100 
101 	struct spi_buf tx_buf[] = {
102 		{ .buf = cmd_buf, .len = sizeof(cmd_buf) },
103 		{ .buf = buf_data, .len = buf_len }
104 	};
105 	const struct spi_buf_set tx = {
106 		.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)
107 	};
108 
109 	return spi_write_dt(&dev_cfg->bus, &tx);
110 }
111 
112 /*
113  * Request-to-Send Instruction
114  *
115  * Parameter nnn is the combination of bits at positions 0, 1 and 2 in the RTS
116  * opcode that respectively initiate transmission for buffers TXB0, TXB1 and
117  * TXB2.
118  */
mcp2515_cmd_rts(const struct device * dev,uint8_t nnn)119 static int mcp2515_cmd_rts(const struct device *dev, uint8_t nnn)
120 {
121 	const struct mcp2515_config *dev_cfg = dev->config;
122 
123 	__ASSERT(nnn < BIT(MCP2515_TX_CNT), "nnn < BIT(MCP2515_TX_CNT)");
124 
125 	uint8_t cmd_buf[] = { MCP2515_OPCODE_RTS | nnn };
126 
127 	struct spi_buf tx_buf[] = {
128 		{ .buf = cmd_buf, .len = sizeof(cmd_buf) }
129 	};
130 	const struct spi_buf_set tx = {
131 		.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)
132 	};
133 
134 	return spi_write_dt(&dev_cfg->bus, &tx);
135 }
136 
mcp2515_cmd_read_reg(const struct device * dev,uint8_t reg_addr,uint8_t * buf_data,uint8_t buf_len)137 static int mcp2515_cmd_read_reg(const struct device *dev, uint8_t reg_addr,
138 				uint8_t *buf_data, uint8_t buf_len)
139 {
140 	const struct mcp2515_config *dev_cfg = dev->config;
141 
142 	uint8_t cmd_buf[] = { MCP2515_OPCODE_READ, reg_addr };
143 
144 	struct spi_buf tx_buf[] = {
145 		{ .buf = cmd_buf, .len = sizeof(cmd_buf) },
146 		{ .buf = NULL, .len = buf_len }
147 	};
148 	const struct spi_buf_set tx = {
149 		.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)
150 	};
151 	struct spi_buf rx_buf[] = {
152 		{ .buf = NULL, .len = sizeof(cmd_buf) },
153 		{ .buf = buf_data, .len = buf_len }
154 	};
155 	const struct spi_buf_set rx = {
156 		.buffers = rx_buf, .count = ARRAY_SIZE(rx_buf)
157 	};
158 
159 	return spi_transceive_dt(&dev_cfg->bus, &tx, &rx);
160 }
161 
162 /*
163  * Read RX Buffer instruction
164  *
165  * When reading a receive buffer, reduces the overhead of a normal READ
166  * command by placing the Address Pointer at one of four locations selected by
167  * parameter nm:
168  *   0: Receive Buffer 0, Start at RXB0SIDH (0x61)
169  *   1: Receive Buffer 0, Start at RXB0D0 (0x66)
170  *   2: Receive Buffer 1, Start at RXB1SIDH (0x71)
171  *   3: Receive Buffer 1, Start at RXB1D0 (0x76)
172  */
mcp2515_cmd_read_rx_buffer(const struct device * dev,uint8_t nm,uint8_t * buf_data,uint8_t buf_len)173 static int mcp2515_cmd_read_rx_buffer(const struct device *dev, uint8_t nm,
174 				      uint8_t *buf_data, uint8_t buf_len)
175 {
176 	const struct mcp2515_config *dev_cfg = dev->config;
177 
178 	__ASSERT(nm <= 0x03, "nm <= 0x03");
179 
180 	uint8_t cmd_buf[] = { MCP2515_OPCODE_READ_RX_BUFFER | (nm << 1) };
181 
182 	struct spi_buf tx_buf[] = {
183 		{ .buf = cmd_buf, .len = sizeof(cmd_buf) },
184 		{ .buf = NULL, .len = buf_len }
185 	};
186 	const struct spi_buf_set tx = {
187 		.buffers = tx_buf, .count = ARRAY_SIZE(tx_buf)
188 	};
189 	struct spi_buf rx_buf[] = {
190 		{ .buf = NULL, .len = sizeof(cmd_buf) },
191 		{ .buf = buf_data, .len = buf_len }
192 	};
193 	const struct spi_buf_set rx = {
194 		.buffers = rx_buf, .count = ARRAY_SIZE(rx_buf)
195 	};
196 
197 	return spi_transceive_dt(&dev_cfg->bus, &tx, &rx);
198 }
199 
mcp2515_convert_canframe_to_mcp2515frame(const struct can_frame * source,uint8_t * target)200 static void mcp2515_convert_canframe_to_mcp2515frame(const struct can_frame
201 						     *source, uint8_t *target)
202 {
203 	uint8_t rtr;
204 	uint8_t dlc;
205 	uint8_t data_idx;
206 
207 	if ((source->flags & CAN_FRAME_IDE) != 0) {
208 		target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 21;
209 		target[MCP2515_FRAME_OFFSET_SIDL] =
210 			(((source->id >> 18) & 0x07) << 5) | (BIT(3)) |
211 			((source->id >> 16) & 0x03);
212 		target[MCP2515_FRAME_OFFSET_EID8] = source->id >> 8;
213 		target[MCP2515_FRAME_OFFSET_EID0] = source->id;
214 	} else {
215 		target[MCP2515_FRAME_OFFSET_SIDH] = source->id >> 3;
216 		target[MCP2515_FRAME_OFFSET_SIDL] =
217 			(source->id & 0x07) << 5;
218 	}
219 
220 	rtr = (source->flags & CAN_FRAME_RTR) != 0 ? BIT(6) : 0;
221 	dlc = (source->dlc) & 0x0F;
222 
223 	target[MCP2515_FRAME_OFFSET_DLC] = rtr | dlc;
224 
225 	if (rtr == 0U) {
226 		for (data_idx = 0U; data_idx < dlc; data_idx++) {
227 			target[MCP2515_FRAME_OFFSET_D0 + data_idx] =
228 				source->data[data_idx];
229 		}
230 	}
231 }
232 
mcp2515_convert_mcp2515frame_to_canframe(const uint8_t * source,struct can_frame * target)233 static void mcp2515_convert_mcp2515frame_to_canframe(const uint8_t *source,
234 						     struct can_frame *target)
235 {
236 	uint8_t data_idx;
237 
238 	memset(target, 0, sizeof(*target));
239 
240 	if (source[MCP2515_FRAME_OFFSET_SIDL] & BIT(3)) {
241 		target->flags |= CAN_FRAME_IDE;
242 		target->id =
243 			(source[MCP2515_FRAME_OFFSET_SIDH] << 21) |
244 			((source[MCP2515_FRAME_OFFSET_SIDL] >> 5) << 18) |
245 			((source[MCP2515_FRAME_OFFSET_SIDL] & 0x03) << 16) |
246 			(source[MCP2515_FRAME_OFFSET_EID8] << 8) |
247 			source[MCP2515_FRAME_OFFSET_EID0];
248 	} else {
249 		target->id = (source[MCP2515_FRAME_OFFSET_SIDH] << 3) |
250 				 (source[MCP2515_FRAME_OFFSET_SIDL] >> 5);
251 	}
252 
253 	target->dlc = source[MCP2515_FRAME_OFFSET_DLC] & 0x0F;
254 
255 	if ((source[MCP2515_FRAME_OFFSET_DLC] & BIT(6)) != 0) {
256 		target->flags |= CAN_FRAME_RTR;
257 	} else {
258 		for (data_idx = 0U; data_idx < target->dlc; data_idx++) {
259 			target->data[data_idx] = source[MCP2515_FRAME_OFFSET_D0 +
260 							data_idx];
261 		}
262 	}
263 }
264 
mcp2515_set_mode_int(const struct device * dev,uint8_t mcp2515_mode)265 const int mcp2515_set_mode_int(const struct device *dev, uint8_t mcp2515_mode)
266 {
267 	int retries = MCP2515_MODE_CHANGE_RETRIES;
268 	uint8_t canstat;
269 
270 	mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_CANCTRL,
271 			       MCP2515_CANCTRL_MODE_MASK,
272 			       mcp2515_mode << MCP2515_CANCTRL_MODE_POS);
273 	mcp2515_cmd_read_reg(dev, MCP2515_ADDR_CANSTAT, &canstat, 1);
274 
275 	while (((canstat & MCP2515_CANSTAT_MODE_MASK) >> MCP2515_CANSTAT_MODE_POS)
276 		!= mcp2515_mode) {
277 		if (--retries < 0) {
278 			LOG_ERR("Timeout trying to set MCP2515 operation mode");
279 			return -EIO;
280 		}
281 
282 		k_sleep(MCP2515_MODE_CHANGE_DELAY);
283 		mcp2515_cmd_read_reg(dev, MCP2515_ADDR_CANSTAT, &canstat, 1);
284 	}
285 
286 	return 0;
287 }
288 
mcp2515_tx_done(const struct device * dev,uint8_t tx_idx,int status)289 static void mcp2515_tx_done(const struct device *dev, uint8_t tx_idx, int status)
290 {
291 	struct mcp2515_data *dev_data = dev->data;
292 	can_tx_callback_t callback = dev_data->tx_cb[tx_idx].cb;
293 
294 	if (callback != NULL) {
295 		callback(dev, status, dev_data->tx_cb[tx_idx].cb_arg);
296 		dev_data->tx_cb[tx_idx].cb = NULL;
297 
298 		k_mutex_lock(&dev_data->mutex, K_FOREVER);
299 		dev_data->tx_busy_map &= ~BIT(tx_idx);
300 		k_mutex_unlock(&dev_data->mutex);
301 		k_sem_give(&dev_data->tx_sem);
302 	}
303 }
304 
mcp2515_get_core_clock(const struct device * dev,uint32_t * rate)305 static int mcp2515_get_core_clock(const struct device *dev, uint32_t *rate)
306 {
307 	const struct mcp2515_config *dev_cfg = dev->config;
308 
309 	*rate = dev_cfg->osc_freq / 2;
310 	return 0;
311 }
312 
mcp2515_get_max_filters(const struct device * dev,bool ide)313 static int mcp2515_get_max_filters(const struct device *dev, bool ide)
314 {
315 	ARG_UNUSED(ide);
316 
317 	return CONFIG_CAN_MAX_FILTER;
318 }
319 
mcp2515_set_timing(const struct device * dev,const struct can_timing * timing)320 static int mcp2515_set_timing(const struct device *dev,
321 			      const struct can_timing *timing)
322 {
323 	struct mcp2515_data *dev_data = dev->data;
324 	int ret;
325 
326 	if (!timing) {
327 		return -EINVAL;
328 	}
329 
330 	if (dev_data->common.started) {
331 		return -EBUSY;
332 	}
333 
334 	/* CNF3, CNF2, CNF1, CANINTE */
335 	uint8_t config_buf[4];
336 
337 	/* CNF1; SJW<7:6> | BRP<5:0> */
338 	__ASSERT(timing->prescaler > 0, "Prescaler should be bigger than zero");
339 	uint8_t brp = timing->prescaler - 1;
340 	uint8_t sjw = (timing->sjw - 1) << 6;
341 	uint8_t cnf1 = sjw | brp;
342 
343 	/* CNF2; BTLMODE<7>|SAM<6>|PHSEG1<5:3>|PRSEG<2:0> */
344 	const uint8_t btlmode = 1 << 7;
345 	const uint8_t sam = 0 << 6;
346 	const uint8_t phseg1 = (timing->phase_seg1 - 1) << 3;
347 	const uint8_t prseg = (timing->prop_seg - 1);
348 
349 	const uint8_t cnf2 = btlmode | sam | phseg1 | prseg;
350 
351 	/* CNF3; SOF<7>|WAKFIL<6>|UND<5:3>|PHSEG2<2:0> */
352 	const uint8_t sof = 0 << 7;
353 	const uint8_t wakfil = 0 << 6;
354 	const uint8_t und = 0 << 3;
355 	const uint8_t phseg2 = (timing->phase_seg2 - 1);
356 
357 	const uint8_t cnf3 = sof | wakfil | und | phseg2;
358 
359 	const uint8_t caninte = MCP2515_INTE_RX0IE | MCP2515_INTE_RX1IE |
360 			     MCP2515_INTE_TX0IE | MCP2515_INTE_TX1IE |
361 			     MCP2515_INTE_TX2IE | MCP2515_INTE_ERRIE;
362 
363 	/* Receive everything, filtering done in driver, RXB0 roll over into
364 	 * RXB1 */
365 	const uint8_t rx0_ctrl = BIT(6) | BIT(5) | BIT(2);
366 	const uint8_t rx1_ctrl = BIT(6) | BIT(5);
367 
368 	config_buf[0] = cnf3;
369 	config_buf[1] = cnf2;
370 	config_buf[2] = cnf1;
371 	config_buf[3] = caninte;
372 
373 	k_mutex_lock(&dev_data->mutex, K_FOREVER);
374 
375 	ret = mcp2515_cmd_write_reg(dev, MCP2515_ADDR_CNF3, config_buf,
376 				    sizeof(config_buf));
377 	if (ret < 0) {
378 		LOG_ERR("Failed to write the configuration [%d]", ret);
379 		goto done;
380 	}
381 
382 	ret = mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_RXB0CTRL, rx0_ctrl,
383 				     rx0_ctrl);
384 	if (ret < 0) {
385 		LOG_ERR("Failed to write RXB0CTRL [%d]", ret);
386 		goto done;
387 	}
388 
389 	ret = mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_RXB1CTRL, rx1_ctrl,
390 				     rx1_ctrl);
391 	if (ret < 0) {
392 		LOG_ERR("Failed to write RXB1CTRL [%d]", ret);
393 		goto done;
394 	}
395 
396 done:
397 	k_mutex_unlock(&dev_data->mutex);
398 	return ret;
399 }
400 
mcp2515_get_capabilities(const struct device * dev,can_mode_t * cap)401 static int mcp2515_get_capabilities(const struct device *dev, can_mode_t *cap)
402 {
403 	ARG_UNUSED(dev);
404 
405 	*cap = CAN_MODE_NORMAL | CAN_MODE_LISTENONLY | CAN_MODE_LOOPBACK;
406 
407 	return 0;
408 }
409 
mcp2515_start(const struct device * dev)410 static int mcp2515_start(const struct device *dev)
411 {
412 	const struct mcp2515_config *dev_cfg = dev->config;
413 	struct mcp2515_data *dev_data = dev->data;
414 	int ret;
415 
416 	if (dev_data->common.started) {
417 		return -EALREADY;
418 	}
419 
420 	if (dev_cfg->common.phy != NULL) {
421 		ret = can_transceiver_enable(dev_cfg->common.phy, dev_data->common.mode);
422 		if (ret != 0) {
423 			LOG_ERR("Failed to enable CAN transceiver [%d]", ret);
424 			return ret;
425 		}
426 	}
427 
428 	CAN_STATS_RESET(dev);
429 
430 	k_mutex_lock(&dev_data->mutex, K_FOREVER);
431 
432 	ret = mcp2515_set_mode_int(dev, dev_data->mcp2515_mode);
433 	if (ret < 0) {
434 		LOG_ERR("Failed to set the mode [%d]", ret);
435 
436 		if (dev_cfg->common.phy != NULL) {
437 			/* Attempt to disable the CAN transceiver in case of error */
438 			(void)can_transceiver_disable(dev_cfg->common.phy);
439 		}
440 	} else {
441 		dev_data->common.started = true;
442 	}
443 
444 	k_mutex_unlock(&dev_data->mutex);
445 
446 	return ret;
447 }
448 
mcp2515_stop(const struct device * dev)449 static int mcp2515_stop(const struct device *dev)
450 {
451 	const struct mcp2515_config *dev_cfg = dev->config;
452 	struct mcp2515_data *dev_data = dev->data;
453 	int ret;
454 	int i;
455 
456 	if (!dev_data->common.started) {
457 		return -EALREADY;
458 	}
459 
460 	k_mutex_lock(&dev_data->mutex, K_FOREVER);
461 
462 	/* Abort any pending transmissions before entering configuration mode */
463 	mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_TXB0CTRL,
464 			       MCP2515_TXBNCTRL_TXREQ_MASK, 0);
465 #if MCP2515_TX_CNT == 2
466 	mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_TXB1CTRL,
467 			       MCP2515_TXBNCTRL_TXREQ_MASK, 0);
468 #endif /*  MCP2515_TX_CNT == 2 */
469 #if MCP2515_TX_CNT == 3
470 	mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_TXB2CTRL,
471 			       MCP2515_TXBNCTRL_TXREQ_MASK, 0);
472 #endif /* MCP2515_TX_CNT == 3 */
473 
474 	ret = mcp2515_set_mode_int(dev, MCP2515_MODE_CONFIGURATION);
475 	if (ret < 0) {
476 		LOG_ERR("Failed to enter configuration mode [%d]", ret);
477 		k_mutex_unlock(&dev_data->mutex);
478 		return ret;
479 	}
480 
481 	dev_data->common.started = false;
482 
483 	k_mutex_unlock(&dev_data->mutex);
484 
485 	for (i = 0; i < MCP2515_TX_CNT; i++) {
486 		mcp2515_tx_done(dev, i, -ENETDOWN);
487 	}
488 
489 	if (dev_cfg->common.phy != NULL) {
490 		ret = can_transceiver_disable(dev_cfg->common.phy);
491 		if (ret != 0) {
492 			LOG_ERR("Failed to disable CAN transceiver [%d]", ret);
493 			return ret;
494 		}
495 	}
496 
497 	return 0;
498 }
499 
mcp2515_set_mode(const struct device * dev,can_mode_t mode)500 static int mcp2515_set_mode(const struct device *dev, can_mode_t mode)
501 {
502 	struct mcp2515_data *dev_data = dev->data;
503 
504 	if (dev_data->common.started) {
505 		return -EBUSY;
506 	}
507 
508 	switch (mode) {
509 	case CAN_MODE_NORMAL:
510 		dev_data->mcp2515_mode = MCP2515_MODE_NORMAL;
511 		break;
512 	case CAN_MODE_LISTENONLY:
513 		dev_data->mcp2515_mode = MCP2515_MODE_SILENT;
514 		break;
515 	case CAN_MODE_LOOPBACK:
516 		dev_data->mcp2515_mode = MCP2515_MODE_LOOPBACK;
517 		break;
518 	default:
519 		LOG_ERR("Unsupported CAN Mode %u", mode);
520 		return -ENOTSUP;
521 	}
522 
523 	dev_data->common.mode = mode;
524 
525 	return 0;
526 }
527 
mcp2515_send(const struct device * dev,const struct can_frame * frame,k_timeout_t timeout,can_tx_callback_t callback,void * user_data)528 static int mcp2515_send(const struct device *dev,
529 			const struct can_frame *frame,
530 			k_timeout_t timeout, can_tx_callback_t callback,
531 			void *user_data)
532 {
533 	struct mcp2515_data *dev_data = dev->data;
534 	uint8_t tx_idx = 0U;
535 	uint8_t abc;
536 	uint8_t nnn;
537 	uint8_t len;
538 	uint8_t tx_frame[MCP2515_FRAME_LEN];
539 
540 	if (frame->dlc > CAN_MAX_DLC) {
541 		LOG_ERR("DLC of %d exceeds maximum (%d)",
542 			frame->dlc, CAN_MAX_DLC);
543 		return -EINVAL;
544 	}
545 
546 	if ((frame->flags & ~(CAN_FRAME_IDE | CAN_FRAME_RTR)) != 0) {
547 		LOG_ERR("unsupported CAN frame flags 0x%02x", frame->flags);
548 		return -ENOTSUP;
549 	}
550 
551 	if (!dev_data->common.started) {
552 		return -ENETDOWN;
553 	}
554 
555 	if (k_sem_take(&dev_data->tx_sem, timeout) != 0) {
556 		return -EAGAIN;
557 	}
558 
559 	k_mutex_lock(&dev_data->mutex, K_FOREVER);
560 
561 	/* find a free tx slot */
562 	for (; tx_idx < MCP2515_TX_CNT; tx_idx++) {
563 		if ((BIT(tx_idx) & dev_data->tx_busy_map) == 0) {
564 			dev_data->tx_busy_map |= BIT(tx_idx);
565 			break;
566 		}
567 	}
568 
569 	k_mutex_unlock(&dev_data->mutex);
570 
571 	if (tx_idx == MCP2515_TX_CNT) {
572 		LOG_WRN("no free tx slot available");
573 		return -EIO;
574 	}
575 
576 	dev_data->tx_cb[tx_idx].cb = callback;
577 	dev_data->tx_cb[tx_idx].cb_arg = user_data;
578 
579 	mcp2515_convert_canframe_to_mcp2515frame(frame, tx_frame);
580 
581 	/* Address Pointer selection */
582 	abc = 2 * tx_idx;
583 
584 	/* Calculate minimum length to transfer */
585 	len = sizeof(tx_frame) - CAN_MAX_DLC + frame->dlc;
586 
587 	mcp2515_cmd_load_tx_buffer(dev, abc, tx_frame, len);
588 
589 	/* request tx slot transmission */
590 	nnn = BIT(tx_idx);
591 	mcp2515_cmd_rts(dev, nnn);
592 
593 	return 0;
594 }
595 
mcp2515_add_rx_filter(const struct device * dev,can_rx_callback_t rx_cb,void * cb_arg,const struct can_filter * filter)596 static int mcp2515_add_rx_filter(const struct device *dev,
597 				 can_rx_callback_t rx_cb,
598 				 void *cb_arg,
599 				 const struct can_filter *filter)
600 {
601 	struct mcp2515_data *dev_data = dev->data;
602 	int filter_id = 0;
603 
604 	__ASSERT(rx_cb != NULL, "response_ptr can not be null");
605 
606 	if ((filter->flags & ~(CAN_FILTER_IDE)) != 0) {
607 		LOG_ERR("unsupported CAN filter flags 0x%02x", filter->flags);
608 		return -ENOTSUP;
609 	}
610 
611 	k_mutex_lock(&dev_data->mutex, K_FOREVER);
612 
613 	/* find free filter */
614 	while ((BIT(filter_id) & dev_data->filter_usage)
615 	       && (filter_id < CONFIG_CAN_MAX_FILTER)) {
616 		filter_id++;
617 	}
618 
619 	/* setup filter */
620 	if (filter_id < CONFIG_CAN_MAX_FILTER) {
621 		dev_data->filter_usage |= BIT(filter_id);
622 
623 		dev_data->filter[filter_id] = *filter;
624 		dev_data->rx_cb[filter_id] = rx_cb;
625 		dev_data->cb_arg[filter_id] = cb_arg;
626 
627 	} else {
628 		filter_id = -ENOSPC;
629 	}
630 
631 	k_mutex_unlock(&dev_data->mutex);
632 
633 	return filter_id;
634 }
635 
mcp2515_remove_rx_filter(const struct device * dev,int filter_id)636 static void mcp2515_remove_rx_filter(const struct device *dev, int filter_id)
637 {
638 	struct mcp2515_data *dev_data = dev->data;
639 
640 	if (filter_id < 0 || filter_id >= CONFIG_CAN_MAX_FILTER) {
641 		LOG_ERR("filter ID %d out of bounds", filter_id);
642 		return;
643 	}
644 
645 	k_mutex_lock(&dev_data->mutex, K_FOREVER);
646 	dev_data->filter_usage &= ~BIT(filter_id);
647 	k_mutex_unlock(&dev_data->mutex);
648 }
649 
mcp2515_set_state_change_callback(const struct device * dev,can_state_change_callback_t cb,void * user_data)650 static void mcp2515_set_state_change_callback(const struct device *dev,
651 					      can_state_change_callback_t cb,
652 					      void *user_data)
653 {
654 	struct mcp2515_data *dev_data = dev->data;
655 
656 	dev_data->common.state_change_cb = cb;
657 	dev_data->common.state_change_cb_user_data = user_data;
658 }
659 
mcp2515_rx_filter(const struct device * dev,struct can_frame * frame)660 static void mcp2515_rx_filter(const struct device *dev,
661 			      struct can_frame *frame)
662 {
663 	struct mcp2515_data *dev_data = dev->data;
664 	uint8_t filter_id = 0U;
665 	can_rx_callback_t callback;
666 	struct can_frame tmp_frame;
667 
668 #ifndef CONFIG_CAN_ACCEPT_RTR
669 	if ((frame->flags & CAN_FRAME_RTR) != 0U) {
670 		return;
671 	}
672 #endif /* !CONFIG_CAN_ACCEPT_RTR */
673 
674 	k_mutex_lock(&dev_data->mutex, K_FOREVER);
675 
676 	for (; filter_id < CONFIG_CAN_MAX_FILTER; filter_id++) {
677 		if (!(BIT(filter_id) & dev_data->filter_usage)) {
678 			continue; /* filter slot empty */
679 		}
680 
681 		if (!can_frame_matches_filter(frame, &dev_data->filter[filter_id])) {
682 			continue; /* filter did not match */
683 		}
684 
685 		callback = dev_data->rx_cb[filter_id];
686 		/*Make a temporary copy in case the user modifies the message*/
687 		tmp_frame = *frame;
688 
689 		callback(dev, &tmp_frame, dev_data->cb_arg[filter_id]);
690 	}
691 
692 	k_mutex_unlock(&dev_data->mutex);
693 }
694 
mcp2515_rx(const struct device * dev,uint8_t rx_idx)695 static void mcp2515_rx(const struct device *dev, uint8_t rx_idx)
696 {
697 	__ASSERT(rx_idx < MCP2515_RX_CNT, "rx_idx < MCP2515_RX_CNT");
698 
699 	struct can_frame frame;
700 	uint8_t rx_frame[MCP2515_FRAME_LEN];
701 	uint8_t nm;
702 
703 	/* Address Pointer selection */
704 	nm = 2 * rx_idx;
705 
706 	/* Fetch rx buffer */
707 	mcp2515_cmd_read_rx_buffer(dev, nm, rx_frame, sizeof(rx_frame));
708 	mcp2515_convert_mcp2515frame_to_canframe(rx_frame, &frame);
709 	mcp2515_rx_filter(dev, &frame);
710 }
711 
mcp2515_get_state(const struct device * dev,enum can_state * state,struct can_bus_err_cnt * err_cnt)712 static int mcp2515_get_state(const struct device *dev, enum can_state *state,
713 			     struct can_bus_err_cnt *err_cnt)
714 {
715 	struct mcp2515_data *dev_data = dev->data;
716 	uint8_t eflg;
717 	uint8_t err_cnt_buf[2];
718 	int ret;
719 
720 	ret = mcp2515_cmd_read_reg(dev, MCP2515_ADDR_EFLG, &eflg, sizeof(eflg));
721 	if (ret < 0) {
722 		LOG_ERR("Failed to read error register [%d]", ret);
723 		return -EIO;
724 	}
725 
726 	if (state != NULL) {
727 		if (!dev_data->common.started) {
728 			*state = CAN_STATE_STOPPED;
729 		} else if (eflg & MCP2515_EFLG_TXBO) {
730 			*state = CAN_STATE_BUS_OFF;
731 		} else if ((eflg & MCP2515_EFLG_RXEP) || (eflg & MCP2515_EFLG_TXEP)) {
732 			*state = CAN_STATE_ERROR_PASSIVE;
733 		} else if (eflg & MCP2515_EFLG_EWARN) {
734 			*state = CAN_STATE_ERROR_WARNING;
735 		} else {
736 			*state = CAN_STATE_ERROR_ACTIVE;
737 		}
738 	}
739 
740 	if (err_cnt != NULL) {
741 		ret = mcp2515_cmd_read_reg(dev, MCP2515_ADDR_TEC, err_cnt_buf,
742 					   sizeof(err_cnt_buf));
743 		if (ret < 0) {
744 			LOG_ERR("Failed to read error counters [%d]", ret);
745 			return -EIO;
746 		}
747 
748 		err_cnt->tx_err_cnt = err_cnt_buf[0];
749 		err_cnt->rx_err_cnt = err_cnt_buf[1];
750 	}
751 
752 #ifdef CONFIG_CAN_STATS
753 	if ((eflg & (MCP2515_EFLG_RX0OVR | MCP2515_EFLG_RX1OVR)) != 0U) {
754 		CAN_STATS_RX_OVERRUN_INC(dev);
755 
756 		ret = mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_EFLG,
757 					     eflg & (MCP2515_EFLG_RX0OVR | MCP2515_EFLG_RX1OVR),
758 					     0U);
759 		if (ret < 0) {
760 			LOG_ERR("Failed to clear RX overrun flags [%d]", ret);
761 			return -EIO;
762 		}
763 	}
764 #endif /* CONFIG_CAN_STATS */
765 
766 	return 0;
767 }
768 
mcp2515_handle_errors(const struct device * dev)769 static void mcp2515_handle_errors(const struct device *dev)
770 {
771 	struct mcp2515_data *dev_data = dev->data;
772 	can_state_change_callback_t state_change_cb = dev_data->common.state_change_cb;
773 	void *state_change_cb_data = dev_data->common.state_change_cb_user_data;
774 	enum can_state state;
775 	struct can_bus_err_cnt err_cnt;
776 	int err;
777 
778 	err = mcp2515_get_state(dev, &state, state_change_cb ? &err_cnt : NULL);
779 	if (err != 0) {
780 		LOG_ERR("Failed to get CAN controller state [%d]", err);
781 		return;
782 	}
783 
784 	if (state_change_cb && dev_data->old_state != state) {
785 		dev_data->old_state = state;
786 		state_change_cb(dev, state, err_cnt, state_change_cb_data);
787 	}
788 }
789 
mcp2515_handle_interrupts(const struct device * dev)790 static void mcp2515_handle_interrupts(const struct device *dev)
791 {
792 	const struct mcp2515_config *dev_cfg = dev->config;
793 	int ret;
794 	uint8_t canintf;
795 
796 	/* Loop until INT pin is inactive (all interrupt flags handled) */
797 	while (1) {
798 		ret = mcp2515_cmd_read_reg(dev, MCP2515_ADDR_CANINTF,
799 				&canintf, 1);
800 		if (ret != 0) {
801 			LOG_ERR("Couldn't read INTF register %d", ret);
802 			continue;
803 		}
804 
805 		if (canintf == 0) {
806 			/* No interrupt flags set */
807 			break;
808 		}
809 
810 		if (canintf & MCP2515_CANINTF_RX0IF) {
811 			mcp2515_rx(dev, 0);
812 
813 			/* RX0IF flag cleared automatically during read */
814 			canintf &= ~MCP2515_CANINTF_RX0IF;
815 		}
816 
817 		if (canintf & MCP2515_CANINTF_RX1IF) {
818 			mcp2515_rx(dev, 1);
819 
820 			/* RX1IF flag cleared automatically during read */
821 			canintf &= ~MCP2515_CANINTF_RX1IF;
822 		}
823 
824 		if (canintf & MCP2515_CANINTF_TX0IF) {
825 			mcp2515_tx_done(dev, 0, 0);
826 		}
827 
828 		if (canintf & MCP2515_CANINTF_TX1IF) {
829 			mcp2515_tx_done(dev, 1, 0);
830 		}
831 
832 		if (canintf & MCP2515_CANINTF_TX2IF) {
833 			mcp2515_tx_done(dev, 2, 0);
834 		}
835 
836 		if (canintf & MCP2515_CANINTF_ERRIF) {
837 			mcp2515_handle_errors(dev);
838 		}
839 
840 		if (canintf != 0) {
841 			/* Clear remaining flags */
842 			mcp2515_cmd_bit_modify(dev, MCP2515_ADDR_CANINTF,
843 					canintf, ~canintf);
844 		}
845 
846 		/* Break from loop if INT pin is inactive */
847 		ret = gpio_pin_get_dt(&dev_cfg->int_gpio);
848 		if (ret < 0) {
849 			LOG_ERR("Couldn't read INT pin");
850 		} else if (ret == 0) {
851 			/* All interrupt flags handled */
852 			break;
853 		}
854 	}
855 }
856 
mcp2515_int_thread(void * p1,void * p2,void * p3)857 static void mcp2515_int_thread(void *p1, void *p2, void *p3)
858 {
859 	ARG_UNUSED(p2);
860 	ARG_UNUSED(p3);
861 
862 	const struct device *dev = p1;
863 	struct mcp2515_data *dev_data = dev->data;
864 
865 	while (1) {
866 		k_sem_take(&dev_data->int_sem, K_FOREVER);
867 		mcp2515_handle_interrupts(dev);
868 	}
869 }
870 
mcp2515_int_gpio_callback(const struct device * dev,struct gpio_callback * cb,uint32_t pins)871 static void mcp2515_int_gpio_callback(const struct device *dev,
872 				      struct gpio_callback *cb, uint32_t pins)
873 {
874 	struct mcp2515_data *dev_data =
875 		CONTAINER_OF(cb, struct mcp2515_data, int_gpio_cb);
876 
877 	k_sem_give(&dev_data->int_sem);
878 }
879 
880 static const struct can_driver_api can_api_funcs = {
881 	.get_capabilities = mcp2515_get_capabilities,
882 	.set_timing = mcp2515_set_timing,
883 	.start = mcp2515_start,
884 	.stop = mcp2515_stop,
885 	.set_mode = mcp2515_set_mode,
886 	.send = mcp2515_send,
887 	.add_rx_filter = mcp2515_add_rx_filter,
888 	.remove_rx_filter = mcp2515_remove_rx_filter,
889 	.get_state = mcp2515_get_state,
890 	.set_state_change_callback = mcp2515_set_state_change_callback,
891 	.get_core_clock = mcp2515_get_core_clock,
892 	.get_max_filters = mcp2515_get_max_filters,
893 	.timing_min = {
894 		.sjw = 0x1,
895 		.prop_seg = 0x01,
896 		.phase_seg1 = 0x01,
897 		.phase_seg2 = 0x02,
898 		.prescaler = 0x01
899 	},
900 	.timing_max = {
901 		.sjw = 0x04,
902 		.prop_seg = 0x08,
903 		.phase_seg1 = 0x08,
904 		.phase_seg2 = 0x08,
905 		.prescaler = 0x40
906 	}
907 };
908 
909 
mcp2515_init(const struct device * dev)910 static int mcp2515_init(const struct device *dev)
911 {
912 	const struct mcp2515_config *dev_cfg = dev->config;
913 	struct mcp2515_data *dev_data = dev->data;
914 	struct can_timing timing = { 0 };
915 	k_tid_t tid;
916 	int ret;
917 
918 	k_sem_init(&dev_data->int_sem, 0, 1);
919 	k_mutex_init(&dev_data->mutex);
920 	k_sem_init(&dev_data->tx_sem, MCP2515_TX_CNT, MCP2515_TX_CNT);
921 
922 	if (dev_cfg->common.phy != NULL) {
923 		if (!device_is_ready(dev_cfg->common.phy)) {
924 			LOG_ERR("CAN transceiver not ready");
925 			return -ENODEV;
926 		}
927 	}
928 
929 	if (!spi_is_ready_dt(&dev_cfg->bus)) {
930 		LOG_ERR("SPI bus %s not ready", dev_cfg->bus.bus->name);
931 		return -ENODEV;
932 	}
933 
934 	/* Reset MCP2515 */
935 	if (mcp2515_cmd_soft_reset(dev)) {
936 		LOG_ERR("Soft-reset failed");
937 		return -EIO;
938 	}
939 
940 	/* Initialize interrupt handling  */
941 	if (!gpio_is_ready_dt(&dev_cfg->int_gpio)) {
942 		LOG_ERR("Interrupt GPIO port not ready");
943 		return -ENODEV;
944 	}
945 
946 	if (gpio_pin_configure_dt(&dev_cfg->int_gpio, GPIO_INPUT)) {
947 		LOG_ERR("Unable to configure interrupt GPIO");
948 		return -EINVAL;
949 	}
950 
951 	gpio_init_callback(&(dev_data->int_gpio_cb), mcp2515_int_gpio_callback,
952 			   BIT(dev_cfg->int_gpio.pin));
953 
954 	if (gpio_add_callback(dev_cfg->int_gpio.port,
955 			      &(dev_data->int_gpio_cb))) {
956 		return -EINVAL;
957 	}
958 
959 	if (gpio_pin_interrupt_configure_dt(&dev_cfg->int_gpio,
960 					    GPIO_INT_EDGE_TO_ACTIVE)) {
961 		return -EINVAL;
962 	}
963 
964 	tid = k_thread_create(&dev_data->int_thread, dev_data->int_thread_stack,
965 			      dev_cfg->int_thread_stack_size,
966 			      mcp2515_int_thread, (void *)dev,
967 			      NULL, NULL, K_PRIO_COOP(dev_cfg->int_thread_priority),
968 			      0, K_NO_WAIT);
969 	(void)k_thread_name_set(tid, "mcp2515");
970 
971 	(void)memset(dev_data->rx_cb, 0, sizeof(dev_data->rx_cb));
972 	(void)memset(dev_data->filter, 0, sizeof(dev_data->filter));
973 	dev_data->old_state = CAN_STATE_ERROR_ACTIVE;
974 
975 	ret = can_calc_timing(dev, &timing, dev_cfg->common.bitrate,
976 			      dev_cfg->common.sample_point);
977 	if (ret == -EINVAL) {
978 		LOG_ERR("Can't find timing for given param");
979 		return -EIO;
980 	}
981 
982 	LOG_DBG("Presc: %d, BS1: %d, BS2: %d",
983 		timing.prescaler, timing.phase_seg1, timing.phase_seg2);
984 	LOG_DBG("Sample-point err : %d", ret);
985 
986 	k_usleep(MCP2515_OSC_STARTUP_US);
987 
988 	ret = can_set_timing(dev, &timing);
989 	if (ret) {
990 		return ret;
991 	}
992 
993 	ret = can_set_mode(dev, CAN_MODE_NORMAL);
994 
995 	return ret;
996 }
997 
998 #define MCP2515_INIT(inst)                                                                         \
999 	static K_KERNEL_STACK_DEFINE(mcp2515_int_thread_stack_##inst,                              \
1000 				     CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE);                    \
1001                                                                                                    \
1002 	static struct mcp2515_data mcp2515_data_##inst = {                                         \
1003 		.int_thread_stack = mcp2515_int_thread_stack_##inst,                               \
1004 		.tx_busy_map = 0U,                                                                 \
1005 		.filter_usage = 0U,                                                                \
1006 	};                                                                                         \
1007                                                                                                    \
1008 	static const struct mcp2515_config mcp2515_config_##inst = {                               \
1009 		.common = CAN_DT_DRIVER_CONFIG_INST_GET(inst, 0, 1000000),                         \
1010 		.bus = SPI_DT_SPEC_INST_GET(inst, SPI_WORD_SET(8), 0),                             \
1011 		.int_gpio = GPIO_DT_SPEC_INST_GET(inst, int_gpios),                                \
1012 		.int_thread_stack_size = CONFIG_CAN_MCP2515_INT_THREAD_STACK_SIZE,                 \
1013 		.int_thread_priority = CONFIG_CAN_MCP2515_INT_THREAD_PRIO,                         \
1014 		.osc_freq = DT_INST_PROP(inst, osc_freq),                                          \
1015 	};                                                                                         \
1016                                                                                                    \
1017 	CAN_DEVICE_DT_INST_DEFINE(inst, mcp2515_init, NULL, &mcp2515_data_##inst,                  \
1018 				  &mcp2515_config_##inst, POST_KERNEL, CONFIG_CAN_INIT_PRIORITY,   \
1019 				  &can_api_funcs);
1020 
1021 DT_INST_FOREACH_STATUS_OKAY(MCP2515_INIT)
1022