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 	/* interrupt data */
26 	struct gpio_callback int_gpio_cb;
27 	struct k_thread int_thread;
28 	k_thread_stack_t *int_thread_stack;
29 	struct k_sem int_sem;
30 
31 	/* tx data */
32 	struct k_sem tx_sem;
33 	struct mcp2515_tx_cb tx_cb[MCP2515_TX_CNT];
34 	uint8_t tx_busy_map;
35 
36 	/* filter data */
37 	uint32_t filter_usage;
38 	can_rx_callback_t rx_cb[CONFIG_CAN_MAX_FILTER];
39 	void *cb_arg[CONFIG_CAN_MAX_FILTER];
40 	struct can_filter filter[CONFIG_CAN_MAX_FILTER];
41 	can_state_change_callback_t state_change_cb;
42 	void *state_change_cb_data;
43 
44 	/* general data */
45 	struct k_mutex mutex;
46 	enum can_state old_state;
47 	uint8_t mcp2515_mode;
48 	bool started;
49 };
50 
51 struct mcp2515_config {
52 	/* spi configuration */
53 	struct spi_dt_spec bus;
54 
55 	/* interrupt configuration */
56 	struct gpio_dt_spec int_gpio;
57 	size_t int_thread_stack_size;
58 	int int_thread_priority;
59 
60 	/* CAN timing */
61 	uint8_t tq_sjw;
62 	uint8_t tq_prop;
63 	uint8_t tq_bs1;
64 	uint8_t tq_bs2;
65 	uint32_t bus_speed;
66 	uint32_t osc_freq;
67 	uint16_t sample_point;
68 
69 	/* CAN transceiver */
70 	const struct device *phy;
71 	uint32_t max_bitrate;
72 };
73 
74 /*
75  * Startup time of 128 OSC1 clock cycles at 1MHz (minimum clock in frequency)
76  * see MCP2515 datasheet section 8.1 Oscillator Start-up Timer
77  */
78 #define MCP2515_OSC_STARTUP_US		128U
79 
80 /* MCP2515 Opcodes */
81 #define MCP2515_OPCODE_WRITE            0x02
82 #define MCP2515_OPCODE_READ             0x03
83 #define MCP2515_OPCODE_BIT_MODIFY       0x05
84 #define MCP2515_OPCODE_LOAD_TX_BUFFER   0x40
85 #define MCP2515_OPCODE_RTS              0x80
86 #define MCP2515_OPCODE_READ_RX_BUFFER   0x90
87 #define MCP2515_OPCODE_READ_STATUS      0xA0
88 #define MCP2515_OPCODE_RESET            0xC0
89 
90 /* MCP2515 Registers */
91 #define MCP2515_ADDR_CANSTAT            0x0E
92 #define MCP2515_ADDR_CANCTRL            0x0F
93 #define MCP2515_ADDR_TEC                0x1C
94 #define MCP2515_ADDR_REC                0x1D
95 #define MCP2515_ADDR_CNF3               0x28
96 #define MCP2515_ADDR_CNF2               0x29
97 #define MCP2515_ADDR_CNF1               0x2A
98 #define MCP2515_ADDR_CANINTE            0x2B
99 #define MCP2515_ADDR_CANINTF            0x2C
100 #define MCP2515_ADDR_EFLG               0x2D
101 #define MCP2515_ADDR_TXB0CTRL           0x30
102 #define MCP2515_ADDR_TXB1CTRL           0x40
103 #define MCP2515_ADDR_TXB2CTRL           0x50
104 #define MCP2515_ADDR_RXB0CTRL           0x60
105 #define MCP2515_ADDR_RXB1CTRL           0x70
106 
107 #define MCP2515_ADDR_OFFSET_FRAME2FRAME	0x10
108 #define MCP2515_ADDR_OFFSET_CTRL2FRAME	0x01
109 
110 /* MCP2515 Operation Modes */
111 #define MCP2515_MODE_NORMAL             0x00
112 #define MCP2515_MODE_LOOPBACK           0x02
113 #define MCP2515_MODE_SILENT             0x03
114 #define MCP2515_MODE_CONFIGURATION      0x04
115 
116 /* MCP2515_FRAME_OFFSET */
117 #define MCP2515_FRAME_OFFSET_SIDH       0
118 #define MCP2515_FRAME_OFFSET_SIDL       1
119 #define MCP2515_FRAME_OFFSET_EID8       2
120 #define MCP2515_FRAME_OFFSET_EID0       3
121 #define MCP2515_FRAME_OFFSET_DLC        4
122 #define MCP2515_FRAME_OFFSET_D0         5
123 
124 /* MCP2515_CANINTF */
125 #define MCP2515_CANINTF_RX0IF           BIT(0)
126 #define MCP2515_CANINTF_RX1IF           BIT(1)
127 #define MCP2515_CANINTF_TX0IF           BIT(2)
128 #define MCP2515_CANINTF_TX1IF           BIT(3)
129 #define MCP2515_CANINTF_TX2IF           BIT(4)
130 #define MCP2515_CANINTF_ERRIF           BIT(5)
131 #define MCP2515_CANINTF_WAKIF           BIT(6)
132 #define MCP2515_CANINTF_MERRF           BIT(7)
133 
134 #define MCP2515_INTE_RX0IE              BIT(0)
135 #define MCP2515_INTE_RX1IE              BIT(1)
136 #define MCP2515_INTE_TX0IE              BIT(2)
137 #define MCP2515_INTE_TX1IE              BIT(3)
138 #define MCP2515_INTE_TX2IE              BIT(4)
139 #define MCP2515_INTE_ERRIE              BIT(5)
140 #define MCP2515_INTE_WAKIE              BIT(6)
141 #define MCP2515_INTE_MERRE              BIT(7)
142 
143 #define MCP2515_EFLG_EWARN              BIT(0)
144 #define MCP2515_EFLG_RXWAR              BIT(1)
145 #define MCP2515_EFLG_TXWAR              BIT(2)
146 #define MCP2515_EFLG_RXEP               BIT(3)
147 #define MCP2515_EFLG_TXEP               BIT(4)
148 #define MCP2515_EFLG_TXBO               BIT(5)
149 #define MCP2515_EFLG_RX0OVR             BIT(6)
150 #define MCP2515_EFLG_RX1OVR             BIT(7)
151 
152 #define MCP2515_TXCTRL_TXREQ			BIT(3)
153 
154 #define MCP2515_CANSTAT_MODE_POS		5
155 #define MCP2515_CANSTAT_MODE_MASK		(0x07 << MCP2515_CANSTAT_MODE_POS)
156 #define MCP2515_CANCTRL_MODE_POS		5
157 #define MCP2515_CANCTRL_MODE_MASK		(0x07 << MCP2515_CANCTRL_MODE_POS)
158 #define MCP2515_TXBNCTRL_TXREQ_POS		3
159 #define MCP2515_TXBNCTRL_TXREQ_MASK		(0x01 << MCP2515_TXBNCTRL_TXREQ_POS)
160 
161 #endif /*_MCP2515_H_*/
162