Line data Source code
1 1 : /*
2 : * Copyright (c) 2022 Henrik Brix Andersen <henrik@brixandersen.dk>
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief API for NXP SJA1000 (and compatible) CAN controller frontend drivers.
10 : */
11 :
12 : #ifndef ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_SJA1000_H_
13 : #define ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_SJA1000_H_
14 :
15 : #include <zephyr/drivers/can.h>
16 :
17 : /**
18 : * @name SJA1000 Output Control Register (OCR) bits
19 : *
20 : * @{
21 : */
22 0 : #define CAN_SJA1000_OCR_OCMODE_MASK GENMASK(1, 0)
23 0 : #define CAN_SJA1000_OCR_OCPOL0 BIT(2)
24 0 : #define CAN_SJA1000_OCR_OCTN0 BIT(3)
25 0 : #define CAN_SJA1000_OCR_OCTP0 BIT(4)
26 0 : #define CAN_SJA1000_OCR_OCPOL1 BIT(5)
27 0 : #define CAN_SJA1000_OCR_OCTN1 BIT(6)
28 0 : #define CAN_SJA1000_OCR_OCTP1 BIT(7)
29 :
30 0 : #define CAN_SJA1000_OCR_OCMODE_BIPHASE FIELD_PREP(CAN_SJA1000_OCR_OCMODE_MASK, 0U)
31 0 : #define CAN_SJA1000_OCR_OCMODE_TEST FIELD_PREP(CAN_SJA1000_OCR_OCMODE_MASK, 1U)
32 0 : #define CAN_SJA1000_OCR_OCMODE_NORMAL FIELD_PREP(CAN_SJA1000_OCR_OCMODE_MASK, 2U)
33 0 : #define CAN_SJA1000_OCR_OCMODE_CLOCK FIELD_PREP(CAN_SJA1000_OCR_OCMODE_MASK, 3U)
34 :
35 : /** @} */
36 :
37 : /**
38 : * @name SJA1000 Clock Divider Register (CDR) bits
39 : *
40 : * @{
41 : */
42 0 : #define CAN_SJA1000_CDR_CD_MASK GENMASK(2, 0)
43 0 : #define CAN_SJA1000_CDR_CLOCK_OFF BIT(3)
44 0 : #define CAN_SJA1000_CDR_RXINTEN BIT(5)
45 0 : #define CAN_SJA1000_CDR_CBP BIT(6)
46 0 : #define CAN_SJA1000_CDR_CAN_MODE BIT(7)
47 :
48 0 : #define CAN_SJA1000_CDR_CD_DIV1 FIELD_PREP(CAN_SJA1000_CDR_CD_MASK, 7U)
49 0 : #define CAN_SJA1000_CDR_CD_DIV2 FIELD_PREP(CAN_SJA1000_CDR_CD_MASK, 0U)
50 0 : #define CAN_SJA1000_CDR_CD_DIV4 FIELD_PREP(CAN_SJA1000_CDR_CD_MASK, 1U)
51 0 : #define CAN_SJA1000_CDR_CD_DIV6 FIELD_PREP(CAN_SJA1000_CDR_CD_MASK, 2U)
52 0 : #define CAN_SJA1000_CDR_CD_DIV8 FIELD_PREP(CAN_SJA1000_CDR_CD_MASK, 3U)
53 0 : #define CAN_SJA1000_CDR_CD_DIV10 FIELD_PREP(CAN_SJA1000_CDR_CD_MASK, 4U)
54 0 : #define CAN_SJA1000_CDR_CD_DIV12 FIELD_PREP(CAN_SJA1000_CDR_CD_MASK, 5U)
55 0 : #define CAN_SJA1000_CDR_CD_DIV14 FIELD_PREP(CAN_SJA1000_CDR_CD_MASK, 6U)
56 :
57 : /** @} */
58 :
59 : /**
60 : * @brief SJA1000 specific static initializer for a minimum @p can_timing struct
61 : */
62 1 : #define CAN_SJA1000_TIMING_MIN_INITIALIZER \
63 : { \
64 : .sjw = 1, \
65 : .prop_seg = 0, \
66 : .phase_seg1 = 1, \
67 : .phase_seg2 = 1, \
68 : .prescaler = 1 \
69 : }
70 :
71 : /**
72 : * @brief SJA1000 specific static initializer for a maximum @p can_timing struct
73 : */
74 1 : #define CAN_SJA1000_TIMING_MAX_INITIALIZER \
75 : { \
76 : .sjw = 4, \
77 : .prop_seg = 0, \
78 : .phase_seg1 = 16, \
79 : .phase_seg2 = 8, \
80 : .prescaler = 64 \
81 : }
82 :
83 : /**
84 : * @brief SJA1000 driver front-end callback for writing a register value
85 : *
86 : * @param dev Pointer to the device structure for the driver instance.
87 : * @param reg Register offset
88 : * @param val Register value
89 : */
90 1 : typedef void (*can_sja1000_write_reg_t)(const struct device *dev, uint8_t reg, uint8_t val);
91 :
92 : /**
93 : * @brief SJA1000 driver front-end callback for reading a register value
94 : *
95 : * @param dev Pointer to the device structure for the driver instance.
96 : * @param reg Register offset
97 : * @retval Register value
98 : */
99 1 : typedef uint8_t (*can_sja1000_read_reg_t)(const struct device *dev, uint8_t reg);
100 :
101 : /**
102 : * @brief SJA1000 driver internal configuration structure.
103 : */
104 1 : struct can_sja1000_config {
105 0 : const struct can_driver_config common;
106 0 : can_sja1000_read_reg_t read_reg;
107 0 : can_sja1000_write_reg_t write_reg;
108 0 : uint8_t ocr;
109 0 : uint8_t cdr;
110 0 : const void *custom;
111 : };
112 :
113 : /**
114 : * @brief Static initializer for @p can_sja1000_config struct
115 : *
116 : * @param node_id Devicetree node identifier
117 : * @param _custom Pointer to custom driver frontend configuration structure
118 : * @param _read_reg Driver frontend SJA100 register read function
119 : * @param _write_reg Driver frontend SJA100 register write function
120 : * @param _ocr Initial SJA1000 Output Control Register (OCR) value
121 : * @param _cdr Initial SJA1000 Clock Divider Register (CDR) value
122 : * @param _min_bitrate minimum bitrate supported by the CAN controller
123 : */
124 : #define CAN_SJA1000_DT_CONFIG_GET(node_id, _custom, _read_reg, _write_reg, _ocr, _cdr, \
125 1 : _min_bitrate) \
126 : { \
127 : .common = CAN_DT_DRIVER_CONFIG_GET(node_id, _min_bitrate, 1000000), \
128 : .read_reg = _read_reg, \
129 : .write_reg = _write_reg, \
130 : .ocr = _ocr, \
131 : .cdr = _cdr, \
132 : .custom = _custom, \
133 : }
134 :
135 : /**
136 : * @brief Static initializer for @p can_sja1000_config struct from a DT_DRV_COMPAT instance
137 : *
138 : * @param inst DT_DRV_COMPAT instance number
139 : * @param _custom Pointer to custom driver frontend configuration structure
140 : * @param _read_reg Driver frontend SJA100 register read function
141 : * @param _write_reg Driver frontend SJA100 register write function
142 : * @param _ocr Initial SJA1000 Output Control Register (OCR) value
143 : * @param _cdr Initial SJA1000 Clock Divider Register (CDR) value
144 : * @param _min_bitrate minimum bitrate supported by the CAN controller
145 : * @see CAN_SJA1000_DT_CONFIG_GET()
146 : */
147 : #define CAN_SJA1000_DT_CONFIG_INST_GET(inst, _custom, _read_reg, _write_reg, _ocr, _cdr, \
148 1 : _min_bitrate) \
149 : CAN_SJA1000_DT_CONFIG_GET(DT_DRV_INST(inst), _custom, _read_reg, _write_reg, _ocr, _cdr, \
150 : _min_bitrate)
151 :
152 : /**
153 : * @brief SJA1000 driver internal RX filter structure.
154 : */
155 1 : struct can_sja1000_rx_filter {
156 0 : struct can_filter filter;
157 0 : can_rx_callback_t callback;
158 0 : void *user_data;
159 : };
160 :
161 : /**
162 : * @brief SJA1000 driver internal data structure.
163 : */
164 1 : struct can_sja1000_data {
165 0 : struct can_driver_data common;
166 0 : ATOMIC_DEFINE(rx_allocs, CONFIG_CAN_MAX_FILTER);
167 0 : struct can_sja1000_rx_filter filters[CONFIG_CAN_MAX_FILTER];
168 0 : struct k_mutex mod_lock;
169 0 : enum can_state state;
170 0 : struct k_sem tx_idle;
171 0 : can_tx_callback_t tx_callback;
172 0 : void *tx_user_data;
173 0 : void *custom;
174 : };
175 :
176 : /**
177 : * @brief Initializer for a @a can_sja1000_data struct
178 : * @param _custom Pointer to custom driver frontend data structure
179 : */
180 1 : #define CAN_SJA1000_DATA_INITIALIZER(_custom) \
181 : { \
182 : .custom = _custom, \
183 : }
184 :
185 : /**
186 : * @brief SJA1000 callback API upon setting CAN bus timing
187 : * See @a can_set_timing() for argument description
188 : */
189 1 : int can_sja1000_set_timing(const struct device *dev, const struct can_timing *timing);
190 :
191 : /**
192 : * @brief SJA1000 callback API upon getting CAN controller capabilities
193 : * See @a can_get_capabilities() for argument description
194 : */
195 1 : int can_sja1000_get_capabilities(const struct device *dev, can_mode_t *cap);
196 :
197 : /**
198 : * @brief SJA1000 callback API upon starting CAN controller
199 : * See @a can_start() for argument description
200 : */
201 1 : int can_sja1000_start(const struct device *dev);
202 :
203 : /**
204 : * @brief SJA1000 callback API upon stopping CAN controller
205 : * See @a can_stop() for argument description
206 : */
207 1 : int can_sja1000_stop(const struct device *dev);
208 :
209 : /**
210 : * @brief SJA1000 callback API upon setting CAN controller mode
211 : * See @a can_set_mode() for argument description
212 : */
213 1 : int can_sja1000_set_mode(const struct device *dev, can_mode_t mode);
214 :
215 : /**
216 : * @brief SJA1000 callback API upon sending a CAN frame
217 : * See @a can_send() for argument description
218 : */
219 1 : int can_sja1000_send(const struct device *dev, const struct can_frame *frame, k_timeout_t timeout,
220 : can_tx_callback_t callback, void *user_data);
221 :
222 : /**
223 : * @brief SJA1000 callback API upon adding an RX filter
224 : * See @a can_add_rx_callback() for argument description
225 : */
226 1 : int can_sja1000_add_rx_filter(const struct device *dev, can_rx_callback_t callback, void *user_data,
227 : const struct can_filter *filter);
228 :
229 : /**
230 : * @brief SJA1000 callback API upon removing an RX filter
231 : * See @a can_remove_rx_filter() for argument description
232 : */
233 1 : void can_sja1000_remove_rx_filter(const struct device *dev, int filter_id);
234 :
235 : #ifdef CONFIG_CAN_MANUAL_RECOVERY_MODE
236 : /**
237 : * @brief SJA1000 callback API upon recovering the CAN bus
238 : * See @a can_recover() for argument description
239 : */
240 : int can_sja1000_recover(const struct device *dev, k_timeout_t timeout);
241 : #endif /* CONFIG_CAN_MANUAL_RECOVERY_MODE */
242 :
243 : /**
244 : * @brief SJA1000 callback API upon getting the CAN controller state
245 : * See @a can_get_state() for argument description
246 : */
247 1 : int can_sja1000_get_state(const struct device *dev, enum can_state *state,
248 : struct can_bus_err_cnt *err_cnt);
249 :
250 : /**
251 : * @brief SJA1000 callback API upon setting a state change callback
252 : * See @a can_set_state_change_callback() for argument description
253 : */
254 1 : void can_sja1000_set_state_change_callback(const struct device *dev,
255 : can_state_change_callback_t callback, void *user_data);
256 :
257 : /**
258 : * @brief SJA1000 callback API upon getting the maximum number of concurrent CAN RX filters
259 : * See @a can_get_max_filters() for argument description
260 : */
261 1 : int can_sja1000_get_max_filters(const struct device *dev, bool ide);
262 :
263 : /**
264 : * @brief SJA1000 IRQ handler callback.
265 : *
266 : * @param dev Pointer to the device structure for the driver instance.
267 : */
268 1 : void can_sja1000_isr(const struct device *dev);
269 :
270 : /**
271 : * @brief SJA1000 driver initialization callback.
272 : *
273 : * @param dev Pointer to the device structure for the driver instance.
274 : */
275 1 : int can_sja1000_init(const struct device *dev);
276 :
277 : #endif /* ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_SJA1000_H_ */
|