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