1 /*
2  * Copyright (c) 2018 Karsten Koenig
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  */
7 
8 #ifndef _MCP2515_H_
9 #define _MCP2515_H_
10 
11 #include <zephyr/drivers/gpio.h>
12 #include <zephyr/drivers/can.h>
13 
14 #define MCP2515_RX_CNT                   2
15 /* Reduce the number of Tx buffers to 1 in order to avoid priority inversion. */
16 #define MCP2515_TX_CNT                   1
17 #define MCP2515_FRAME_LEN               13
18 
19 struct mcp2515_tx_cb {
20 	can_tx_callback_t cb;
21 	void *cb_arg;
22 };
23 
24 struct mcp2515_data {
25 	struct can_driver_data common;
26 
27 	/* interrupt data */
28 	struct gpio_callback int_gpio_cb;
29 	struct k_thread int_thread;
30 	k_thread_stack_t *int_thread_stack;
31 	struct k_sem int_sem;
32 
33 	/* tx data */
34 	struct k_sem tx_sem;
35 	struct mcp2515_tx_cb tx_cb[MCP2515_TX_CNT];
36 	uint8_t tx_busy_map;
37 
38 	/* filter data */
39 	uint32_t filter_usage;
40 	can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER];
41 	void *cb_arg[CONFIG_CAN_MAX_FILTER];
42 	struct can_filter filter[CONFIG_CAN_MAX_FILTER];
43 
44 	/* general data */
45 	struct k_mutex mutex;
46 	enum can_state old_state;
47 	uint8_t mcp2515_mode;
48 };
49 
50 struct mcp2515_config {
51 	const struct can_driver_config common;
52 
53 	/* spi configuration */
54 	struct spi_dt_spec bus;
55 
56 	/* interrupt configuration */
57 	struct gpio_dt_spec int_gpio;
58 	size_t int_thread_stack_size;
59 	int int_thread_priority;
60 
61 	/* CAN timing */
62 	uint32_t osc_freq;
63 };
64 
65 /*
66  * Startup time of 128 OSC1 clock cycles at 1MHz (minimum clock in frequency)
67  * see MCP2515 datasheet section 8.1 Oscillator Start-up Timer
68  */
69 #define MCP2515_OSC_STARTUP_US		128U
70 
71 /* MCP2515 Opcodes */
72 #define MCP2515_OPCODE_WRITE            0x02
73 #define MCP2515_OPCODE_READ             0x03
74 #define MCP2515_OPCODE_BIT_MODIFY       0x05
75 #define MCP2515_OPCODE_LOAD_TX_BUFFER   0x40
76 #define MCP2515_OPCODE_RTS              0x80
77 #define MCP2515_OPCODE_READ_RX_BUFFER   0x90
78 #define MCP2515_OPCODE_READ_STATUS      0xA0
79 #define MCP2515_OPCODE_RESET            0xC0
80 
81 /* MCP2515 Registers */
82 #define MCP2515_ADDR_CANSTAT            0x0E
83 #define MCP2515_ADDR_CANCTRL            0x0F
84 #define MCP2515_ADDR_TEC                0x1C
85 #define MCP2515_ADDR_REC                0x1D
86 #define MCP2515_ADDR_CNF3               0x28
87 #define MCP2515_ADDR_CNF2               0x29
88 #define MCP2515_ADDR_CNF1               0x2A
89 #define MCP2515_ADDR_CANINTE            0x2B
90 #define MCP2515_ADDR_CANINTF            0x2C
91 #define MCP2515_ADDR_EFLG               0x2D
92 #define MCP2515_ADDR_TXB0CTRL           0x30
93 #define MCP2515_ADDR_TXB1CTRL           0x40
94 #define MCP2515_ADDR_TXB2CTRL           0x50
95 #define MCP2515_ADDR_RXB0CTRL           0x60
96 #define MCP2515_ADDR_RXB1CTRL           0x70
97 
98 #define MCP2515_ADDR_OFFSET_FRAME2FRAME	0x10
99 #define MCP2515_ADDR_OFFSET_CTRL2FRAME	0x01
100 
101 /* MCP2515 Operation Modes */
102 #define MCP2515_MODE_NORMAL             0x00
103 #define MCP2515_MODE_LOOPBACK           0x02
104 #define MCP2515_MODE_SILENT             0x03
105 #define MCP2515_MODE_CONFIGURATION      0x04
106 
107 /* MCP2515_FRAME_OFFSET */
108 #define MCP2515_FRAME_OFFSET_SIDH       0
109 #define MCP2515_FRAME_OFFSET_SIDL       1
110 #define MCP2515_FRAME_OFFSET_EID8       2
111 #define MCP2515_FRAME_OFFSET_EID0       3
112 #define MCP2515_FRAME_OFFSET_DLC        4
113 #define MCP2515_FRAME_OFFSET_D0         5
114 
115 /* MCP2515_CANINTF */
116 #define MCP2515_CANINTF_RX0IF           BIT(0)
117 #define MCP2515_CANINTF_RX1IF           BIT(1)
118 #define MCP2515_CANINTF_TX0IF           BIT(2)
119 #define MCP2515_CANINTF_TX1IF           BIT(3)
120 #define MCP2515_CANINTF_TX2IF           BIT(4)
121 #define MCP2515_CANINTF_ERRIF           BIT(5)
122 #define MCP2515_CANINTF_WAKIF           BIT(6)
123 #define MCP2515_CANINTF_MERRF           BIT(7)
124 
125 #define MCP2515_INTE_RX0IE              BIT(0)
126 #define MCP2515_INTE_RX1IE              BIT(1)
127 #define MCP2515_INTE_TX0IE              BIT(2)
128 #define MCP2515_INTE_TX1IE              BIT(3)
129 #define MCP2515_INTE_TX2IE              BIT(4)
130 #define MCP2515_INTE_ERRIE              BIT(5)
131 #define MCP2515_INTE_WAKIE              BIT(6)
132 #define MCP2515_INTE_MERRE              BIT(7)
133 
134 #define MCP2515_EFLG_EWARN              BIT(0)
135 #define MCP2515_EFLG_RXWAR              BIT(1)
136 #define MCP2515_EFLG_TXWAR              BIT(2)
137 #define MCP2515_EFLG_RXEP               BIT(3)
138 #define MCP2515_EFLG_TXEP               BIT(4)
139 #define MCP2515_EFLG_TXBO               BIT(5)
140 #define MCP2515_EFLG_RX0OVR             BIT(6)
141 #define MCP2515_EFLG_RX1OVR             BIT(7)
142 
143 #define MCP2515_TXCTRL_TXREQ			BIT(3)
144 
145 #define MCP2515_CANSTAT_MODE_POS		5
146 #define MCP2515_CANSTAT_MODE_MASK		(0x07 << MCP2515_CANSTAT_MODE_POS)
147 #define MCP2515_CANCTRL_MODE_POS		5
148 #define MCP2515_CANCTRL_MODE_MASK		(0x07 << MCP2515_CANCTRL_MODE_POS)
149 #define MCP2515_TXBNCTRL_TXREQ_POS		3
150 #define MCP2515_TXBNCTRL_TXREQ_MASK		(0x01 << MCP2515_TXBNCTRL_TXREQ_POS)
151 
152 #endif /*_MCP2515_H_*/
153