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