1 /*
2 * Copyright (c) 2023 Vestas Wind Systems A/S
3 * Copyright (c) 2020 Alexander Wachter
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 */
8
9 #ifndef ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_MCAN_H_
10 #define ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_MCAN_H_
11
12 #include <zephyr/cache.h>
13 #include <zephyr/devicetree.h>
14 #include <zephyr/drivers/can.h>
15 #include <zephyr/kernel.h>
16 #include <zephyr/sys/sys_io.h>
17 #include <zephyr/sys/util.h>
18
19 /*
20 * The Bosch M_CAN register definitions correspond to those found in the Bosch M_CAN Controller Area
21 * Network User's Manual, Revision 3.3.0.
22 */
23
24 /* Core Release register */
25 #define CAN_MCAN_CREL 0x000
26 #define CAN_MCAN_CREL_REL GENMASK(31, 28)
27 #define CAN_MCAN_CREL_STEP GENMASK(27, 24)
28 #define CAN_MCAN_CREL_SUBSTEP GENMASK(23, 20)
29 #define CAN_MCAN_CREL_YEAR GENMASK(19, 16)
30 #define CAN_MCAN_CREL_MON GENMASK(15, 8)
31 #define CAN_MCAN_CREL_DAY GENMASK(7, 0)
32
33 /* Endian register */
34 #define CAN_MCAN_ENDN 0x004
35 #define CAN_MCAN_ENDN_ETV GENMASK(31, 0)
36
37 /* Customer register */
38 #define CAN_MCAN_CUST 0x008
39 #define CAN_MCAN_CUST_CUST GENMASK(31, 0)
40
41 /* Data Bit Timing & Prescaler register */
42 #define CAN_MCAN_DBTP 0x00C
43 #define CAN_MCAN_DBTP_TDC BIT(23)
44 #define CAN_MCAN_DBTP_DBRP GENMASK(20, 16)
45 #define CAN_MCAN_DBTP_DTSEG1 GENMASK(12, 8)
46 #define CAN_MCAN_DBTP_DTSEG2 GENMASK(7, 4)
47 #define CAN_MCAN_DBTP_DSJW GENMASK(3, 0)
48
49 /* Test register */
50 #define CAN_MCAN_TEST 0x010
51 #define CAN_MCAN_TEST_SVAL BIT(21)
52 #define CAN_MCAN_TEST_TXBNS GENMASK(20, 16)
53 #define CAN_MCAN_TEST_PVAL BIT(13)
54 #define CAN_MCAN_TEST_TXBNP GENMASK(12, 8)
55 #define CAN_MCAN_TEST_RX BIT(7)
56 #define CAN_MCAN_TEST_TX GENMASK(6, 5)
57 #define CAN_MCAN_TEST_LBCK BIT(4)
58
59 /* RAM Watchdog register */
60 #define CAN_MCAN_RWD 0x014
61 #define CAN_MCAN_RWD_WDV GENMASK(15, 8)
62 #define CAN_MCAN_RWD_WDC GENMASK(7, 0)
63
64 /* CC Control register */
65 #define CAN_MCAN_CCCR 0x018
66 #define CAN_MCAN_CCCR_NISO BIT(15)
67 #define CAN_MCAN_CCCR_TXP BIT(14)
68 #define CAN_MCAN_CCCR_EFBI BIT(13)
69 #define CAN_MCAN_CCCR_PXHD BIT(12)
70 #define CAN_MCAN_CCCR_WMM BIT(11)
71 #define CAN_MCAN_CCCR_UTSU BIT(10)
72 #define CAN_MCAN_CCCR_BRSE BIT(9)
73 #define CAN_MCAN_CCCR_FDOE BIT(8)
74 #define CAN_MCAN_CCCR_TEST BIT(7)
75 #define CAN_MCAN_CCCR_DAR BIT(6)
76 #define CAN_MCAN_CCCR_MON BIT(5)
77 #define CAN_MCAN_CCCR_CSR BIT(4)
78 #define CAN_MCAN_CCCR_CSA BIT(3)
79 #define CAN_MCAN_CCCR_ASM BIT(2)
80 #define CAN_MCAN_CCCR_CCE BIT(1)
81 #define CAN_MCAN_CCCR_INIT BIT(0)
82
83 /* Nominal Bit Timing & Prescaler register */
84 #define CAN_MCAN_NBTP 0x01C
85 #define CAN_MCAN_NBTP_NSJW GENMASK(31, 25)
86 #define CAN_MCAN_NBTP_NBRP GENMASK(24, 16)
87 #define CAN_MCAN_NBTP_NTSEG1 GENMASK(15, 8)
88 #define CAN_MCAN_NBTP_NTSEG2 GENMASK(6, 0)
89
90 /* Timestamp Counter Configuration register */
91 #define CAN_MCAN_TSCC 0x020
92 #define CAN_MCAN_TSCC_TCP GENMASK(19, 16)
93 #define CAN_MCAN_TSCC_TSS GENMASK(1, 0)
94
95 /* Timestamp Counter Value register */
96 #define CAN_MCAN_TSCV 0x024
97 #define CAN_MCAN_TSCV_TSC GENMASK(15, 0)
98
99 /* Timeout Counter Configuration register */
100 #define CAN_MCAN_TOCC 0x028
101 #define CAN_MCAN_TOCC_TOP GENMASK(31, 16)
102 #define CAN_MCAN_TOCC_TOS GENMASK(2, 1)
103 #define CAN_MCAN_TOCC_ETOC BIT(1)
104
105 /* Timeout Counter Value register */
106 #define CAN_MCAN_TOCV 0x02C
107 #define CAN_MCAN_TOCV_TOC GENMASK(15, 0)
108
109 /* Error Counter register */
110 #define CAN_MCAN_ECR 0x040
111 #define CAN_MCAN_ECR_CEL GENMASK(23, 16)
112 #define CAN_MCAN_ECR_RP BIT(15)
113 #define CAN_MCAN_ECR_REC GENMASK(14, 8)
114 #define CAN_MCAN_ECR_TEC GENMASK(7, 0)
115
116 /* Protocol Status register */
117 #define CAN_MCAN_PSR 0x044
118 #define CAN_MCAN_PSR_TDCV GENMASK(22, 16)
119 #define CAN_MCAN_PSR_PXE BIT(14)
120 #define CAN_MCAN_PSR_RFDF BIT(13)
121 #define CAN_MCAN_PSR_RBRS BIT(12)
122 #define CAN_MCAN_PSR_RESI BIT(11)
123 #define CAN_MCAN_PSR_DLEC GENMASK(10, 8)
124 #define CAN_MCAN_PSR_BO BIT(7)
125 #define CAN_MCAN_PSR_EW BIT(6)
126 #define CAN_MCAN_PSR_EP BIT(5)
127 #define CAN_MCAN_PSR_ACT GENMASK(4, 3)
128 #define CAN_MCAN_PSR_LEC GENMASK(2, 0)
129
130 enum can_mcan_psr_lec {
131 CAN_MCAN_PSR_LEC_NO_ERROR = 0,
132 CAN_MCAN_PSR_LEC_STUFF_ERROR = 1,
133 CAN_MCAN_PSR_LEC_FORM_ERROR = 2,
134 CAN_MCAN_PSR_LEC_ACK_ERROR = 3,
135 CAN_MCAN_PSR_LEC_BIT1_ERROR = 4,
136 CAN_MCAN_PSR_LEC_BIT0_ERROR = 5,
137 CAN_MCAN_PSR_LEC_CRC_ERROR = 6,
138 CAN_MCAN_PSR_LEC_NO_CHANGE = 7
139 };
140
141 /* Transmitter Delay Compensation register */
142 #define CAN_MCAN_TDCR 0x048
143 #define CAN_MCAN_TDCR_TDCO GENMASK(14, 8)
144 #define CAN_MCAN_TDCR_TDCF GENMASK(6, 0)
145
146 /* Interrupt register */
147 #define CAN_MCAN_IR 0x050
148 #define CAN_MCAN_IR_ARA BIT(29)
149 #define CAN_MCAN_IR_PED BIT(28)
150 #define CAN_MCAN_IR_PEA BIT(27)
151 #define CAN_MCAN_IR_WDI BIT(26)
152 #define CAN_MCAN_IR_BO BIT(25)
153 #define CAN_MCAN_IR_EW BIT(24)
154 #define CAN_MCAN_IR_EP BIT(23)
155 #define CAN_MCAN_IR_ELO BIT(22)
156 #define CAN_MCAN_IR_BEU BIT(21)
157 #define CAN_MCAN_IR_BEC BIT(20)
158 #define CAN_MCAN_IR_DRX BIT(19)
159 #define CAN_MCAN_IR_TOO BIT(18)
160 #define CAN_MCAN_IR_MRAF BIT(17)
161 #define CAN_MCAN_IR_TSW BIT(16)
162 #define CAN_MCAN_IR_TEFL BIT(15)
163 #define CAN_MCAN_IR_TEFF BIT(14)
164 #define CAN_MCAN_IR_TEFW BIT(13)
165 #define CAN_MCAN_IR_TEFN BIT(12)
166 #define CAN_MCAN_IR_TFE BIT(11)
167 #define CAN_MCAN_IR_TCF BIT(10)
168 #define CAN_MCAN_IR_TC BIT(9)
169 #define CAN_MCAN_IR_HPM BIT(8)
170 #define CAN_MCAN_IR_RF1L BIT(7)
171 #define CAN_MCAN_IR_RF1F BIT(6)
172 #define CAN_MCAN_IR_RF1W BIT(5)
173 #define CAN_MCAN_IR_RF1N BIT(4)
174 #define CAN_MCAN_IR_RF0L BIT(3)
175 #define CAN_MCAN_IR_RF0F BIT(2)
176 #define CAN_MCAN_IR_RF0W BIT(1)
177 #define CAN_MCAN_IR_RF0N BIT(0)
178
179 /* Interrupt Enable register */
180 #define CAN_MCAN_IE 0x054
181 #define CAN_MCAN_IE_ARAE BIT(29)
182 #define CAN_MCAN_IE_PEDE BIT(28)
183 #define CAN_MCAN_IE_PEAE BIT(27)
184 #define CAN_MCAN_IE_WDIE BIT(26)
185 #define CAN_MCAN_IE_BOE BIT(25)
186 #define CAN_MCAN_IE_EWE BIT(24)
187 #define CAN_MCAN_IE_EPE BIT(23)
188 #define CAN_MCAN_IE_ELOE BIT(22)
189 #define CAN_MCAN_IE_BEUE BIT(21)
190 #define CAN_MCAN_IE_BECE BIT(20)
191 #define CAN_MCAN_IE_DRXE BIT(19)
192 #define CAN_MCAN_IE_TOOE BIT(18)
193 #define CAN_MCAN_IE_MRAFE BIT(17)
194 #define CAN_MCAN_IE_TSWE BIT(16)
195 #define CAN_MCAN_IE_TEFLE BIT(15)
196 #define CAN_MCAN_IE_TEFFE BIT(14)
197 #define CAN_MCAN_IE_TEFWE BIT(13)
198 #define CAN_MCAN_IE_TEFNE BIT(12)
199 #define CAN_MCAN_IE_TFEE BIT(11)
200 #define CAN_MCAN_IE_TCFE BIT(10)
201 #define CAN_MCAN_IE_TCE BIT(9)
202 #define CAN_MCAN_IE_HPME BIT(8)
203 #define CAN_MCAN_IE_RF1LE BIT(7)
204 #define CAN_MCAN_IE_RF1FE BIT(6)
205 #define CAN_MCAN_IE_RF1WE BIT(5)
206 #define CAN_MCAN_IE_RF1NE BIT(4)
207 #define CAN_MCAN_IE_RF0LE BIT(3)
208 #define CAN_MCAN_IE_RF0FE BIT(2)
209 #define CAN_MCAN_IE_RF0WE BIT(1)
210 #define CAN_MCAN_IE_RF0NE BIT(0)
211
212 /* Interrupt Line Select register */
213 #define CAN_MCAN_ILS 0x058
214 #define CAN_MCAN_ILS_ARAL BIT(29)
215 #define CAN_MCAN_ILS_PEDL BIT(28)
216 #define CAN_MCAN_ILS_PEAL BIT(27)
217 #define CAN_MCAN_ILS_WDIL BIT(26)
218 #define CAN_MCAN_ILS_BOL BIT(25)
219 #define CAN_MCAN_ILS_EWL BIT(24)
220 #define CAN_MCAN_ILS_EPL BIT(23)
221 #define CAN_MCAN_ILS_ELOL BIT(22)
222 #define CAN_MCAN_ILS_BEUL BIT(21)
223 #define CAN_MCAN_ILS_BECL BIT(20)
224 #define CAN_MCAN_ILS_DRXL BIT(19)
225 #define CAN_MCAN_ILS_TOOL BIT(18)
226 #define CAN_MCAN_ILS_MRAFL BIT(17)
227 #define CAN_MCAN_ILS_TSWL BIT(16)
228 #define CAN_MCAN_ILS_TEFLL BIT(15)
229 #define CAN_MCAN_ILS_TEFFL BIT(14)
230 #define CAN_MCAN_ILS_TEFWL BIT(13)
231 #define CAN_MCAN_ILS_TEFNL BIT(12)
232 #define CAN_MCAN_ILS_TFEL BIT(11)
233 #define CAN_MCAN_ILS_TCFL BIT(10)
234 #define CAN_MCAN_ILS_TCL BIT(9)
235 #define CAN_MCAN_ILS_HPML BIT(8)
236 #define CAN_MCAN_ILS_RF1LL BIT(7)
237 #define CAN_MCAN_ILS_RF1FL BIT(6)
238 #define CAN_MCAN_ILS_RF1WL BIT(5)
239 #define CAN_MCAN_ILS_RF1NL BIT(4)
240 #define CAN_MCAN_ILS_RF0LL BIT(3)
241 #define CAN_MCAN_ILS_RF0FL BIT(2)
242 #define CAN_MCAN_ILS_RF0WL BIT(1)
243 #define CAN_MCAN_ILS_RF0NL BIT(0)
244
245 /* Interrupt Line Enable register */
246 #define CAN_MCAN_ILE 0x05C
247 #define CAN_MCAN_ILE_EINT1 BIT(1)
248 #define CAN_MCAN_ILE_EINT0 BIT(0)
249
250 /* Global filter configuration register */
251 #define CAN_MCAN_GFC 0x080
252 #define CAN_MCAN_GFC_ANFS GENMASK(5, 4)
253 #define CAN_MCAN_GFC_ANFE GENMASK(3, 2)
254 #define CAN_MCAN_GFC_RRFS BIT(1)
255 #define CAN_MCAN_GFC_RRFE BIT(0)
256
257 /* Standard ID Filter Configuration register */
258 #define CAN_MCAN_SIDFC 0x084
259 #define CAN_MCAN_SIDFC_LSS GENMASK(23, 16)
260 #define CAN_MCAN_SIDFC_FLSSA GENMASK(15, 2)
261
262 /* Extended ID Filter Configuration register */
263 #define CAN_MCAN_XIDFC 0x088
264 #define CAN_MCAN_XIDFC_LSS GENMASK(22, 16)
265 #define CAN_MCAN_XIDFC_FLESA GENMASK(15, 2)
266
267 /* Extended ID AND Mask register */
268 #define CAN_MCAN_XIDAM 0x090
269 #define CAN_MCAN_XIDAM_EIDM GENMASK(28, 0)
270
271 /* High Priority Message Status register */
272 #define CAN_MCAN_HPMS 0x094
273 #define CAN_MCAN_HPMS_FLST BIT(15)
274 #define CAN_MCAN_HPMS_FIDX GENMASK(14, 8)
275 #define CAN_MCAN_HPMS_MSI GENMASK(7, 6)
276 #define CAN_MCAN_HPMS_BIDX GENMASK(5, 0)
277
278 /* New Data 1 register */
279 #define CAN_MCAN_NDAT1 0x098
280 #define CAN_MCAN_NDAT1_ND GENMASK(31, 0)
281
282 /* New Data 2 register */
283 #define CAN_MCAN_NDAT2 0x09C
284 #define CAN_MCAN_NDAT2_ND GENMASK(31, 0)
285
286 /* Rx FIFO 0 Configuration register */
287 #define CAN_MCAN_RXF0C 0x0A0
288 #define CAN_MCAN_RXF0C_F0OM BIT(31)
289 #define CAN_MCAN_RXF0C_F0WM GENMASK(30, 24)
290 #define CAN_MCAN_RXF0C_F0S GENMASK(22, 16)
291 #define CAN_MCAN_RXF0C_F0SA GENMASK(15, 2)
292
293 /* Rx FIFO 0 Status register */
294 #define CAN_MCAN_RXF0S 0x0A4
295 #define CAN_MCAN_RXF0S_RF0L BIT(25)
296 #define CAN_MCAN_RXF0S_F0F BIT(24)
297 #define CAN_MCAN_RXF0S_F0PI GENMASK(21, 16)
298 #define CAN_MCAN_RXF0S_F0GI GENMASK(13, 8)
299 #define CAN_MCAN_RXF0S_F0FL GENMASK(6, 0)
300
301 /* Rx FIFO 0 Acknowledge register */
302 #define CAN_MCAN_RXF0A 0x0A8
303 #define CAN_MCAN_RXF0A_F0AI GENMASK(5, 0)
304
305 /* Rx Buffer Configuration register */
306 #define CAN_MCAN_RXBC 0x0AC
307 #define CAN_MCAN_RXBC_RBSA GENMASK(15, 2)
308
309 /* Rx FIFO 1 Configuration register */
310 #define CAN_MCAN_RXF1C 0x0B0
311 #define CAN_MCAN_RXF1C_F1OM BIT(31)
312 #define CAN_MCAN_RXF1C_F1WM GENMASK(30, 24)
313 #define CAN_MCAN_RXF1C_F1S GENMASK(22, 16)
314 #define CAN_MCAN_RXF1C_F1SA GENMASK(15, 2)
315
316 /* Rx FIFO 1 Status register */
317 #define CAN_MCAN_RXF1S 0x0B4
318 #define CAN_MCAN_RXF1S_RF1L BIT(25)
319 #define CAN_MCAN_RXF1S_F1F BIT(24)
320 #define CAN_MCAN_RXF1S_F1PI GENMASK(21, 16)
321 #define CAN_MCAN_RXF1S_F1GI GENMASK(13, 8)
322 #define CAN_MCAN_RXF1S_F1FL GENMASK(6, 0)
323
324 /* Rx FIFO 1 Acknowledge register */
325 #define CAN_MCAN_RXF1A 0x0B8
326 #define CAN_MCAN_RXF1A_F1AI GENMASK(5, 0)
327
328 /* Rx Buffer/FIFO Element Size Configuration register */
329 #define CAN_MCAN_RXESC 0x0BC
330 #define CAN_MCAN_RXESC_RBDS GENMASK(10, 8)
331 #define CAN_MCAN_RXESC_F1DS GENMASK(6, 4)
332 #define CAN_MCAN_RXESC_F0DS GENMASK(2, 0)
333
334 /* Tx Buffer Configuration register */
335 #define CAN_MCAN_TXBC 0x0C0
336 #define CAN_MCAN_TXBC_TFQM BIT(30)
337 #define CAN_MCAN_TXBC_TFQS GENMASK(29, 24)
338 #define CAN_MCAN_TXBC_NDTB GENMASK(21, 16)
339 #define CAN_MCAN_TXBC_TBSA GENMASK(15, 2)
340
341 /* Tx FIFO/Queue Status register */
342 #define CAN_MCAN_TXFQS 0x0C4
343 #define CAN_MCAN_TXFQS_TFQF BIT(21)
344 #define CAN_MCAN_TXFQS_TFQPI GENMASK(20, 16)
345 #define CAN_MCAN_TXFQS_TFGI GENMASK(12, 8)
346 #define CAN_MCAN_TXFQS_TFFL GENMASK(5, 0)
347
348 /* Tx Buffer Element Size Configuration register */
349 #define CAN_MCAN_TXESC 0x0C8
350 #define CAN_MCAN_TXESC_TBDS GENMASK(2, 0)
351
352 /* Tx Buffer Request Pending register */
353 #define CAN_MCAN_TXBRP 0x0CC
354 #define CAN_MCAN_TXBRP_TRP GENMASK(31, 0)
355
356 /* Tx Buffer Add Request register */
357 #define CAN_MCAN_TXBAR 0x0D0
358 #define CAN_MCAN_TXBAR_AR GENMASK(31, 0)
359
360 /* Tx Buffer Cancellation Request register */
361 #define CAN_MCAN_TXBCR 0x0D4
362 #define CAN_MCAN_TXBCR_CR GENMASK(31, 0)
363
364 /* Tx Buffer Transmission Occurred register */
365 #define CAN_MCAN_TXBTO 0x0D8
366 #define CAN_MCAN_TXBTO_TO GENMASK(31, 0)
367
368 /* Tx Buffer Cancellation Finished register */
369 #define CAN_MCAN_TXBCF 0x0DC
370 #define CAN_MCAN_TXBCF_CF GENMASK(31, 0)
371
372 /* Tx Buffer Transmission Interrupt Enable register */
373 #define CAN_MCAN_TXBTIE 0x0E0
374 #define CAN_MCAN_TXBTIE_TIE GENMASK(31, 0)
375
376 /* Tx Buffer Cancellation Finished Interrupt Enable register */
377 #define CAN_MCAN_TXBCIE 0x0E4
378 #define CAN_MCAN_TXBCIE_CFIE GENMASK(31, 0)
379
380 /* Tx Event FIFO Configuration register */
381 #define CAN_MCAN_TXEFC 0x0F0
382 #define CAN_MCAN_TXEFC_EFWM GENMASK(29, 24)
383 #define CAN_MCAN_TXEFC_EFS GENMASK(21, 16)
384 #define CAN_MCAN_TXEFC_EFSA GENMASK(15, 2)
385
386 /* Tx Event FIFO Status register */
387 #define CAN_MCAN_TXEFS 0x0F4
388 #define CAN_MCAN_TXEFS_TEFL BIT(25)
389 #define CAN_MCAN_TXEFS_EFF BIT(24)
390 #define CAN_MCAN_TXEFS_EFPI GENMASK(20, 16)
391 #define CAN_MCAN_TXEFS_EFGI GENMASK(12, 8)
392 #define CAN_MCAN_TXEFS_EFFL GENMASK(5, 0)
393
394 /* Tx Event FIFO Acknowledge register */
395 #define CAN_MCAN_TXEFA 0x0F8
396 #define CAN_MCAN_TXEFA_EFAI GENMASK(4, 0)
397
398 /**
399 * @name Indexes for the cells in the devicetree bosch,mram-cfg property
400 * @anchor CAN_MCAN_MRAM_CFG
401
402 * These match the description of the cells in the bosch,m_can-base devicetree binding.
403 *
404 * @{
405 */
406 /** offset cell index */
407 #define CAN_MCAN_MRAM_CFG_OFFSET 0
408 /** std-filter-elements cell index */
409 #define CAN_MCAN_MRAM_CFG_STD_FILTER 1
410 /** ext-filter-elements cell index */
411 #define CAN_MCAN_MRAM_CFG_EXT_FILTER 2
412 /** rx-fifo0-elements cell index */
413 #define CAN_MCAN_MRAM_CFG_RX_FIFO0 3
414 /** rx-fifo1-elements cell index */
415 #define CAN_MCAN_MRAM_CFG_RX_FIFO1 4
416 /** rx-buffer-elements cell index */
417 #define CAN_MCAN_MRAM_CFG_RX_BUFFER 5
418 /** tx-event-fifo-elements cell index */
419 #define CAN_MCAN_MRAM_CFG_TX_EVENT_FIFO 6
420 /** tx-buffer-elements cell index */
421 #define CAN_MCAN_MRAM_CFG_TX_BUFFER 7
422 /** Total number of cells in bosch,mram-cfg property */
423 #define CAN_MCAN_MRAM_CFG_NUM_CELLS 8
424
425 /** @} */
426
427 /**
428 * @brief Get the Bosch M_CAN Message RAM offset
429 *
430 * @param node_id node identifier
431 * @return the Message RAM offset in bytes
432 */
433 #define CAN_MCAN_DT_MRAM_OFFSET(node_id) \
434 DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_OFFSET)
435
436 /**
437 * @brief Get the number of standard (11-bit) filter elements in Bosch M_CAN Message RAM
438 *
439 * @param node_id node identifier
440 * @return the number of standard (11-bit) filter elements
441 */
442 #define CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id) \
443 DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_STD_FILTER)
444
445 /**
446 * @brief Get the number of extended (29-bit) filter elements in Bosch M_CAN Message RAM
447 *
448 * @param node_id node identifier
449 * @return the number of extended (29-bit) filter elements
450 */
451 #define CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id) \
452 DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_EXT_FILTER)
453
454 /**
455 * @brief Get the number of Rx FIFO 0 elements in Bosch M_CAN Message RAM
456 *
457 * @param node_id node identifier
458 * @return the number of Rx FIFO 0 elements
459 */
460 #define CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id) \
461 DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_RX_FIFO0)
462
463 /**
464 * @brief Get the number of Rx FIFO 1 elements in Bosch M_CAN Message RAM
465 *
466 * @param node_id node identifier
467 * @return the number of Rx FIFO 1 elements
468 */
469 #define CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id) \
470 DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_RX_FIFO1)
471
472 /**
473 * @brief Get the number of Rx Buffer elements in Bosch M_CAN Message RAM
474 *
475 * @param node_id node identifier
476 * @return the number of Rx Buffer elements
477 */
478 #define CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id) \
479 DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_RX_BUFFER)
480
481 /**
482 * @brief Get the number of Tx Event FIFO elements in Bosch M_CAN Message RAM
483 *
484 * @param node_id node identifier
485 * @return the number of Tx Event FIFO elements
486 */
487 #define CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id) \
488 DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_TX_EVENT_FIFO)
489
490 /**
491 * @brief Get the number of Tx Buffer elements in Bosch M_CAN Message RAM
492 *
493 * @param node_id node identifier
494 * @return the number of Tx Buffer elements
495 */
496 #define CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) \
497 DT_PROP_BY_IDX(node_id, bosch_mram_cfg, CAN_MCAN_MRAM_CFG_TX_BUFFER)
498
499 /**
500 * @brief Get the base offset of standard (11-bit) filter elements in Bosch M_CAN Message RAM
501 *
502 * @param node_id node identifier
503 * @return the base offset of standard (11-bit) filter elements in bytes
504 */
505 #define CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id) (0U)
506
507 /**
508 * @brief Get the base offset of extended (29-bit) filter elements in Bosch M_CAN Message RAM
509 *
510 * @param node_id node identifier
511 * @return the base offset of extended (29-bit) filter elements in bytes
512 */
513 #define CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id) \
514 (CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id) + \
515 CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id) * sizeof(struct can_mcan_std_filter))
516
517 /**
518 * @brief Get the base offset of Rx FIFO 0 elements in Bosch M_CAN Message RAM
519 *
520 * @param node_id node identifier
521 * @return the base offset of Rx FIFO 0 elements in bytes
522 */
523 #define CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id) \
524 (CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id) + \
525 CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id) * sizeof(struct can_mcan_ext_filter))
526
527 /**
528 * @brief Get the base offset of Rx FIFO 1 elements in Bosch M_CAN Message RAM
529 *
530 * @param node_id node identifier
531 * @return the base offset of Rx FIFO 1 elements in bytes
532 */
533 #define CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id) \
534 (CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id) + \
535 CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id) * sizeof(struct can_mcan_rx_fifo))
536
537 /**
538 * @brief Get the base offset of Rx Buffer elements in Bosch M_CAN Message RAM
539 *
540 * @param node_id node identifier
541 * @return the base offset of Rx Buffer elements in bytes
542 */
543 #define CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id) \
544 (CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id) + \
545 CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id) * sizeof(struct can_mcan_rx_fifo))
546
547 /**
548 * @brief Get the base offset of Tx Event FIFO elements in Bosch M_CAN Message RAM
549 *
550 * @param node_id node identifier
551 * @return the base offset of Tx Event FIFO elements in bytes
552 */
553 #define CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id) \
554 (CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id) + \
555 CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id) * sizeof(struct can_mcan_rx_fifo))
556
557 /**
558 * @brief Get the base offset of Tx Buffer elements in Bosch M_CAN Message RAM
559 *
560 * @param node_id node identifier
561 * @return the base offset of Tx Buffer elements in bytes
562 */
563 #define CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id) \
564 (CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id) + \
565 CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id) * sizeof(struct can_mcan_tx_event_fifo))
566
567 /**
568 * @brief Get the Bosch M_CAN register base address
569 *
570 * For devicetree nodes with just one register block, this macro returns the base address of that
571 * register block.
572 *
573 * If a devicetree node has more than one register block, this macros returns the base address of
574 * the register block named "m_can".
575 *
576 * @param node_id node identifier
577 * @return the Bosch M_CAN register base address
578 */
579 #define CAN_MCAN_DT_MCAN_ADDR(node_id) \
580 COND_CODE_1(DT_NUM_REGS(node_id), ((mm_reg_t)DT_REG_ADDR(node_id)), \
581 ((mm_reg_t)DT_REG_ADDR_BY_NAME(node_id, m_can)))
582
583 /**
584 * @brief Get the Bosch M_CAN Message RAM base address
585 *
586 * For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns
587 * the base address of the Message RAM.
588 *
589 * @param node_id node identifier
590 * @return the Bosch M_CAN Message RAM base address (MRBA)
591 */
592 #define CAN_MCAN_DT_MRBA(node_id) \
593 (mem_addr_t)DT_REG_ADDR_BY_NAME(node_id, message_ram)
594
595 /**
596 * @brief Get the Bosch M_CAN Message RAM address
597 *
598 * For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns
599 * the address of the Message RAM, taking in the Message RAM offset into account.
600 *
601 * @param node_id node identifier
602 * @return the Bosch M_CAN Message RAM address
603 */
604 #define CAN_MCAN_DT_MRAM_ADDR(node_id) \
605 (mem_addr_t)(CAN_MCAN_DT_MRBA(node_id) + CAN_MCAN_DT_MRAM_OFFSET(node_id))
606
607 /**
608 * @brief Get the Bosch M_CAN Message RAM size
609 *
610 * For devicetree nodes with dedicated Message RAM area defined via devicetree, this macro returns
611 * the size of the Message RAM, taking in the Message RAM offset into account.
612 *
613 * @param node_id node identifier
614 * @return the Bosch M_CAN Message RAM base address
615 * @see CAN_MCAN_DT_MRAM_ELEMENTS_SIZE()
616 */
617 #define CAN_MCAN_DT_MRAM_SIZE(node_id) \
618 (mem_addr_t)(DT_REG_SIZE_BY_NAME(node_id, message_ram) - CAN_MCAN_DT_MRAM_OFFSET(node_id))
619
620 /**
621 * @brief Get the total size of all Bosch M_CAN Message RAM elements
622 *
623 * @param node_id node identifier
624 * @return the total size of all Message RAM elements in bytes
625 * @see CAN_MCAN_DT_MRAM_SIZE()
626 */
627 #define CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id) \
628 (CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id) + \
629 CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) * sizeof(struct can_mcan_tx_buffer))
630
631 /**
632 * @brief Define a RAM buffer for Bosch M_CAN Message RAM
633 *
634 * For devicetree nodes without dedicated Message RAM area, this macro defines a suitable RAM buffer
635 * to hold the Message RAM elements. Since this buffer cannot be shared between multiple Bosch M_CAN
636 * instances, the Message RAM offset must be set to 0x0.
637 *
638 * @param node_id node identifier
639 * @param _name buffer variable name
640 */
641 #define CAN_MCAN_DT_MRAM_DEFINE(node_id, _name) \
642 BUILD_ASSERT(CAN_MCAN_DT_MRAM_OFFSET(node_id) == 0, "offset must be 0"); \
643 static char __noinit __nocache __aligned(4) _name[CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id)];
644
645 /**
646 * @brief Assert that the Message RAM configuration meets the Bosch M_CAN IP core restrictions
647 *
648 * @param node_id node identifier
649 */
650 #define CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG(node_id) \
651 BUILD_ASSERT(CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id) <= 128, \
652 "Maximum Standard filter elements exceeded"); \
653 BUILD_ASSERT(CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id) <= 64, \
654 "Maximum Extended filter elements exceeded"); \
655 BUILD_ASSERT(CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id) <= 64, \
656 "Maximum Rx FIFO 0 elements exceeded"); \
657 BUILD_ASSERT(CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id) <= 64, \
658 "Maximum Rx FIFO 1 elements exceeded"); \
659 BUILD_ASSERT(CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id) <= 64, \
660 "Maximum Rx Buffer elements exceeded"); \
661 BUILD_ASSERT(CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id) <= 32, \
662 "Maximum Tx Buffer elements exceeded"); \
663 BUILD_ASSERT(CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) <= 32, \
664 "Maximum Tx Buffer elements exceeded");
665
666 /**
667 * @brief Equivalent to CAN_MCAN_DT_MRAM_OFFSET(DT_DRV_INST(inst))
668 * @param inst DT_DRV_COMPAT instance number
669 * @return the Message RAM offset in bytes
670 * @see CAN_MCAN_DT_MRAM_OFFSET()
671 */
672 #define CAN_MCAN_DT_INST_MRAM_OFFSET(inst) CAN_MCAN_DT_MRAM_OFFSET(DT_DRV_INST(inst))
673
674 /**
675 * @brief Equivalent to CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(DT_DRV_INST(inst))
676 * @param inst DT_DRV_COMPAT instance number
677 * @return the number of standard (11-bit) elements
678 * @see CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS()
679 */
680 #define CAN_MCAN_DT_INST_MRAM_STD_FILTER_ELEMENTS(inst) \
681 CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(DT_DRV_INST(inst))
682
683 /**
684 * @brief Equivalent to CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(DT_DRV_INST(inst))
685 * @param inst DT_DRV_COMPAT instance number
686 * @return the number of extended (29-bit) elements
687 * @see CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS()
688 */
689 #define CAN_MCAN_DT_INST_MRAM_EXT_FILTER_ELEMENTS(inst) \
690 CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(DT_DRV_INST(inst))
691
692 /**
693 * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(DT_DRV_INST(inst))
694 * @param inst DT_DRV_COMPAT instance number
695 * @return the number of Rx FIFO 0 elements
696 * @see CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS()
697 */
698 #define CAN_MCAN_DT_INST_MRAM_RX_FIFO0_ELEMENTS(inst) \
699 CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(DT_DRV_INST(inst))
700
701 /**
702 * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(DT_DRV_INST(inst))
703 * @param inst DT_DRV_COMPAT instance number
704 * @return the number of Rx FIFO 1 elements
705 * @see CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS()
706 */
707 #define CAN_MCAN_DT_INST_MRAM_RX_FIFO1_ELEMENTS(inst) \
708 CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(DT_DRV_INST(inst))
709
710 /**
711 * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
712 * @param inst DT_DRV_COMPAT instance number
713 * @return the number of Rx Buffer elements
714 * @see CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS()
715 */
716 #define CAN_MCAN_DT_INST_MRAM_RX_BUFFER_ELEMENTS(inst) \
717 CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
718
719 /**
720 * @brief Equivalent to CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(DT_DRV_INST(inst))
721 * @param inst DT_DRV_COMPAT instance number
722 * @return the number of Tx Event FIFO elements
723 * @see CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS()
724 */
725 #define CAN_MCAN_DT_INST_MRAM_TX_EVENT_FIFO_ELEMENTS(inst) \
726 CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(DT_DRV_INST(inst))
727
728 /**
729 * @brief Equivalent to CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
730 * @param inst DT_DRV_COMPAT instance number
731 * @return the number of Tx Buffer elements
732 * @see CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS()
733 */
734 #define CAN_MCAN_DT_INST_MRAM_TX_BUFFER_ELEMENTS(inst) \
735 CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(DT_DRV_INST(inst))
736
737 /**
738 * @brief Equivalent to CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(DT_DRV_INST(inst))
739 * @param inst DT_DRV_COMPAT instance number
740 * @return the base offset of standard (11-bit) filter elements in bytes
741 * @see CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET()
742 */
743 #define CAN_MCAN_DT_INST_MRAM_STD_FILTER_OFFSET(inst) \
744 CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(DT_DRV_INST(inst))
745
746 /**
747 * @brief Equivalent to CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(DT_DRV_INST(inst))
748 * @param inst DT_DRV_COMPAT instance number
749 * @return the base offset of extended (29-bit) filter elements in bytes
750 * @see CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET()
751 */
752 #define CAN_MCAN_DT_INST_MRAM_EXT_FILTER_OFFSET(inst) \
753 CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(DT_DRV_INST(inst))
754
755 /**
756 * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(DT_DRV_INST(inst))
757 * @param inst DT_DRV_COMPAT instance number
758 * @return the base offset of Rx FIFO 0 elements in bytes
759 * @see CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET()
760 */
761 #define CAN_MCAN_DT_INST_MRAM_RX_FIFO0_OFFSET(inst) \
762 CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(DT_DRV_INST(inst))
763
764 /**
765 * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(DT_DRV_INST(inst))
766 * @param inst DT_DRV_COMPAT instance number
767 * @return the base offset of Rx FIFO 1 elements in bytes
768 * @see CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET()
769 */
770 #define CAN_MCAN_DT_INST_MRAM_RX_FIFO1_OFFSET(inst) \
771 CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(DT_DRV_INST(inst))
772
773 /**
774 * @brief Equivalent to CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(DT_DRV_INST(inst))
775 * @param inst DT_DRV_COMPAT instance number
776 * @return the base offset of Rx Buffer elements in bytes
777 * @see CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET()
778 */
779 #define CAN_MCAN_DT_INST_MRAM_RX_BUFFER_OFFSET(inst) \
780 CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(DT_DRV_INST(inst))
781
782 /**
783 * @brief Equivalent to CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(DT_DRV_INST(inst))
784 * @param inst DT_DRV_COMPAT instance number
785 * @return the base offset of Tx Event FIFO elements in bytes
786 * @see CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET()
787 */
788 #define CAN_MCAN_DT_INST_MRAM_TX_EVENT_FIFO_OFFSET(inst) \
789 CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(DT_DRV_INST(inst))
790
791 /**
792 * @brief Equivalent to CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(DT_DRV_INST(inst))
793 * @param inst DT_DRV_COMPAT instance number
794 * @return the base offset of Tx Buffer elements in bytes
795 * @see CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET()
796 */
797 #define CAN_MCAN_DT_INST_MRAM_TX_BUFFER_OFFSET(inst) \
798 CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(DT_DRV_INST(inst))
799
800 /**
801 * @brief Equivalent to CAN_MCAN_DT_MCAN_ADDR(DT_DRV_INST(inst))
802 * @param inst DT_DRV_COMPAT instance number
803 * @return the Bosch M_CAN register base address
804 * @see CAN_MCAN_DT_MRAM_ADDR()
805 */
806 #define CAN_MCAN_DT_INST_MCAN_ADDR(inst) CAN_MCAN_DT_MCAN_ADDR(DT_DRV_INST(inst))
807
808 /**
809 * @brief Equivalent to CAN_MCAN_DT_MRBA(DT_DRV_INST(inst))
810 * @param inst DT_DRV_COMPAT instance number
811 * @return the Bosch M_CAN Message RAM Base Address (MRBA)
812 * @see CAN_MCAN_DT_MRBA()
813 */
814 #define CAN_MCAN_DT_INST_MRBA(inst) CAN_MCAN_DT_MRBA(DT_DRV_INST(inst))
815
816 /**
817 * @brief Equivalent to CAN_MCAN_DT_MRAM_ADDR(DT_DRV_INST(inst))
818 * @param inst DT_DRV_COMPAT instance number
819 * @return the Bosch M_CAN Message RAM address
820 * @see CAN_MCAN_DT_MRAM_ADDR()
821 */
822 #define CAN_MCAN_DT_INST_MRAM_ADDR(inst) CAN_MCAN_DT_MRAM_ADDR(DT_DRV_INST(inst))
823
824 /**
825 * @brief Equivalent to CAN_MCAN_DT_MRAM_SIZE(DT_DRV_INST(inst))
826 * @param inst DT_DRV_COMPAT instance number
827 * @return the Bosch M_CAN Message RAM size in bytes
828 * @see CAN_MCAN_DT_MRAM_SIZE()
829 */
830 #define CAN_MCAN_DT_INST_MRAM_SIZE(inst) CAN_MCAN_DT_MRAM_SIZE(DT_DRV_INST(inst))
831
832 /**
833 * @brief Equivalent to CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(DT_DRV_INST(inst))
834 * @param inst DT_DRV_COMPAT instance number
835 * @return the total size of all Message RAM elements in bytes
836 * @see CAN_MCAN_DT_MRAM_ELEMENTS_SIZE()
837 */
838 #define CAN_MCAN_DT_INST_MRAM_ELEMENTS_SIZE(inst) CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(DT_DRV_INST(inst))
839
840 /**
841 * @brief Equivalent to CAN_MCAN_DT_MRAM_DEFINE(DT_DRV_INST(inst))
842 * @param inst DT_DRV_COMPAT instance number
843 * @param _name buffer variable name
844 * @see CAN_MCAN_DT_MRAM_DEFINE()
845 */
846 #define CAN_MCAN_DT_INST_MRAM_DEFINE(inst, _name) CAN_MCAN_DT_MRAM_DEFINE(DT_DRV_INST(inst), _name)
847
848 /**
849 * @brief Bosch M_CAN specific static initializer for a minimum nominal @p can_timing struct
850 */
851 #define CAN_MCAN_TIMING_MIN_INITIALIZER \
852 { \
853 .sjw = 1, \
854 .prop_seg = 0, \
855 .phase_seg1 = 2, \
856 .phase_seg2 = 2, \
857 .prescaler = 1 \
858 }
859
860 /**
861 * @brief Bosch M_CAN specific static initializer for a maximum nominal @p can_timing struct
862 */
863 #define CAN_MCAN_TIMING_MAX_INITIALIZER \
864 { \
865 .sjw = 128, \
866 .prop_seg = 0, \
867 .phase_seg1 = 256, \
868 .phase_seg2 = 128, \
869 .prescaler = 512 \
870 }
871
872 /**
873 * @brief Bosch M_CAN specific static initializer for a minimum data phase @p can_timing struct
874 */
875 #define CAN_MCAN_TIMING_DATA_MIN_INITIALIZER \
876 { \
877 .sjw = 1, \
878 .prop_seg = 0, \
879 .phase_seg1 = 1, \
880 .phase_seg2 = 1, \
881 .prescaler = 1 \
882 }
883
884 /**
885 * @brief Bosch M_CAN specific static initializer for a maximum data phase @p can_timing struct
886 */
887 #define CAN_MCAN_TIMING_DATA_MAX_INITIALIZER \
888 { \
889 .sjw = 16, \
890 .prop_seg = 0, \
891 .phase_seg1 = 32, \
892 .phase_seg2 = 16, \
893 .prescaler = 32 \
894 }
895
896 /**
897 * @brief Equivalent to CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG(DT_DRV_INST(inst))
898 * @param inst DT_DRV_COMPAT instance number
899 * @see CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG()
900 */
901 #define CAN_MCAN_DT_INST_BUILD_ASSERT_MRAM_CFG(inst) \
902 CAN_MCAN_DT_BUILD_ASSERT_MRAM_CFG(DT_DRV_INST(inst))
903
904 /**
905 * @brief Bosch M_CAN Rx Buffer and FIFO Element header
906 *
907 * See Bosch M_CAN Users Manual section 2.4.2 for details.
908 */
909 struct can_mcan_rx_fifo_hdr {
910 union {
911 struct {
912 uint32_t ext_id: 29;
913 uint32_t rtr: 1;
914 uint32_t xtd: 1;
915 uint32_t esi: 1;
916 };
917 struct {
918 uint32_t pad1: 18;
919 uint32_t std_id: 11;
920 uint32_t pad2: 3;
921 };
922 };
923 uint32_t rxts: 16;
924 uint32_t dlc: 4;
925 uint32_t brs: 1;
926 uint32_t fdf: 1;
927 uint32_t res: 2;
928 uint32_t fidx: 7;
929 uint32_t anmf: 1;
930 } __packed __aligned(4);
931
932 /**
933 * @brief Bosch M_CAN Rx Buffer and FIFO Element
934 *
935 * See Bosch M_CAN Users Manual section 2.4.2 for details.
936 */
937 struct can_mcan_rx_fifo {
938 struct can_mcan_rx_fifo_hdr hdr;
939 union {
940 uint8_t data[64];
941 uint32_t data_32[16];
942 };
943 } __packed __aligned(4);
944
945 /**
946 * @brief Bosch M_CAN Tx Buffer Element header
947 *
948 * See Bosch M_CAN Users Manual section 2.4.3 for details.
949 */
950 struct can_mcan_tx_buffer_hdr {
951 union {
952 struct {
953 uint32_t ext_id: 29;
954 uint32_t rtr: 1;
955 uint32_t xtd: 1;
956 uint32_t esi: 1;
957 };
958 struct {
959 uint32_t pad1: 18;
960 uint32_t std_id: 11;
961 uint32_t pad2: 3;
962 };
963 };
964 uint16_t res1;
965 uint8_t dlc: 4;
966 uint8_t brs: 1;
967 uint8_t fdf: 1;
968 uint8_t tsce: 1;
969 uint8_t efc: 1;
970 uint8_t mm;
971 } __packed __aligned(4);
972
973 /**
974 * @brief Bosch M_CAN Tx Buffer Element
975 *
976 * See Bosch M_CAN Users Manual section 2.4.3 for details.
977 */
978 struct can_mcan_tx_buffer {
979 struct can_mcan_tx_buffer_hdr hdr;
980 union {
981 uint8_t data[64];
982 uint32_t data_32[16];
983 };
984 } __packed __aligned(4);
985
986 /**
987 * @brief Bosch M_CAN Tx Event FIFO Element
988 *
989 * See Bosch M_CAN Users Manual section 2.4.4 for details.
990 */
991 struct can_mcan_tx_event_fifo {
992 union {
993 struct {
994 uint32_t ext_id: 29;
995 uint32_t rtr: 1;
996 uint32_t xtd: 1;
997 uint32_t esi: 1;
998 };
999 struct {
1000 uint32_t pad1: 18;
1001 uint32_t std_id: 11;
1002 uint32_t pad2: 3;
1003 };
1004 };
1005 uint16_t txts;
1006 uint8_t dlc: 4;
1007 uint8_t brs: 1;
1008 uint8_t fdf: 1;
1009 uint8_t et: 2;
1010 uint8_t mm;
1011 } __packed __aligned(4);
1012
1013 /* Bosch M_CAN Standard/Extended Filter Element Configuration (SFEC/EFEC) */
1014 #define CAN_MCAN_XFEC_DISABLE 0x0
1015 #define CAN_MCAN_XFEC_FIFO0 0x1
1016 #define CAN_MCAN_XFEC_FIFO1 0x2
1017 #define CAN_MCAN_XFEC_REJECT 0x3
1018 #define CAN_MCAN_XFEC_PRIO 0x4
1019 #define CAN_MCAN_XFEC_PRIO_FIFO0 0x5
1020 #define CAN_MCAN_XFEC_PRIO_FIFO1 0x7
1021
1022 /* Bosch M_CAN Standard Filter Type (SFT) */
1023 #define CAN_MCAN_SFT_RANGE 0x0
1024 #define CAN_MCAN_SFT_DUAL 0x1
1025 #define CAN_MCAN_SFT_CLASSIC 0x2
1026 #define CAN_MCAN_SFT_DISABLED 0x3
1027
1028 /**
1029 * @brief Bosch M_CAN Standard Message ID Filter Element
1030 *
1031 * See Bosch M_CAN Users Manual section 2.4.5 for details.
1032 */
1033 struct can_mcan_std_filter {
1034 uint32_t sfid2: 11;
1035 uint32_t res: 5;
1036 uint32_t sfid1: 11;
1037 uint32_t sfec: 3;
1038 uint32_t sft: 2;
1039 } __packed __aligned(4);
1040
1041 /* Bosch M_CAN Extended Filter Type (EFT) */
1042 #define CAN_MCAN_EFT_RANGE_XIDAM 0x0
1043 #define CAN_MCAN_EFT_DUAL 0x1
1044 #define CAN_MCAN_EFT_CLASSIC 0x2
1045 #define CAN_MCAN_EFT_RANGE 0x3
1046
1047 /**
1048 * @brief Bosch M_CAN Extended Message ID Filter Element
1049 *
1050 * See Bosch M_CAN Users Manual section 2.4.6 for details.
1051 */
1052 struct can_mcan_ext_filter {
1053 uint32_t efid1: 29;
1054 uint32_t efec: 3;
1055 uint32_t efid2: 29;
1056 uint32_t esync: 1;
1057 uint32_t eft: 2;
1058 } __packed __aligned(4);
1059
1060 /**
1061 * @brief Bosch M_CAN driver internal data structure.
1062 */
1063 struct can_mcan_data {
1064 struct k_mutex lock;
1065 struct k_sem tx_sem;
1066 struct k_mutex tx_mtx;
1067 can_state_change_callback_t state_change_cb;
1068 void *state_change_cb_data;
1069 bool started;
1070 #ifdef CONFIG_CAN_FD_MODE
1071 bool fd;
1072 #endif /* CONFIG_CAN_FD_MODE */
1073 void *custom;
1074 } __aligned(4);
1075
1076 /**
1077 * @brief Bosch M_CAN driver front-end callback for reading a register value
1078 *
1079 * @param dev Pointer to the device structure for the driver instance.
1080 * @param reg Register offset
1081 * @param[out] val Register value
1082 *
1083 * @retval 0 If successful.
1084 * @retval -ENOTSUP Register not supported.
1085 * @retval -EIO General input/output error.
1086 */
1087 typedef int (*can_mcan_read_reg_t)(const struct device *dev, uint16_t reg, uint32_t *val);
1088
1089 /**
1090 * @brief Bosch M_CAN driver front-end callback for writing a register value
1091 *
1092 * @param dev Pointer to the device structure for the driver instance.
1093 * @param reg Register offset
1094 * @param val Register value
1095 *
1096 * @retval 0 If successful.
1097 * @retval -ENOTSUP Register not supported.
1098 * @retval -EIO General input/output error.
1099 */
1100 typedef int (*can_mcan_write_reg_t)(const struct device *dev, uint16_t reg, uint32_t val);
1101
1102 /**
1103 * @brief Bosch M_CAN driver front-end callback for reading from Message RAM
1104 *
1105 * @param dev Pointer to the device structure for the driver instance.
1106 * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1107 * offset must be 32-bit aligned.
1108 * @param[out] dst Destination for the data read. The destination address must be 32-bit aligned.
1109 * @param len Number of bytes to read. Must be a multiple of 4.
1110 *
1111 * @retval 0 If successful.
1112 * @retval -EIO General input/output error.
1113 */
1114 typedef int (*can_mcan_read_mram_t)(const struct device *dev, uint16_t offset, void *dst,
1115 size_t len);
1116
1117 /**
1118 * @brief Bosch M_CAN driver front-end callback for writing to Message RAM
1119 *
1120 * @param dev Pointer to the device structure for the driver instance.
1121 * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1122 * offset must be 32-bit aligned.
1123 * @param src Source for the data to be written. The source address must be 32-bit aligned.
1124 * @param len Number of bytes to write. Must be a multiple of 4.
1125 *
1126 * @retval 0 If successful.
1127 * @retval -EIO General input/output error.
1128 */
1129 typedef int (*can_mcan_write_mram_t)(const struct device *dev, uint16_t offset, const void *src,
1130 size_t len);
1131
1132 /**
1133 * @brief Bosch M_CAN driver front-end callback for clearing Message RAM
1134 *
1135 * Clear Message RAM by writing 0 to all words.
1136 *
1137 * @param dev Pointer to the device structure for the driver instance.
1138 * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1139 * offset must be 32-bit aligned.
1140 * @param len Number of bytes to clear. Must be a multiple of 4.
1141 *
1142 * @retval 0 If successful.
1143 * @retval -EIO General input/output error.
1144 */
1145 typedef int (*can_mcan_clear_mram_t)(const struct device *dev, uint16_t offset, size_t len);
1146
1147 /**
1148 * @brief Bosch M_CAN driver front-end operations.
1149 */
1150 struct can_mcan_ops {
1151 can_mcan_read_reg_t read_reg;
1152 can_mcan_write_reg_t write_reg;
1153 can_mcan_read_mram_t read_mram;
1154 can_mcan_write_mram_t write_mram;
1155 can_mcan_clear_mram_t clear_mram;
1156 };
1157
1158 /**
1159 * @brief Bosch M_CAN driver internal Tx callback structure.
1160 */
1161 struct can_mcan_tx_callback {
1162 can_tx_callback_t function;
1163 void *user_data;
1164 };
1165
1166 /**
1167 * @brief Bosch M_CAN driver internal Rx callback structure.
1168 */
1169 struct can_mcan_rx_callback {
1170 can_rx_callback_t function;
1171 void *user_data;
1172 uint8_t flags;
1173 };
1174
1175 /**
1176 * @brief Bosch M_CAN driver internal Tx + Rx callbacks structure.
1177 */
1178 struct can_mcan_callbacks {
1179 struct can_mcan_tx_callback *tx;
1180 struct can_mcan_rx_callback *std;
1181 struct can_mcan_rx_callback *ext;
1182 uint8_t num_tx;
1183 uint8_t num_std;
1184 uint8_t num_ext;
1185 };
1186
1187 /**
1188 * @brief Define Bosch M_CAN TX and RX callbacks
1189 *
1190 * This macro allows a Bosch M_CAN driver frontend using a fixed Message RAM configuration to limit
1191 * the required software resources (e.g. limit the number of the standard (11-bit) or extended
1192 * (29-bit) filters in use).
1193 *
1194 * Frontend drivers supporting dynamic Message RAM configuration should use @ref
1195 * CAN_MCAN_DT_CALLBACKS_DEFINE() or @ref CAN_MCAN_DT_INST_CALLBACKS_DEFINE() instead.
1196 *
1197 * @param _name callbacks variable name
1198 * @param _tx Number of Tx callbacks
1199 * @param _std Number of standard (11-bit) filter callbacks
1200 * @param _ext Number of extended (29-bit) filter callbacks
1201 * @see CAN_MCAN_DT_CALLBACKS_DEFINE()
1202 */
1203 #define CAN_MCAN_CALLBACKS_DEFINE(_name, _tx, _std, _ext) \
1204 static struct can_mcan_tx_callback _name##_tx_cbs[_tx]; \
1205 static struct can_mcan_rx_callback _name##_std_cbs[_std]; \
1206 static struct can_mcan_rx_callback _name##_ext_cbs[_ext]; \
1207 static const struct can_mcan_callbacks _name = { \
1208 .tx = _name##_tx_cbs, \
1209 .std = _name##_std_cbs, \
1210 .ext = _name##_ext_cbs, \
1211 .num_tx = _tx, \
1212 .num_std = _std, \
1213 .num_ext = _ext, \
1214 }
1215
1216 /**
1217 * @brief Define Bosch M_CAN TX and RX callbacks
1218 * @param node_id node identifier
1219 * @param _name callbacks variable name
1220 * @see CAN_MCAN_CALLBACKS_DEFINE()
1221 */
1222 #define CAN_MCAN_DT_CALLBACKS_DEFINE(node_id, _name) \
1223 CAN_MCAN_CALLBACKS_DEFINE(_name, CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id), \
1224 CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id), \
1225 CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id))
1226
1227 /**
1228 * @brief Equivalent to CAN_MCAN_DT_CALLBACKS_DEFINE(DT_DRV_INST(inst))
1229 * @param inst DT_DRV_COMPAT instance number
1230 * @param _name callbacks variable name
1231 * @see CAN_MCAN_DT_CALLBACKS_DEFINE()
1232 */
1233 #define CAN_MCAN_DT_INST_CALLBACKS_DEFINE(inst, _name) \
1234 CAN_MCAN_DT_CALLBACKS_DEFINE(DT_DRV_INST(inst), _name)
1235
1236 /**
1237 * @brief Bosch M_CAN driver internal configuration structure.
1238 */
1239 struct can_mcan_config {
1240 const struct can_mcan_ops *ops;
1241 const struct can_mcan_callbacks *callbacks;
1242 uint16_t mram_elements[CAN_MCAN_MRAM_CFG_NUM_CELLS];
1243 uint16_t mram_offsets[CAN_MCAN_MRAM_CFG_NUM_CELLS];
1244 size_t mram_size;
1245 uint32_t bus_speed;
1246 uint16_t sjw;
1247 uint16_t sample_point;
1248 uint16_t prop_ts1;
1249 uint16_t ts2;
1250 #ifdef CONFIG_CAN_FD_MODE
1251 uint32_t bus_speed_data;
1252 uint16_t sample_point_data;
1253 uint8_t sjw_data;
1254 uint8_t prop_ts1_data;
1255 uint8_t ts2_data;
1256 uint8_t tx_delay_comp_offset;
1257 #endif
1258 const struct device *phy;
1259 uint32_t max_bitrate;
1260 const void *custom;
1261 };
1262
1263 /**
1264 * @brief Get an array containing the number of elements in Bosch M_CAN Message RAM
1265 *
1266 * The order of the array entries is given by the @ref CAN_MCAN_MRAM_CFG definitions.
1267 *
1268 * @param node_id node identifier
1269 * @return array of number of elements
1270 */
1271 #define CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id) \
1272 { \
1273 0, /* offset cell */ \
1274 CAN_MCAN_DT_MRAM_STD_FILTER_ELEMENTS(node_id), \
1275 CAN_MCAN_DT_MRAM_EXT_FILTER_ELEMENTS(node_id), \
1276 CAN_MCAN_DT_MRAM_RX_FIFO0_ELEMENTS(node_id), \
1277 CAN_MCAN_DT_MRAM_RX_FIFO1_ELEMENTS(node_id), \
1278 CAN_MCAN_DT_MRAM_RX_BUFFER_ELEMENTS(node_id), \
1279 CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_ELEMENTS(node_id), \
1280 CAN_MCAN_DT_MRAM_TX_BUFFER_ELEMENTS(node_id) \
1281 }
1282
1283 /**
1284 * @brief Get an array containing the base offsets for element in Bosch M_CAN Message RAM
1285 *
1286 * The order of the array entries is given by the @ref CAN_MCAN_MRAM_CFG definitions.
1287 *
1288 * @param node_id node identifier
1289 * @return array of base offsets for elements
1290 */
1291 #define CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id) \
1292 { \
1293 0, /* offset cell */ \
1294 CAN_MCAN_DT_MRAM_STD_FILTER_OFFSET(node_id), \
1295 CAN_MCAN_DT_MRAM_EXT_FILTER_OFFSET(node_id), \
1296 CAN_MCAN_DT_MRAM_RX_FIFO0_OFFSET(node_id), \
1297 CAN_MCAN_DT_MRAM_RX_FIFO1_OFFSET(node_id), \
1298 CAN_MCAN_DT_MRAM_RX_BUFFER_OFFSET(node_id), \
1299 CAN_MCAN_DT_MRAM_TX_EVENT_FIFO_OFFSET(node_id), \
1300 CAN_MCAN_DT_MRAM_TX_BUFFER_OFFSET(node_id) \
1301 }
1302
1303 /**
1304 * @brief Static initializer for @p can_mcan_config struct
1305 *
1306 * @param node_id Devicetree node identifier
1307 * @param _custom Pointer to custom driver frontend configuration structure
1308 * @param _ops Pointer to front-end @a can_mcan_ops
1309 * @param _cbs Pointer to front-end @a can_mcan_callbacks
1310 */
1311 #ifdef CONFIG_CAN_FD_MODE
1312 #define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops, _cbs) \
1313 { \
1314 .ops = _ops, \
1315 .callbacks = _cbs, \
1316 .mram_elements = CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id), \
1317 .mram_offsets = CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id), \
1318 .mram_size = CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id), \
1319 .bus_speed = DT_PROP(node_id, bus_speed), \
1320 .sjw = DT_PROP(node_id, sjw), \
1321 .sample_point = DT_PROP_OR(node_id, sample_point, 0), \
1322 .prop_ts1 = DT_PROP_OR(node_id, prop_seg, 0) + DT_PROP_OR(node_id, phase_seg1, 0), \
1323 .ts2 = DT_PROP_OR(node_id, phase_seg2, 0), \
1324 .bus_speed_data = DT_PROP(node_id, bus_speed_data), \
1325 .sjw_data = DT_PROP(node_id, sjw_data), \
1326 .sample_point_data = DT_PROP_OR(node_id, sample_point_data, 0), \
1327 .prop_ts1_data = DT_PROP_OR(node_id, prop_seg_data, 0) + \
1328 DT_PROP_OR(node_id, phase_seg1_data, 0), \
1329 .ts2_data = DT_PROP_OR(node_id, phase_seg2_data, 0), \
1330 .tx_delay_comp_offset = DT_PROP(node_id, tx_delay_comp_offset), \
1331 .phy = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, phys)), \
1332 .max_bitrate = DT_CAN_TRANSCEIVER_MAX_BITRATE(node_id, 8000000), \
1333 .custom = _custom, \
1334 }
1335 #else /* CONFIG_CAN_FD_MODE */
1336 #define CAN_MCAN_DT_CONFIG_GET(node_id, _custom, _ops, _cbs) \
1337 { \
1338 .ops = _ops, \
1339 .callbacks = _cbs, \
1340 .mram_elements = CAN_MCAN_DT_MRAM_ELEMENTS_GET(node_id), \
1341 .mram_offsets = CAN_MCAN_DT_MRAM_OFFSETS_GET(node_id), \
1342 .mram_size = CAN_MCAN_DT_MRAM_ELEMENTS_SIZE(node_id), \
1343 .bus_speed = DT_PROP(node_id, bus_speed), \
1344 .sjw = DT_PROP(node_id, sjw), \
1345 .sample_point = DT_PROP_OR(node_id, sample_point, 0), \
1346 .prop_ts1 = DT_PROP_OR(node_id, prop_seg, 0) + DT_PROP_OR(node_id, phase_seg1, 0), \
1347 .ts2 = DT_PROP_OR(node_id, phase_seg2, 0), \
1348 .phy = DEVICE_DT_GET_OR_NULL(DT_PHANDLE(node_id, phys)), \
1349 .max_bitrate = DT_CAN_TRANSCEIVER_MAX_BITRATE(node_id, 1000000), \
1350 .custom = _custom, \
1351 }
1352 #endif /* !CONFIG_CAN_FD_MODE */
1353
1354 /**
1355 * @brief Static initializer for @p can_mcan_config struct from DT_DRV_COMPAT instance
1356 *
1357 * @param inst DT_DRV_COMPAT instance number
1358 * @param _custom Pointer to custom driver frontend configuration structure
1359 * @param _ops Pointer to front-end @a can_mcan_ops
1360 * @param _cbs Pointer to front-end @a can_mcan_callbacks
1361 * @see CAN_MCAN_DT_CONFIG_GET()
1362 */
1363 #define CAN_MCAN_DT_CONFIG_INST_GET(inst, _custom, _ops, _cbs) \
1364 CAN_MCAN_DT_CONFIG_GET(DT_DRV_INST(inst), _custom, _ops, _cbs)
1365
1366 /**
1367 * @brief Initializer for a @a can_mcan_data struct
1368 * @param _custom Pointer to custom driver frontend data structure
1369 */
1370 #define CAN_MCAN_DATA_INITIALIZER(_custom) \
1371 { \
1372 .custom = _custom, \
1373 }
1374
1375 /**
1376 * @brief Bosch M_CAN driver front-end callback helper for reading a memory mapped register
1377 *
1378 * @param base Register base address
1379 * @param reg Register offset
1380 * @param[out] val Register value
1381 *
1382 * @retval 0 Memory mapped register read always succeeds.
1383 */
can_mcan_sys_read_reg(mm_reg_t base,uint16_t reg,uint32_t * val)1384 static inline int can_mcan_sys_read_reg(mm_reg_t base, uint16_t reg, uint32_t *val)
1385 {
1386 *val = sys_read32(base + reg);
1387
1388 return 0;
1389 }
1390
1391 /**
1392 * @brief Bosch M_CAN driver front-end callback helper for writing a memory mapped register
1393 *
1394 * @param base Register base address
1395 * @param reg Register offset
1396 * @param val Register value
1397 *
1398 * @retval 0 Memory mapped register write always succeeds.
1399 */
can_mcan_sys_write_reg(mm_reg_t base,uint16_t reg,uint32_t val)1400 static inline int can_mcan_sys_write_reg(mm_reg_t base, uint16_t reg, uint32_t val)
1401 {
1402 sys_write32(val, base + reg);
1403
1404 return 0;
1405 }
1406
1407 /**
1408 * @brief Bosch M_CAN driver front-end callback helper for reading from memory mapped Message RAM
1409 *
1410 * @param base Base address of the Message RAM for the given Bosch M_CAN instance. The base address
1411 * must be 32-bit aligned.
1412 * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1413 * offset must be 32-bit aligned.
1414 * @param[out] dst Destination for the data read. The destination address must be 32-bit aligned.
1415 * @param len Number of bytes to read. Must be a multiple of 4.
1416 *
1417 * @retval 0 If successful.
1418 * @retval -EIO General input/output error.
1419 */
can_mcan_sys_read_mram(mem_addr_t base,uint16_t offset,void * dst,size_t len)1420 static inline int can_mcan_sys_read_mram(mem_addr_t base, uint16_t offset, void *dst, size_t len)
1421 {
1422 volatile uint32_t *src32 = (volatile uint32_t *)(base + offset);
1423 uint32_t *dst32 = (uint32_t *)dst;
1424 size_t len32 = len / sizeof(uint32_t);
1425
1426 __ASSERT(base % 4U == 0U, "base must be a multiple of 4");
1427 __ASSERT(offset % 4U == 0U, "offset must be a multiple of 4");
1428 __ASSERT(POINTER_TO_UINT(dst) % 4U == 0U, "dst must be 32-bit aligned");
1429 __ASSERT(len % 4U == 0U, "len must be a multiple of 4");
1430
1431 #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
1432 int err;
1433
1434 err = sys_cache_data_invd_range((void *)(base + offset), len);
1435 if (err != 0) {
1436 return err;
1437 }
1438 #endif /* !defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1439
1440 while (len32-- > 0) {
1441 *dst32++ = *src32++;
1442 }
1443
1444 return 0;
1445 }
1446
1447 /**
1448 * @brief Bosch M_CAN driver front-end callback helper for writing to memory mapped Message RAM
1449 *
1450 * @param base Base address of the Message RAM for the given Bosch M_CAN instance. The base address
1451 * must be 32-bit aligned.
1452 * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1453 * offset must be 32-bit aligned.
1454 * @param src Source for the data to be written. The source address must be 32-bit aligned.
1455 * @param len Number of bytes to write. Must be a multiple of 4.
1456 *
1457 * @retval 0 If successful.
1458 * @retval -EIO General input/output error.
1459 */
can_mcan_sys_write_mram(mem_addr_t base,uint16_t offset,const void * src,size_t len)1460 static inline int can_mcan_sys_write_mram(mem_addr_t base, uint16_t offset, const void *src,
1461 size_t len)
1462 {
1463 volatile uint32_t *dst32 = (volatile uint32_t *)(base + offset);
1464 const uint32_t *src32 = (const uint32_t *)src;
1465 size_t len32 = len / sizeof(uint32_t);
1466
1467 __ASSERT(base % 4U == 0U, "base must be a multiple of 4");
1468 __ASSERT(offset % 4U == 0U, "offset must be a multiple of 4");
1469 __ASSERT(POINTER_TO_UINT(src) % 4U == 0U, "src must be 32-bit aligned");
1470 __ASSERT(len % 4U == 0U, "len must be a multiple of 4");
1471
1472 while (len32-- > 0) {
1473 *dst32++ = *src32++;
1474 }
1475
1476 #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
1477 return sys_cache_data_flush_range((void *)(base + offset), len);
1478 #else /* defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1479 return 0;
1480 #endif /* !defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1481 }
1482
1483 /**
1484 * @brief Bosch M_CAN driver front-end callback helper for clearing memory mapped Message RAM
1485 *
1486 * Clear Message RAM by writing 0 to all words.
1487 *
1488 * @param base Base address of the Message RAM for the given Bosch M_CAN instance. The base address
1489 * must be 32-bit aligned.
1490 * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1491 * offset must be 32-bit aligned.
1492 * @param len Number of bytes to clear. Must be a multiple of 4.
1493 *
1494 * @retval 0 If successful.
1495 * @retval -EIO General input/output error.
1496 */
can_mcan_sys_clear_mram(mem_addr_t base,uint16_t offset,size_t len)1497 static inline int can_mcan_sys_clear_mram(mem_addr_t base, uint16_t offset, size_t len)
1498 {
1499 volatile uint32_t *dst32 = (volatile uint32_t *)(base + offset);
1500 size_t len32 = len / sizeof(uint32_t);
1501
1502 __ASSERT(base % 4U == 0U, "base must be a multiple of 4");
1503 __ASSERT(offset % 4U == 0U, "offset must be a multiple of 4");
1504 __ASSERT(len % 4U == 0U, "len must be a multiple of 4");
1505
1506 while (len32-- > 0) {
1507 *dst32++ = 0U;
1508 }
1509
1510 #if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE)
1511 return sys_cache_data_flush_range((void *)(base + offset), len);
1512 #else /* defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1513 return 0;
1514 #endif /* !defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_DCACHE) */
1515 }
1516
1517 /**
1518 * @brief Read a Bosch M_CAN register
1519 *
1520 * @param dev Pointer to the device structure for the driver instance.
1521 * @param reg Register offset
1522 * @param[out] val Register value
1523 *
1524 * @retval 0 If successful.
1525 * @retval -ENOTSUP Register not supported.
1526 * @retval -EIO General input/output error.
1527 */
1528 int can_mcan_read_reg(const struct device *dev, uint16_t reg, uint32_t *val);
1529
1530 /**
1531 * @brief Write a Bosch M_CAN register
1532 *
1533 * @param dev Pointer to the device structure for the driver instance.
1534 * @param reg Register offset
1535 * @param val Register value
1536 *
1537 * @retval 0 If successful.
1538 * @retval -ENOTSUP Register not supported.
1539 * @retval -EIO General input/output error.
1540 */
1541 int can_mcan_write_reg(const struct device *dev, uint16_t reg, uint32_t val);
1542
1543 /**
1544 * @brief Read from Bosch M_CAN Message RAM
1545 *
1546 * @param dev Pointer to the device structure for the driver instance.
1547 * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1548 * offset must be 32-bit aligned.
1549 * @param[out] dst Destination for the data read.
1550 * @param len Number of bytes to read. Must be a multiple of 4.
1551 *
1552 * @retval 0 If successful.
1553 * @retval -EIO General input/output error.
1554 */
can_mcan_read_mram(const struct device * dev,uint16_t offset,void * dst,size_t len)1555 static inline int can_mcan_read_mram(const struct device *dev, uint16_t offset, void *dst,
1556 size_t len)
1557 {
1558 const struct can_mcan_config *config = dev->config;
1559
1560 return config->ops->read_mram(dev, offset, dst, len);
1561 }
1562
1563 /**
1564 * @brief Write to Bosch M_CAN Message RAM
1565 *
1566 * @param dev Pointer to the device structure for the driver instance.
1567 * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1568 * offset must be 32-bit aligned.
1569 * @param src Source for the data to be written
1570 * @param len Number of bytes to write. Must be a multiple of 4.
1571 *
1572 * @retval 0 If successful.
1573 * @retval -EIO General input/output error.
1574 */
can_mcan_write_mram(const struct device * dev,uint16_t offset,const void * src,size_t len)1575 static inline int can_mcan_write_mram(const struct device *dev, uint16_t offset, const void *src,
1576 size_t len)
1577 {
1578 const struct can_mcan_config *config = dev->config;
1579
1580 return config->ops->write_mram(dev, offset, src, len);
1581 }
1582
1583 /**
1584 * @brief Clear Bosch M_CAN Message RAM
1585 *
1586 * Clear Message RAM by writing 0 to all words.
1587 *
1588 * @param dev Pointer to the device structure for the driver instance.
1589 * @param offset Offset from the start of the Message RAM for the given Bosch M_CAN instance. The
1590 * offset must be 32-bit aligned.
1591 * @param len Number of bytes to clear. Must be a multiple of 4.
1592 *
1593 * @retval 0 If successful.
1594 * @retval -EIO General input/output error.
1595 */
can_mcan_clear_mram(const struct device * dev,uint16_t offset,size_t len)1596 static inline int can_mcan_clear_mram(const struct device *dev, uint16_t offset, size_t len)
1597 {
1598 const struct can_mcan_config *config = dev->config;
1599
1600 return config->ops->clear_mram(dev, offset, len);
1601 }
1602
1603 /**
1604 * @brief Configure Bosch M_MCAN Message RAM start addresses.
1605 *
1606 * Bosch M_CAN driver front-end callback helper function for configuring the start addresses of the
1607 * Bosch M_CAN Rx FIFO0 (RXFOC), Rx FIFO1 (RXF1C), Rx Buffer (RXBCC), Tx Buffer (TXBC), and Tx Event
1608 * FIFO (TXEFC) in Message RAM.
1609 *
1610 * The start addresses (containing bits 15:2 since Bosch M_CAN message RAM is accessed as 32 bit
1611 * words) are calculated relative to the provided Message RAM Base Address (mrba).
1612 *
1613 * Some Bosch M_CAN implementations use a fixed Message RAM configuration, other use a fixed memory
1614 * area and relative addressing, others again have custom registers for configuring the Message
1615 * RAM. It is the responsibility of the front-end driver to call this function during driver
1616 * initialization as needed.
1617 *
1618 * @param dev Pointer to the device structure for the driver instance.
1619 * @param mrba Message RAM Base Address.
1620 * @param mram Message RAM Address.
1621 *
1622 * @retval 0 If successful.
1623 * @retval -EIO General input/output error.
1624 */
1625 int can_mcan_configure_mram(const struct device *dev, uintptr_t mrba, uintptr_t mram);
1626
1627 /**
1628 * @brief Bosch M_CAN driver initialization callback.
1629 *
1630 * @param dev Pointer to the device structure for the driver instance.
1631 */
1632 int can_mcan_init(const struct device *dev);
1633
1634 /**
1635 * @brief Bosch M_CAN driver m_can_int0 IRQ handler.
1636 *
1637 * @param dev Pointer to the device structure for the driver instance.
1638 */
1639 void can_mcan_line_0_isr(const struct device *dev);
1640
1641 /**
1642 * @brief Bosch M_CAN driver m_can_int1 IRQ handler.
1643 *
1644 * @param dev Pointer to the device structure for the driver instance.
1645 */
1646 void can_mcan_line_1_isr(const struct device *dev);
1647
1648 /**
1649 * @brief Enable Bosch M_CAN configuration change.
1650 *
1651 * @param dev Pointer to the device structure for the driver instance.
1652 */
1653 void can_mcan_enable_configuration_change(const struct device *dev);
1654
1655 /**
1656 * @brief Bosch M_CAN driver callback API upon getting CAN controller capabilities
1657 * See @a can_get_capabilities() for argument description
1658 */
1659 int can_mcan_get_capabilities(const struct device *dev, can_mode_t *cap);
1660
1661 /**
1662 * @brief Bosch M_CAN driver callback API upon starting CAN controller
1663 * See @a can_start() for argument description
1664 */
1665 int can_mcan_start(const struct device *dev);
1666
1667 /**
1668 * @brief Bosch M_CAN driver callback API upon stopping CAN controller
1669 * See @a can_stop() for argument description
1670 */
1671 int can_mcan_stop(const struct device *dev);
1672
1673 /**
1674 * @brief Bosch M_CAN driver callback API upon setting CAN controller mode
1675 * See @a can_set_mode() for argument description
1676 */
1677 int can_mcan_set_mode(const struct device *dev, can_mode_t mode);
1678
1679 /**
1680 * @brief Bosch M_CAN driver callback API upon setting CAN bus timing
1681 * See @a can_set_timing() for argument description
1682 */
1683 int can_mcan_set_timing(const struct device *dev, const struct can_timing *timing);
1684
1685 /**
1686 * @brief Bosch M_CAN driver callback API upon setting CAN bus data phase timing
1687 * See @a can_set_timing_data() for argument description
1688 */
1689 int can_mcan_set_timing_data(const struct device *dev, const struct can_timing *timing_data);
1690
1691 #ifndef CONFIG_CAN_AUTO_BUS_OFF_RECOVERY
1692 /**
1693 * @brief Bosch M_CAN driver callback API upon recovering the CAN bus
1694 * See @a can_recover() for argument description
1695 */
1696 int can_mcan_recover(const struct device *dev, k_timeout_t timeout);
1697 #endif /* !CONFIG_CAN_AUTO_BUS_OFF_RECOVERY */
1698
1699 int can_mcan_send(const struct device *dev, const struct can_frame *frame, k_timeout_t timeout,
1700 can_tx_callback_t callback, void *user_data);
1701
1702 int can_mcan_get_max_filters(const struct device *dev, bool ide);
1703
1704 /**
1705 * @brief Bosch M_CAN driver callback API upon adding an RX filter
1706 * See @a can_add_rx_callback() for argument description
1707 */
1708 int can_mcan_add_rx_filter(const struct device *dev, can_rx_callback_t callback, void *user_data,
1709 const struct can_filter *filter);
1710
1711 /**
1712 * @brief Bosch M_CAN driver callback API upon removing an RX filter
1713 * See @a can_remove_rx_filter() for argument description
1714 */
1715 void can_mcan_remove_rx_filter(const struct device *dev, int filter_id);
1716
1717 /**
1718 * @brief Bosch M_CAN driver callback API upon getting the CAN controller state
1719 * See @a can_get_state() for argument description
1720 */
1721 int can_mcan_get_state(const struct device *dev, enum can_state *state,
1722 struct can_bus_err_cnt *err_cnt);
1723
1724 /**
1725 * @brief Bosch M_CAN driver callback API upon setting a state change callback
1726 * See @a can_set_state_change_callback() for argument description
1727 */
1728 void can_mcan_set_state_change_callback(const struct device *dev,
1729 can_state_change_callback_t callback, void *user_data);
1730
1731 /**
1732 * @brief Bosch M_CAN driver callback API upon getting the maximum supported bitrate
1733 * See @a can_get_max_bitrate() for argument description
1734 */
1735 int can_mcan_get_max_bitrate(const struct device *dev, uint32_t *max_bitrate);
1736
1737 #endif /* ZEPHYR_INCLUDE_DRIVERS_CAN_CAN_MCAN_H_ */
1738