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