1 | /* ---------------------------------------------------------------------------- */ |
---|
2 | /* Atmel Microcontroller Software Support */ |
---|
3 | /* SAM Software Package License */ |
---|
4 | /* ---------------------------------------------------------------------------- */ |
---|
5 | /* Copyright (c) 2015, Atmel Corporation */ |
---|
6 | /* */ |
---|
7 | /* All rights reserved. */ |
---|
8 | /* */ |
---|
9 | /* Redistribution and use in source and binary forms, with or without */ |
---|
10 | /* modification, are permitted provided that the following condition is met: */ |
---|
11 | /* */ |
---|
12 | /* - Redistributions of source code must retain the above copyright notice, */ |
---|
13 | /* this list of conditions and the disclaimer below. */ |
---|
14 | /* */ |
---|
15 | /* Atmel's name may not be used to endorse or promote products derived from */ |
---|
16 | /* this software without specific prior written permission. */ |
---|
17 | /* */ |
---|
18 | /* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR */ |
---|
19 | /* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF */ |
---|
20 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE */ |
---|
21 | /* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, */ |
---|
22 | /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT */ |
---|
23 | /* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, */ |
---|
24 | /* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ |
---|
25 | /* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ |
---|
26 | /* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, */ |
---|
27 | /* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ |
---|
28 | /* ---------------------------------------------------------------------------- */ |
---|
29 | |
---|
30 | /** \file |
---|
31 | * Implements functions for Controller Area Network (CAN) |
---|
32 | * peripheral operations. |
---|
33 | */ |
---|
34 | /** \addtogroup can_module |
---|
35 | *@{*/ |
---|
36 | |
---|
37 | |
---|
38 | /*---------------------------------------------------------------------------- |
---|
39 | * Headers |
---|
40 | *----------------------------------------------------------------------------*/ |
---|
41 | #ifndef __rtems__ |
---|
42 | #include "board.h" |
---|
43 | #endif /* __rtems__ */ |
---|
44 | #include "chip.h" |
---|
45 | #include "mcan_config.h" |
---|
46 | #include <assert.h> |
---|
47 | /*--------------------------------------------------------------------------- |
---|
48 | * Definitions |
---|
49 | *---------------------------------------------------------------------------*/ |
---|
50 | #define MAILBOX_ADDRESS(address) (0xFFFC & (address)) |
---|
51 | |
---|
52 | #define CAN_CLK_FREQ_HZ MCAN_PROG_CLK_FREQ_HZ |
---|
53 | |
---|
54 | #define MCAN0_TSEG1 (MCAN0_PROP_SEG + MCAN0_PHASE_SEG1) |
---|
55 | #define MCAN0_TSEG2 (MCAN0_PHASE_SEG2) |
---|
56 | #define MCAN0_BRP ((uint32_t) (((float) CAN_CLK_FREQ_HZ / \ |
---|
57 | ((float)(MCAN0_TSEG1 + MCAN0_TSEG2 + 3) *\ |
---|
58 | (float) MCAN0_BIT_RATE_BPS)) - 1)) |
---|
59 | #define MCAN0_SJW (MCAN0_SYNC_JUMP - 1) |
---|
60 | #define MCAN0_FTSEG1 (MCAN0_FAST_PROP_SEG + MCAN0_FAST_PHASE_SEG1) |
---|
61 | #define MCAN0_FTSEG2 (MCAN0_FAST_PHASE_SEG2) |
---|
62 | #define MCAN0_FBRP ((uint32_t) (((float) CAN_CLK_FREQ_HZ / \ |
---|
63 | ((float)(MCAN0_FTSEG1 + MCAN0_FTSEG2 + 3) * \ |
---|
64 | (float) MCAN0_FAST_BIT_RATE_BPS)) - 1)) |
---|
65 | #define MCAN0_FSJW (MCAN0_FAST_SYNC_JUMP - 1) |
---|
66 | |
---|
67 | #define MCAN0_STD_FLTS_WRDS (MCAN0_NMBR_STD_FLTS) |
---|
68 | /* 128 max filters */ |
---|
69 | #define MCAN0_EXT_FLTS_WRDS (MCAN0_NMBR_EXT_FLTS * 2) |
---|
70 | /* 64 max filters */ |
---|
71 | #define MCAN0_RX_FIFO0_WRDS (MCAN0_NMBR_RX_FIFO0_ELMTS * \ |
---|
72 | ((MCAN0_RX_FIFO0_ELMT_SZ/4) + 2)) |
---|
73 | /* 64 elements max */ |
---|
74 | #define MCAN0_RX_FIFO1_WRDS (MCAN0_NMBR_RX_FIFO1_ELMTS *\ |
---|
75 | ((MCAN0_RX_FIFO1_ELMT_SZ/4) + 2)) |
---|
76 | /* 64 elements max */ |
---|
77 | #define MCAN0_RX_DED_BUFS_WRDS (MCAN0_NMBR_RX_DED_BUF_ELMTS * \ |
---|
78 | ((MCAN0_RX_BUF_ELMT_SZ/4) + 2)) |
---|
79 | /* 64 elements max */ |
---|
80 | #define MCAN0_TX_EVT_FIFO_WRDS (MCAN0_NMBR_TX_EVT_FIFO_ELMTS * 2) |
---|
81 | /* 32 elements max */ |
---|
82 | #define MCAN0_TX_DED_BUF_WRDS (MCAN0_NMBR_TX_DED_BUF_ELMTS * \ |
---|
83 | ((MCAN0_TX_BUF_ELMT_SZ/4) + 2)) |
---|
84 | /* 32 elements max */ |
---|
85 | #define MCAN0_TX_FIFO_Q_WRDS (MCAN0_NMBR_TX_FIFO_Q_ELMTS *\ |
---|
86 | ((MCAN0_TX_BUF_ELMT_SZ/4) + 2)) |
---|
87 | /* 32 elements max */ |
---|
88 | |
---|
89 | #define MCAN1_TSEG1 (MCAN1_PROP_SEG + MCAN1_PHASE_SEG1) |
---|
90 | #define MCAN1_TSEG2 (MCAN1_PHASE_SEG2) |
---|
91 | #define MCAN1_BRP ((uint32_t) (((float) CAN_CLK_FREQ_HZ / \ |
---|
92 | ((float)(MCAN1_TSEG1 + MCAN1_TSEG2 + 3) *\ |
---|
93 | (float) MCAN1_BIT_RATE_BPS)) - 1)) |
---|
94 | #define MCAN1_SJW (MCAN1_SYNC_JUMP - 1) |
---|
95 | #define MCAN1_FTSEG1 (MCAN1_FAST_PROP_SEG + MCAN1_FAST_PHASE_SEG1) |
---|
96 | #define MCAN1_FTSEG2 (MCAN1_FAST_PHASE_SEG2) |
---|
97 | #define MCAN1_FBRP ((uint32_t) (((float) CAN_CLK_FREQ_HZ /\ |
---|
98 | ((float)(MCAN1_FTSEG1 + MCAN1_FTSEG2 + 3) *\ |
---|
99 | (float) MCAN1_FAST_BIT_RATE_BPS)) - 1)) |
---|
100 | #define MCAN1_FSJW (MCAN1_FAST_SYNC_JUMP - 1) |
---|
101 | |
---|
102 | #define MCAN1_STD_FLTS_WRDS (MCAN1_NMBR_STD_FLTS) |
---|
103 | /* 128 max filters */ |
---|
104 | #define MCAN1_EXT_FLTS_WRDS (MCAN1_NMBR_EXT_FLTS * 2) |
---|
105 | /* 64 max filters */ |
---|
106 | #define MCAN1_RX_FIFO0_WRDS (MCAN1_NMBR_RX_FIFO0_ELMTS * \ |
---|
107 | ((MCAN1_RX_FIFO0_ELMT_SZ/4) + 2)) |
---|
108 | /* 64 elements max */ |
---|
109 | #define MCAN1_RX_FIFO1_WRDS (MCAN1_NMBR_RX_FIFO1_ELMTS *\ |
---|
110 | ((MCAN1_RX_FIFO1_ELMT_SZ/4) + 2)) |
---|
111 | /* 64 elements max */ |
---|
112 | #define MCAN1_RX_DED_BUFS_WRDS (MCAN1_NMBR_RX_DED_BUF_ELMTS * \ |
---|
113 | ((MCAN1_RX_BUF_ELMT_SZ/4) + 2)) |
---|
114 | /* 64 elements max */ |
---|
115 | #define MCAN1_TX_EVT_FIFO_WRDS (MCAN1_NMBR_TX_EVT_FIFO_ELMTS * 2) |
---|
116 | /* 32 elements max */ |
---|
117 | #define MCAN1_TX_DED_BUF_WRDS (MCAN1_NMBR_TX_DED_BUF_ELMTS * \ |
---|
118 | ((MCAN1_TX_BUF_ELMT_SZ/4) + 2)) |
---|
119 | /* 32 elements max */ |
---|
120 | #define MCAN1_TX_FIFO_Q_WRDS (MCAN1_NMBR_TX_FIFO_Q_ELMTS * \ |
---|
121 | ((MCAN1_TX_BUF_ELMT_SZ/4) + 2)) |
---|
122 | /* 32 elements max */ |
---|
123 | |
---|
124 | /* validate CAN0 entries */ |
---|
125 | #if (MCAN0_TSEG1 > 63) |
---|
126 | #error "Invalid CAN0 TSEG1" |
---|
127 | #endif |
---|
128 | #if (MCAN0_TSEG2 > 15) |
---|
129 | #error "Invalid CAN0 TSEG2" |
---|
130 | #endif |
---|
131 | #if (MCAN0_SJW > 15) |
---|
132 | #error "Invalid CAN0 SJW" |
---|
133 | #endif |
---|
134 | #if (MCAN0_FTSEG1 > 15) |
---|
135 | #error "Invalid CAN0 FTSEG1" |
---|
136 | #endif |
---|
137 | #if (MCAN0_FTSEG2 > 7) |
---|
138 | #error "Invalid CAN0 FTSEG2" |
---|
139 | #endif |
---|
140 | #if (MCAN0_FSJW > 3) |
---|
141 | #error "Invalid CAN0 FSJW" |
---|
142 | #endif |
---|
143 | |
---|
144 | #if (MCAN0_NMBR_STD_FLTS > 128) |
---|
145 | #error "Invalid CAN0 # of Standard Filters" |
---|
146 | #endif |
---|
147 | #if (MCAN0_NMBR_EXT_FLTS > 64) |
---|
148 | #error "Invalid CAN0 # of Extended Filters" |
---|
149 | #endif |
---|
150 | #if (MCAN0_NMBR_RX_FIFO0_ELMTS > 64) |
---|
151 | #error "Invalid CAN0 # RX FIFO 0 ELEMENTS" |
---|
152 | #endif |
---|
153 | #if (MCAN0_NMBR_RX_FIFO1_ELMTS > 64) |
---|
154 | #error "Invalid CAN0 # RX FIFO 0 ELEMENTS" |
---|
155 | #endif |
---|
156 | #if (MCAN0_NMBR_RX_DED_BUF_ELMTS > 64) |
---|
157 | #error "Invalid CAN0 # RX BUFFER ELEMENTS" |
---|
158 | #endif |
---|
159 | #if (MCAN0_NMBR_TX_EVT_FIFO_ELMTS > 32) |
---|
160 | #error "Invalid CAN0 # TX EVENT FIFO ELEMENTS" |
---|
161 | #endif |
---|
162 | #if ((MCAN0_NMBR_TX_DED_BUF_ELMTS + MCAN0_NMBR_TX_FIFO_Q_ELMTS) > 32) |
---|
163 | #error "Invalid CAN0 # TX BUFFER ELEMENTS" |
---|
164 | #endif |
---|
165 | |
---|
166 | #if (8 == MCAN0_RX_FIFO0_ELMT_SZ) |
---|
167 | #define MCAN0_RX_FIFO0_DATA_SIZE (0u) |
---|
168 | #elif (12 == MCAN0_RX_FIFO0_ELMT_SZ) |
---|
169 | #define MCAN0_RX_FIFO0_DATA_SIZE (1u) |
---|
170 | #elif (16 == MCAN0_RX_FIFO0_ELMT_SZ) |
---|
171 | #define MCAN0_RX_FIFO0_DATA_SIZE (2u) |
---|
172 | #elif (20 == MCAN0_RX_FIFO0_ELMT_SZ) |
---|
173 | #define MCAN0_RX_FIFO0_DATA_SIZE (3u) |
---|
174 | #elif (24 == MCAN0_RX_FIFO0_ELMT_SZ) |
---|
175 | #define MCAN0_RX_FIFO0_DATA_SIZE (4u) |
---|
176 | #elif (32 == MCAN0_RX_FIFO0_ELMT_SZ) |
---|
177 | #define MCAN0_RX_FIFO0_DATA_SIZE (5u) |
---|
178 | #elif (48 == MCAN0_RX_FIFO0_ELMT_SZ) |
---|
179 | #define MCAN0_RX_FIFO0_DATA_SIZE (6u) |
---|
180 | #elif (64 == MCAN0_RX_FIFO0_ELMT_SZ) |
---|
181 | #define MCAN0_RX_FIFO0_DATA_SIZE (7u) |
---|
182 | #else |
---|
183 | #error "Invalid CAN0 RX FIFO0 ELEMENT SIZE" |
---|
184 | #endif |
---|
185 | |
---|
186 | #if (8 == MCAN0_RX_FIFO1_ELMT_SZ) |
---|
187 | #define MCAN0_RX_FIFO1_DATA_SIZE (0u) |
---|
188 | #elif (12 == MCAN0_RX_FIFO1_ELMT_SZ) |
---|
189 | #define MCAN0_RX_FIFO1_DATA_SIZE (1u) |
---|
190 | #elif (16 == MCAN0_RX_FIFO1_ELMT_SZ) |
---|
191 | #define MCAN0_RX_FIFO1_DATA_SIZE (2u) |
---|
192 | #elif (20 == MCAN0_RX_FIFO1_ELMT_SZ) |
---|
193 | #define MCAN0_RX_FIFO1_DATA_SIZE (3u) |
---|
194 | #elif (24 == MCAN0_RX_FIFO1_ELMT_SZ) |
---|
195 | #define MCAN0_RX_FIFO1_DATA_SIZE (4u) |
---|
196 | #elif (32 == MCAN0_RX_FIFO1_ELMT_SZ) |
---|
197 | #define MCAN0_RX_FIFO1_DATA_SIZE (5u) |
---|
198 | #elif (48 == MCAN0_RX_FIFO1_ELMT_SZ) |
---|
199 | #define MCAN0_RX_FIFO1_DATA_SIZE (6u) |
---|
200 | #elif (64 == MCAN0_RX_FIFO1_ELMT_SZ) |
---|
201 | #define MCAN0_RX_FIFO1_DATA_SIZE (7u) |
---|
202 | #else |
---|
203 | #error "Invalid CAN0 RX FIFO1 ELEMENT SIZE" |
---|
204 | #endif |
---|
205 | |
---|
206 | #if (8 == MCAN0_RX_BUF_ELMT_SZ) |
---|
207 | #define MCAN0_RX_BUF_DATA_SIZE (0u) |
---|
208 | #elif (12 == MCAN0_RX_BUF_ELMT_SZ) |
---|
209 | #define MCAN0_RX_BUF_DATA_SIZE (1u) |
---|
210 | #elif (16 == MCAN0_RX_BUF_ELMT_SZ) |
---|
211 | #define MCAN0_RX_BUF_DATA_SIZE (2u) |
---|
212 | #elif (20 == MCAN0_RX_BUF_ELMT_SZ) |
---|
213 | #define MCAN0_RX_BUF_DATA_SIZE (3u) |
---|
214 | #elif (24 == MCAN0_RX_BUF_ELMT_SZ) |
---|
215 | #define MCAN0_RX_BUF_DATA_SIZE (4u) |
---|
216 | #elif (32 == MCAN0_RX_BUF_ELMT_SZ) |
---|
217 | #define MCAN0_RX_BUF_DATA_SIZE (5u) |
---|
218 | #elif (48 == MCAN0_RX_BUF_ELMT_SZ) |
---|
219 | #define MCAN0_RX_BUF_DATA_SIZE (6u) |
---|
220 | #elif (64 == MCAN0_RX_BUF_ELMT_SZ) |
---|
221 | #define MCAN0_RX_BUF_DATA_SIZE (7u) |
---|
222 | #else |
---|
223 | #error "Invalid CAN0 RX BUFFER ELEMENT SIZE" |
---|
224 | #endif |
---|
225 | |
---|
226 | #if (8 == MCAN0_TX_BUF_ELMT_SZ) |
---|
227 | #define MCAN0_TX_BUF_DATA_SIZE (0u) |
---|
228 | #elif (12 == MCAN0_TX_BUF_ELMT_SZ) |
---|
229 | #define MCAN0_TX_BUF_DATA_SIZE (1u) |
---|
230 | #elif (16 == MCAN0_TX_BUF_ELMT_SZ) |
---|
231 | #define MCAN0_TX_BUF_DATA_SIZE (2u) |
---|
232 | #elif (20 == MCAN0_TX_BUF_ELMT_SZ) |
---|
233 | #define MCAN0_TX_BUF_DATA_SIZE (3u) |
---|
234 | #elif (24 == MCAN0_TX_BUF_ELMT_SZ) |
---|
235 | #define MCAN0_TX_BUF_DATA_SIZE (4u) |
---|
236 | #elif (32 == MCAN0_TX_BUF_ELMT_SZ) |
---|
237 | #define MCAN0_TX_BUF_DATA_SIZE (5u) |
---|
238 | #elif (48 == MCAN0_TX_BUF_ELMT_SZ) |
---|
239 | #define MCAN0_TX_BUF_DATA_SIZE (6u) |
---|
240 | #elif (64 == MCAN0_TX_BUF_ELMT_SZ) |
---|
241 | #define MCAN0_TX_BUF_DATA_SIZE (7u) |
---|
242 | #else |
---|
243 | #error "Invalid CAN0 TX BUFFER ELEMENT SIZE" |
---|
244 | #endif |
---|
245 | |
---|
246 | /* validate CAN1 entries */ |
---|
247 | #if (MCAN1_TSEG1 > 63) |
---|
248 | #error "Invalid CAN1 TSEG1" |
---|
249 | #endif |
---|
250 | #if (MCAN1_TSEG2 > 15) |
---|
251 | #error "Invalid CAN1 TSEG2" |
---|
252 | #endif |
---|
253 | #if (MCAN1_SJW > 15) |
---|
254 | #error "Invalid CAN1 SJW" |
---|
255 | #endif |
---|
256 | #if (MCAN1_FTSEG1 > 15) |
---|
257 | #error "Invalid CAN1 FTSEG1" |
---|
258 | #endif |
---|
259 | #if (MCAN1_FTSEG2 > 7) |
---|
260 | #error "Invalid CAN1 FTSEG2" |
---|
261 | #endif |
---|
262 | #if (MCAN1_FSJW > 3) |
---|
263 | #error "Invalid CAN1 FSJW" |
---|
264 | #endif |
---|
265 | |
---|
266 | #if (MCAN1_NMBR_STD_FLTS > 128) |
---|
267 | #error "Invalid CAN1 # of Standard Filters" |
---|
268 | #endif |
---|
269 | #if (MCAN1_NMBR_EXT_FLTS > 64) |
---|
270 | #error "Invalid CAN1 # of Extended Filters" |
---|
271 | #endif |
---|
272 | #if (MCAN1_NMBR_RX_FIFO0_ELMTS > 64) |
---|
273 | #error "Invalid CAN1 # RX FIFO 0 ELEMENTS" |
---|
274 | #endif |
---|
275 | #if (MCAN1_NMBR_RX_FIFO1_ELMTS > 64) |
---|
276 | #error "Invalid CAN1 # RX FIFO 0 ELEMENTS" |
---|
277 | #endif |
---|
278 | #if (MCAN1_NMBR_RX_DED_BUF_ELMTS > 64) |
---|
279 | #error "Invalid CAN1 # RX BUFFER ELEMENTS" |
---|
280 | #endif |
---|
281 | #if (MCAN1_NMBR_TX_EVT_FIFO_ELMTS > 32) |
---|
282 | #error "Invalid CAN1 # TX EVENT FIFO ELEMENTS" |
---|
283 | #endif |
---|
284 | #if ((MCAN1_NMBR_TX_DED_BUF_ELMTS + MCAN1_NMBR_TX_FIFO_Q_ELMTS) > 32) |
---|
285 | #error "Invalid CAN1 # TX BUFFER ELEMENTS" |
---|
286 | #endif |
---|
287 | |
---|
288 | #if (8 == MCAN1_RX_FIFO0_ELMT_SZ) |
---|
289 | #define MCAN1_RX_FIFO0_DATA_SIZE (0u) |
---|
290 | #elif (12 == MCAN1_RX_FIFO0_ELMT_SZ) |
---|
291 | #define MCAN1_RX_FIFO0_DATA_SIZE (1u) |
---|
292 | #elif (16 == MCAN1_RX_FIFO0_ELMT_SZ) |
---|
293 | #define MCAN1_RX_FIFO0_DATA_SIZE (2u) |
---|
294 | #elif (20 == MCAN1_RX_FIFO0_ELMT_SZ) |
---|
295 | #define MCAN1_RX_FIFO0_DATA_SIZE (3u) |
---|
296 | #elif (24 == MCAN1_RX_FIFO0_ELMT_SZ) |
---|
297 | #define MCAN1_RX_FIFO0_DATA_SIZE (4u) |
---|
298 | #elif (32 == MCAN1_RX_FIFO0_ELMT_SZ) |
---|
299 | #define MCAN1_RX_FIFO0_DATA_SIZE (5u) |
---|
300 | #elif (48 == MCAN1_RX_FIFO0_ELMT_SZ) |
---|
301 | #define MCAN1_RX_FIFO0_DATA_SIZE (6u) |
---|
302 | #elif (64 == MCAN1_RX_FIFO0_ELMT_SZ) |
---|
303 | #define MCAN1_RX_FIFO0_DATA_SIZE (7u) |
---|
304 | #else |
---|
305 | #error "Invalid CAN1 RX FIFO0 ELEMENT SIZE" |
---|
306 | #endif |
---|
307 | |
---|
308 | #if (8 == MCAN1_RX_FIFO1_ELMT_SZ) |
---|
309 | #define MCAN1_RX_FIFO1_DATA_SIZE (0u) |
---|
310 | #elif (12 == MCAN1_RX_FIFO1_ELMT_SZ) |
---|
311 | #define MCAN1_RX_FIFO1_DATA_SIZE (1u) |
---|
312 | #elif (16 == MCAN1_RX_FIFO1_ELMT_SZ) |
---|
313 | #define MCAN1_RX_FIFO1_DATA_SIZE (2u) |
---|
314 | #elif (20 == MCAN1_RX_FIFO1_ELMT_SZ) |
---|
315 | #define MCAN1_RX_FIFO1_DATA_SIZE (3u) |
---|
316 | #elif (24 == MCAN1_RX_FIFO1_ELMT_SZ) |
---|
317 | #define MCAN1_RX_FIFO1_DATA_SIZE (4u) |
---|
318 | #elif (32 == MCAN1_RX_FIFO1_ELMT_SZ) |
---|
319 | #define MCAN1_RX_FIFO1_DATA_SIZE (5u) |
---|
320 | #elif (48 == MCAN1_RX_FIFO1_ELMT_SZ) |
---|
321 | #define MCAN1_RX_FIFO1_DATA_SIZE (6u) |
---|
322 | #elif (64 == MCAN1_RX_FIFO1_ELMT_SZ) |
---|
323 | #define MCAN1_RX_FIFO1_DATA_SIZE (7u) |
---|
324 | #else |
---|
325 | #error "Invalid CAN1 RX FIFO1 ELEMENT SIZE" |
---|
326 | #endif |
---|
327 | |
---|
328 | #if (8 == MCAN1_RX_BUF_ELMT_SZ) |
---|
329 | #define MCAN1_RX_BUF_DATA_SIZE (0u) |
---|
330 | #elif (12 == MCAN1_RX_BUF_ELMT_SZ) |
---|
331 | #define MCAN1_RX_BUF_DATA_SIZE (1u) |
---|
332 | #elif (16 == MCAN1_RX_BUF_ELMT_SZ) |
---|
333 | #define MCAN1_RX_BUF_DATA_SIZE (2u) |
---|
334 | #elif (20 == MCAN1_RX_BUF_ELMT_SZ) |
---|
335 | #define MCAN1_RX_BUF_DATA_SIZE (3u) |
---|
336 | #elif (24 == MCAN1_RX_BUF_ELMT_SZ) |
---|
337 | #define MCAN1_RX_BUF_DATA_SIZE (4u) |
---|
338 | #elif (32 == MCAN1_RX_BUF_ELMT_SZ) |
---|
339 | #define MCAN1_RX_BUF_DATA_SIZE (5u) |
---|
340 | #elif (48 == MCAN1_RX_BUF_ELMT_SZ) |
---|
341 | #define MCAN1_RX_BUF_DATA_SIZE (6u) |
---|
342 | #elif (64 == MCAN1_RX_BUF_ELMT_SZ) |
---|
343 | #define MCAN1_RX_BUF_DATA_SIZE (7u) |
---|
344 | #else |
---|
345 | #error "Invalid CAN1 RX BUFFER ELEMENT SIZE" |
---|
346 | #endif |
---|
347 | |
---|
348 | #if (8 == MCAN1_TX_BUF_ELMT_SZ) |
---|
349 | #define MCAN1_TX_BUF_DATA_SIZE (0u) |
---|
350 | #elif (12 == MCAN1_TX_BUF_ELMT_SZ) |
---|
351 | #define MCAN1_TX_BUF_DATA_SIZE (1u) |
---|
352 | #elif (16 == MCAN1_TX_BUF_ELMT_SZ) |
---|
353 | #define MCAN1_TX_BUF_DATA_SIZE (2u) |
---|
354 | #elif (20 == MCAN1_TX_BUF_ELMT_SZ) |
---|
355 | #define MCAN1_TX_BUF_DATA_SIZE (3u) |
---|
356 | #elif (24 == MCAN1_TX_BUF_ELMT_SZ) |
---|
357 | #define MCAN1_TX_BUF_DATA_SIZE (4u) |
---|
358 | #elif (32 == MCAN1_TX_BUF_ELMT_SZ) |
---|
359 | #define MCAN1_TX_BUF_DATA_SIZE (5u) |
---|
360 | #elif (48 == MCAN1_TX_BUF_ELMT_SZ) |
---|
361 | #define MCAN1_TX_BUF_DATA_SIZE (6u) |
---|
362 | #elif (64 == MCAN1_TX_BUF_ELMT_SZ) |
---|
363 | #define MCAN1_TX_BUF_DATA_SIZE (7u) |
---|
364 | #else |
---|
365 | #error "Invalid CAN1 TX BUFFER ELEMENT SIZE" |
---|
366 | #endif |
---|
367 | |
---|
368 | #define CAN_11_BIT_ID_MASK (0x7FF) |
---|
369 | #define CAN_29_BIT_ID_MASK (0x1FFFFFFF) |
---|
370 | #define ELMT_SIZE_MASK (0x1F) |
---|
371 | /* max element size is 18 words, fits in 5 bits */ |
---|
372 | |
---|
373 | #define BUFFER_XTD_MASK (0x40000000) |
---|
374 | #define BUFFER_EXT_ID_MASK (0x1FFFFFFF) |
---|
375 | #define BUFFER_STD_ID_MASK (0x1FFC0000) |
---|
376 | #define BUFFER_DLC_MASK (0x000F0000) |
---|
377 | #define BUFFER_RXTS_MASK (0x0000FFFF) |
---|
378 | |
---|
379 | #define STD_FILT_SFT_MASK (3U << 30) |
---|
380 | #define STD_FILT_SFT_RANGE (0U << 30) |
---|
381 | #define STD_FILT_SFT_DUAL (1U << 30) |
---|
382 | #define STD_FILT_SFT_CLASSIC (2U << 30) |
---|
383 | #define STD_FILT_SFEC_MASK (7U << 27) |
---|
384 | #define STD_FILT_SFEC_DISABLE (0U << 27) |
---|
385 | #define STD_FILT_SFEC_FIFO0 (1U << 27) |
---|
386 | #define STD_FILT_SFEC_FIFO1 (2U << 27) |
---|
387 | #define STD_FILT_SFEC_REJECT (3U << 27) |
---|
388 | #define STD_FILT_SFEC_PRIORITY (4U << 27) |
---|
389 | #define STD_FILT_SFEC_PRIORITY_FIFO0 (5U << 27) |
---|
390 | #define STD_FILT_SFEC_PRIORITY_FIFO1 (6U << 27) |
---|
391 | #define STD_FILT_SFEC_BUFFER (7U << 27) |
---|
392 | #define STD_FILT_SFID1_MASK (0x03FFU << 16) |
---|
393 | #define STD_FILT_SFID2_MASK (0x3FFU << 0) |
---|
394 | #define STD_FILT_SFID2_RX_BUFFER (0U << 9) |
---|
395 | #define STD_FILT_SFID2_DEBUG_A (1U << 9) |
---|
396 | #define STD_FILT_SFID2_DEBUG_B (2U << 9) |
---|
397 | #define STD_FILT_SFID2_DEBUG_C (3U << 9) |
---|
398 | #define STD_FILT_SFID2_BUFFER(nmbr) (nmbr & 0x3F) |
---|
399 | |
---|
400 | #define EXT_FILT_EFEC_MASK (7U << 29) |
---|
401 | #define EXT_FILT_EFEC_DISABLE (0U << 29) |
---|
402 | #define EXT_FILT_EFEC_FIFO0 (1U << 29) |
---|
403 | #define EXT_FILT_EFEC_FIFO1 (2U << 29) |
---|
404 | #define EXT_FILT_EFEC_REJECT (3U << 29) |
---|
405 | #define EXT_FILT_EFEC_PRIORITY (4U << 29) |
---|
406 | #define EXT_FILT_EFEC_PRIORITY_FIFO0 (5U << 29) |
---|
407 | #define EXT_FILT_EFEC_PRIORITY_FIFO1 (6U << 29) |
---|
408 | #define EXT_FILT_EFEC_BUFFER (7U << 29) |
---|
409 | #define EXT_FILT_EFID1_MASK (0x1FFFFFFF) |
---|
410 | #define EXT_FILT_EFT_MASK (3U << 30) |
---|
411 | #define EXT_FILT_EFT_RANGE (0U << 30) |
---|
412 | #define EXT_FILT_EFT_DUAL (1U << 30) |
---|
413 | #define EXT_FILT_EFT_CLASSIC (2U << 30) |
---|
414 | #define EXT_FILT_EFT_RANGE_NO_XIDAM (3U << 30) |
---|
415 | #define EXT_FILT_EFID2_MASK (0x1FFFFFFF) |
---|
416 | #define EXT_FILT_EFID2_RX_BUFFER (0U << 9) |
---|
417 | #define EXT_FILT_EFID2_DEBUG_A (1U << 9) |
---|
418 | #define EXT_FILT_EFID2_DEBUG_B (2U << 9) |
---|
419 | #define EXT_FILT_EFID2_DEBUG_C (3U << 9) |
---|
420 | #define EXT_FILT_EFID2_BUFFER(nmbr) (nmbr & 0x3F) |
---|
421 | |
---|
422 | |
---|
423 | /*--------------------------------------------------------------------------- |
---|
424 | * Internal variables |
---|
425 | *---------------------------------------------------------------------------*/ |
---|
426 | |
---|
427 | #ifndef __rtems__ |
---|
428 | static const Pin pinsMcan0[] = {PIN_MCAN0_TXD, PIN_MCAN0_RXD }; |
---|
429 | static const Pin pinsMcan1[] = {PIN_MCAN1_TXD, PIN_MCAN1_RXD }; |
---|
430 | #endif /* __rtems__ */ |
---|
431 | |
---|
432 | static uint32_t can0MsgRam[MCAN0_STD_FLTS_WRDS + |
---|
433 | MCAN0_EXT_FLTS_WRDS + |
---|
434 | MCAN0_RX_FIFO0_WRDS + |
---|
435 | MCAN0_RX_FIFO1_WRDS + |
---|
436 | MCAN0_RX_DED_BUFS_WRDS + |
---|
437 | MCAN0_TX_EVT_FIFO_WRDS + |
---|
438 | MCAN0_TX_DED_BUF_WRDS + |
---|
439 | MCAN0_TX_FIFO_Q_WRDS]; |
---|
440 | |
---|
441 | static uint32_t can1MsgRam[MCAN1_STD_FLTS_WRDS + |
---|
442 | MCAN1_EXT_FLTS_WRDS + |
---|
443 | MCAN1_RX_FIFO0_WRDS + |
---|
444 | MCAN1_RX_FIFO1_WRDS + |
---|
445 | MCAN1_RX_DED_BUFS_WRDS + |
---|
446 | MCAN1_TX_EVT_FIFO_WRDS + |
---|
447 | MCAN1_TX_DED_BUF_WRDS + |
---|
448 | MCAN1_TX_FIFO_Q_WRDS]; |
---|
449 | |
---|
450 | static const uint8_t dlcToMsgLength[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 12, 16, 20, 24, 32, 48, 64 }; |
---|
451 | |
---|
452 | const MCan_ConfigType mcan0Config = { |
---|
453 | MCAN0, |
---|
454 | MCAN_BTP_BRP(MCAN0_BRP) | MCAN_BTP_TSEG1(MCAN0_TSEG1) | |
---|
455 | MCAN_BTP_TSEG2(MCAN0_TSEG2) | MCAN_BTP_SJW(MCAN0_SJW), |
---|
456 | MCAN_FBTP_FBRP(MCAN0_FBRP) | MCAN_FBTP_FTSEG1(MCAN0_FTSEG1) | |
---|
457 | MCAN_FBTP_FTSEG2(MCAN0_FTSEG2) | MCAN_FBTP_FSJW(MCAN0_FSJW), |
---|
458 | MCAN0_NMBR_STD_FLTS, |
---|
459 | MCAN0_NMBR_EXT_FLTS, |
---|
460 | MCAN0_NMBR_RX_FIFO0_ELMTS, |
---|
461 | MCAN0_NMBR_RX_FIFO1_ELMTS, |
---|
462 | MCAN0_NMBR_RX_DED_BUF_ELMTS, |
---|
463 | MCAN0_NMBR_TX_EVT_FIFO_ELMTS, |
---|
464 | MCAN0_NMBR_TX_DED_BUF_ELMTS, |
---|
465 | MCAN0_NMBR_TX_FIFO_Q_ELMTS, |
---|
466 | (MCAN0_RX_FIFO0_DATA_SIZE << 29) | ((MCAN0_RX_FIFO0_ELMT_SZ / 4) + 2), |
---|
467 | /* element size in WORDS */ |
---|
468 | (MCAN0_RX_FIFO1_DATA_SIZE << 29) | ((MCAN0_RX_FIFO1_ELMT_SZ / 4) + 2), |
---|
469 | /* element size in WORDS */ |
---|
470 | (MCAN0_RX_BUF_DATA_SIZE << 29) | ((MCAN0_RX_BUF_ELMT_SZ / 4) + 2), |
---|
471 | /* element size in WORDS */ |
---|
472 | (MCAN0_TX_BUF_DATA_SIZE << 29) | ((MCAN0_TX_BUF_ELMT_SZ / 4) + 2), |
---|
473 | /* element size in WORDS */ |
---|
474 | { |
---|
475 | &can0MsgRam[0], |
---|
476 | &can0MsgRam[MCAN0_STD_FLTS_WRDS], |
---|
477 | &can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS], |
---|
478 | &can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS], |
---|
479 | &can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS + |
---|
480 | MCAN0_RX_FIFO1_WRDS], |
---|
481 | &can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS + |
---|
482 | MCAN0_RX_FIFO1_WRDS + MCAN0_RX_DED_BUFS_WRDS], |
---|
483 | &can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS + |
---|
484 | MCAN0_RX_FIFO1_WRDS + MCAN0_RX_DED_BUFS_WRDS + MCAN0_TX_EVT_FIFO_WRDS], |
---|
485 | &can0MsgRam[MCAN0_STD_FLTS_WRDS + MCAN0_EXT_FLTS_WRDS + MCAN0_RX_FIFO0_WRDS + |
---|
486 | MCAN0_RX_FIFO1_WRDS + MCAN0_RX_DED_BUFS_WRDS + MCAN0_TX_EVT_FIFO_WRDS + |
---|
487 | MCAN0_TX_DED_BUF_WRDS] |
---|
488 | }, |
---|
489 | }; |
---|
490 | |
---|
491 | const MCan_ConfigType mcan1Config = { |
---|
492 | MCAN1, |
---|
493 | MCAN_BTP_BRP(MCAN1_BRP) | MCAN_BTP_TSEG1(MCAN1_TSEG1) | |
---|
494 | MCAN_BTP_TSEG2(MCAN1_TSEG2) | MCAN_BTP_SJW(MCAN1_SJW), |
---|
495 | MCAN_FBTP_FBRP(MCAN1_FBRP) | MCAN_FBTP_FTSEG1(MCAN1_FTSEG1) | |
---|
496 | MCAN_FBTP_FTSEG2(MCAN1_FTSEG2) | MCAN_FBTP_FSJW(MCAN1_FSJW), |
---|
497 | MCAN1_NMBR_STD_FLTS, |
---|
498 | MCAN1_NMBR_EXT_FLTS, |
---|
499 | MCAN1_NMBR_RX_FIFO0_ELMTS, |
---|
500 | MCAN1_NMBR_RX_FIFO1_ELMTS, |
---|
501 | MCAN0_NMBR_RX_DED_BUF_ELMTS, |
---|
502 | MCAN1_NMBR_TX_EVT_FIFO_ELMTS, |
---|
503 | MCAN1_NMBR_TX_DED_BUF_ELMTS, |
---|
504 | MCAN1_NMBR_TX_FIFO_Q_ELMTS, |
---|
505 | (MCAN1_RX_FIFO0_DATA_SIZE << 29) | ((MCAN1_RX_FIFO0_ELMT_SZ / 4) + 2), |
---|
506 | /* element size in WORDS */ |
---|
507 | (MCAN1_RX_FIFO1_DATA_SIZE << 29) | ((MCAN1_RX_FIFO1_ELMT_SZ / 4) + 2), |
---|
508 | /* element size in WORDS */ |
---|
509 | (MCAN1_RX_BUF_DATA_SIZE << 29) | ((MCAN1_RX_BUF_ELMT_SZ / 4) + 2), |
---|
510 | /* element size in WORDS */ |
---|
511 | (MCAN1_TX_BUF_DATA_SIZE << 29) | ((MCAN1_TX_BUF_ELMT_SZ / 4) + 2), |
---|
512 | /* element size in WORDS */ |
---|
513 | { |
---|
514 | &can1MsgRam[0], |
---|
515 | &can1MsgRam[MCAN1_STD_FLTS_WRDS], |
---|
516 | &can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS], |
---|
517 | &can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS], |
---|
518 | &can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS |
---|
519 | + MCAN1_RX_FIFO1_WRDS], |
---|
520 | &can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS |
---|
521 | + MCAN1_RX_FIFO1_WRDS + MCAN1_RX_DED_BUFS_WRDS], |
---|
522 | &can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS |
---|
523 | + MCAN1_RX_FIFO1_WRDS + MCAN1_RX_DED_BUFS_WRDS + MCAN1_TX_EVT_FIFO_WRDS], |
---|
524 | &can1MsgRam[MCAN1_STD_FLTS_WRDS + MCAN1_EXT_FLTS_WRDS + MCAN1_RX_FIFO0_WRDS |
---|
525 | + MCAN1_RX_FIFO1_WRDS + MCAN1_RX_DED_BUFS_WRDS + MCAN1_TX_EVT_FIFO_WRDS |
---|
526 | + MCAN1_TX_DED_BUF_WRDS] |
---|
527 | }, |
---|
528 | }; |
---|
529 | |
---|
530 | |
---|
531 | /*--------------------------------------------------------------------------- |
---|
532 | * Exported Functions |
---|
533 | *---------------------------------------------------------------------------*/ |
---|
534 | /** |
---|
535 | * \brief Initializes the MCAN hardware for giving peripheral. |
---|
536 | * Default: Mixed mode TX Buffer + FIFO. |
---|
537 | * |
---|
538 | * \param mcanConfig Pointer to a MCAN instance. |
---|
539 | */ |
---|
540 | void MCAN_Init(const MCan_ConfigType *mcanConfig) |
---|
541 | { |
---|
542 | Mcan *mcan = mcanConfig->pMCan; |
---|
543 | uint32_t regVal32; |
---|
544 | uint32_t *pMsgRam; |
---|
545 | uint32_t cntr; |
---|
546 | IRQn_Type mCanLine0Irq; |
---|
547 | |
---|
548 | /* Both MCAN controllers use programmable clock 5 to derive bit rate */ |
---|
549 | // select MCK divided by 1 as programmable clock 5 output |
---|
550 | PMC->PMC_PCK[5] = PMC_PCK_PRES(MCAN_PROG_CLK_PRESCALER - 1) | |
---|
551 | MCAN_PROG_CLK_SELECT; |
---|
552 | PMC->PMC_SCER = PMC_SCER_PCK5; |
---|
553 | |
---|
554 | if (MCAN0 == mcan) { |
---|
555 | #ifndef __rtems__ |
---|
556 | PIO_Configure(pinsMcan0, PIO_LISTSIZE(pinsMcan0)); |
---|
557 | #endif /* __rtems__ */ |
---|
558 | // Enable MCAN peripheral clock |
---|
559 | PMC_EnablePeripheral(ID_MCAN0); |
---|
560 | // Configure Message RAM Base Address |
---|
561 | regVal32 = MATRIX->CCFG_CAN0 & 0x000001FF; |
---|
562 | MATRIX->CCFG_CAN0 = regVal32 | |
---|
563 | ((uint32_t) mcanConfig->msgRam.pStdFilts & 0xFFFF0000); |
---|
564 | mCanLine0Irq = MCAN0_IRQn; |
---|
565 | } else if (MCAN1 == mcan) { |
---|
566 | #ifndef __rtems__ |
---|
567 | PIO_Configure(pinsMcan1, PIO_LISTSIZE(pinsMcan1)); |
---|
568 | #endif /* __rtems__ */ |
---|
569 | // Enable MCAN peripheral clock |
---|
570 | PMC_EnablePeripheral(ID_MCAN1); |
---|
571 | // Configure Message RAM Base Address |
---|
572 | regVal32 = MATRIX->CCFG_SYSIO & 0x0000FFFF; |
---|
573 | MATRIX->CCFG_SYSIO = regVal32 | ((uint32_t) mcanConfig->msgRam.pStdFilts & |
---|
574 | 0xFFFF0000); |
---|
575 | mCanLine0Irq = MCAN1_IRQn; |
---|
576 | } else |
---|
577 | return; |
---|
578 | |
---|
579 | /* Indicates Initialization state */ |
---|
580 | mcan->MCAN_CCCR = MCAN_CCCR_INIT_ENABLED; |
---|
581 | |
---|
582 | do { regVal32 = mcan->MCAN_CCCR; } |
---|
583 | while (0u == (regVal32 & MCAN_CCCR_INIT_ENABLED)); |
---|
584 | |
---|
585 | /* Enable writing to configuration registers */ |
---|
586 | mcan->MCAN_CCCR = MCAN_CCCR_INIT_ENABLED | MCAN_CCCR_CCE_CONFIGURABLE; |
---|
587 | |
---|
588 | /* Global Filter Configuration: Reject remote frames, reject non-matching frames */ |
---|
589 | mcan->MCAN_GFC = MCAN_GFC_RRFE_REJECT | MCAN_GFC_RRFS_REJECT |
---|
590 | | MCAN_GFC_ANFE(2) | MCAN_GFC_ANFS(2); |
---|
591 | |
---|
592 | // Extended ID Filter AND mask |
---|
593 | mcan->MCAN_XIDAM = 0x1FFFFFFF; |
---|
594 | |
---|
595 | /* Interrupt configuration - leave initialization with all interrupts off */ |
---|
596 | // Disable all interrupts |
---|
597 | mcan->MCAN_IE = 0; |
---|
598 | mcan->MCAN_TXBTIE = 0x00000000; |
---|
599 | // All interrupts directed to Line 0 |
---|
600 | mcan->MCAN_ILS = 0x00000000; |
---|
601 | // Disable both interrupt LINE 0 & LINE 1 |
---|
602 | mcan->MCAN_ILE = 0x00; |
---|
603 | // Clear all interrupt flags |
---|
604 | mcan->MCAN_IR = 0xFFCFFFFF; |
---|
605 | /* Enable NVIC - but no interrupts will happen since all sources are |
---|
606 | disabled in MCAN_IE */ |
---|
607 | NVIC_ClearPendingIRQ(mCanLine0Irq); |
---|
608 | NVIC_EnableIRQ(mCanLine0Irq); |
---|
609 | NVIC_ClearPendingIRQ((IRQn_Type) (mCanLine0Irq + 1)); |
---|
610 | NVIC_EnableIRQ((IRQn_Type) (mCanLine0Irq + 1)); |
---|
611 | |
---|
612 | /* Configure CAN bit timing */ |
---|
613 | mcan->MCAN_BTP = mcanConfig->bitTiming; |
---|
614 | mcan->MCAN_FBTP = mcanConfig->fastBitTiming; |
---|
615 | |
---|
616 | /* Configure message RAM starting addresses & sizes */ |
---|
617 | mcan->MCAN_SIDFC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pStdFilts) |
---|
618 | | MCAN_SIDFC_LSS(mcanConfig->nmbrStdFilts); |
---|
619 | mcan->MCAN_XIDFC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pExtFilts) |
---|
620 | | MCAN_XIDFC_LSE(mcanConfig->nmbrExtFilts); |
---|
621 | mcan->MCAN_RXF0C = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pRxFifo0) |
---|
622 | | MCAN_RXF0C_F0S(mcanConfig->nmbrFifo0Elmts); |
---|
623 | // watermark interrupt off, blocking mode |
---|
624 | mcan->MCAN_RXF1C = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pRxFifo1) |
---|
625 | | MCAN_RXF1C_F1S(mcanConfig->nmbrFifo1Elmts); |
---|
626 | // watermark interrupt off, blocking mode |
---|
627 | mcan->MCAN_RXBC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pRxDedBuf); |
---|
628 | mcan->MCAN_TXEFC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pTxEvtFifo) |
---|
629 | | MCAN_TXEFC_EFS(mcanConfig->nmbrTxEvtFifoElmts); |
---|
630 | // watermark interrupt off |
---|
631 | mcan->MCAN_TXBC = MAILBOX_ADDRESS((uint32_t) mcanConfig->msgRam.pTxDedBuf) |
---|
632 | | MCAN_TXBC_NDTB(mcanConfig->nmbrTxDedBufElmts) |
---|
633 | | MCAN_TXBC_TFQS(mcanConfig->nmbrTxFifoQElmts); |
---|
634 | mcan->MCAN_RXESC = ((mcanConfig->rxBufElmtSize >> (29 - MCAN_RXESC_RBDS_Pos)) & |
---|
635 | MCAN_RXESC_RBDS_Msk) | |
---|
636 | ((mcanConfig->rxFifo1ElmtSize >> (29 - MCAN_RXESC_F1DS_Pos)) & |
---|
637 | MCAN_RXESC_F1DS_Msk) | |
---|
638 | ((mcanConfig->rxFifo0ElmtSize >> (29 - MCAN_RXESC_F0DS_Pos)) & |
---|
639 | MCAN_RXESC_F0DS_Msk); |
---|
640 | mcan->MCAN_TXESC = ((mcanConfig->txBufElmtSize >> (29 - MCAN_TXESC_TBDS_Pos)) & |
---|
641 | MCAN_TXESC_TBDS_Msk); |
---|
642 | |
---|
643 | /* Configure Message Filters */ |
---|
644 | // ...Disable all standard filters |
---|
645 | pMsgRam = mcanConfig->msgRam.pStdFilts; |
---|
646 | cntr = mcanConfig->nmbrStdFilts; |
---|
647 | |
---|
648 | while (cntr > 0) { |
---|
649 | *pMsgRam++ = STD_FILT_SFEC_DISABLE; |
---|
650 | cntr--; |
---|
651 | } |
---|
652 | |
---|
653 | // ...Disable all extended filters |
---|
654 | pMsgRam = mcanConfig->msgRam.pExtFilts; |
---|
655 | cntr = mcanConfig->nmbrExtFilts; |
---|
656 | |
---|
657 | while (cntr > 0) { |
---|
658 | *pMsgRam = EXT_FILT_EFEC_DISABLE; |
---|
659 | pMsgRam = pMsgRam + 2; |
---|
660 | cntr--; |
---|
661 | } |
---|
662 | |
---|
663 | mcan->MCAN_NDAT1 = 0xFFFFFFFF; // clear new (rx) data flags |
---|
664 | mcan->MCAN_NDAT2 = 0xFFFFFFFF; // clear new (rx) data flags |
---|
665 | |
---|
666 | regVal32 = mcan->MCAN_CCCR & ~(MCAN_CCCR_CME_Msk | MCAN_CCCR_CMR_Msk); |
---|
667 | mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CME_ISO11898_1; |
---|
668 | mcan->MCAN_CCCR = regVal32 | (MCAN_CCCR_CMR_ISO11898_1 | |
---|
669 | MCAN_CCCR_CME_ISO11898_1); |
---|
670 | |
---|
671 | __DSB(); |
---|
672 | __ISB(); |
---|
673 | } |
---|
674 | |
---|
675 | /** |
---|
676 | * \brief Enables a FUTURE switch to FD mode (tx & rx payloads up to 64 bytes) |
---|
677 | * but transmits WITHOUT bit rate switching |
---|
678 | * INIT must be set - so this should be called between MCAN_Init() and |
---|
679 | * MCAN_Enable() |
---|
680 | * \param mcanConfig Pointer to a MCAN instance. |
---|
681 | */ |
---|
682 | void MCAN_InitFdEnable(const MCan_ConfigType *mcanConfig) |
---|
683 | { |
---|
684 | Mcan *mcan = mcanConfig->pMCan; |
---|
685 | uint32_t regVal32; |
---|
686 | |
---|
687 | regVal32 = mcan->MCAN_CCCR & ~MCAN_CCCR_CME_Msk; |
---|
688 | mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CME(1); |
---|
689 | } |
---|
690 | |
---|
691 | /** |
---|
692 | * \brief Enables a FUTURE switch to FD mode (tx & rx payloads up to 64 bytes) and transmits |
---|
693 | * WITH bit rate switching |
---|
694 | * INIT must be set - so this should be called between MCAN_Init() and MCAN_Enable() |
---|
695 | * \param mcanConfig Pointer to a MCAN instance. |
---|
696 | */ |
---|
697 | void MCAN_InitFdBitRateSwitchEnable(const MCan_ConfigType *mcanConfig) |
---|
698 | { |
---|
699 | Mcan *mcan = mcanConfig->pMCan; |
---|
700 | uint32_t regVal32; |
---|
701 | |
---|
702 | regVal32 = mcan->MCAN_CCCR & ~MCAN_CCCR_CME_Msk; |
---|
703 | mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CME(2); |
---|
704 | } |
---|
705 | |
---|
706 | /** |
---|
707 | * \brief Initializes the MCAN in loop back mode. |
---|
708 | * INIT must be set - so this should be called between MCAN_Init() and |
---|
709 | * MCAN_Enable() |
---|
710 | * \param mcanConfig Pointer to a MCAN instance. |
---|
711 | */ |
---|
712 | void MCAN_InitLoopback(const MCan_ConfigType *mcanConfig) |
---|
713 | { |
---|
714 | Mcan *mcan = mcanConfig->pMCan; |
---|
715 | |
---|
716 | mcan->MCAN_CCCR |= MCAN_CCCR_TEST_ENABLED; |
---|
717 | //mcan->MCAN_CCCR |= MCAN_CCCR_MON_ENABLED; // for internal loop back |
---|
718 | mcan->MCAN_TEST |= MCAN_TEST_LBCK_ENABLED; |
---|
719 | } |
---|
720 | |
---|
721 | /** |
---|
722 | * \brief Initializes MCAN queue for TX |
---|
723 | * INIT must be set - so this should be called between MCAN_Init() and |
---|
724 | * MCAN_Enable() |
---|
725 | * \param mcanConfig Pointer to a MCAN instance. |
---|
726 | */ |
---|
727 | void MCAN_InitTxQueue(const MCan_ConfigType *mcanConfig) |
---|
728 | { |
---|
729 | Mcan *mcan = mcanConfig->pMCan; |
---|
730 | mcan->MCAN_TXBC |= MCAN_TXBC_TFQM; |
---|
731 | } |
---|
732 | |
---|
733 | /** |
---|
734 | * \brief Enable MCAN peripheral. |
---|
735 | * INIT must be set - so this should be called between MCAN_Init() |
---|
736 | * \param mcanConfig Pointer to a MCAN instance. |
---|
737 | */ |
---|
738 | void MCAN_Enable(const MCan_ConfigType *mcanConfig) |
---|
739 | { |
---|
740 | Mcan *mcan = mcanConfig->pMCan; |
---|
741 | mcan->MCAN_CCCR &= ~MCAN_CCCR_INIT_ENABLED; |
---|
742 | } |
---|
743 | |
---|
744 | /** |
---|
745 | * \brief Requests switch to Iso11898-1 (standard / classic) mode (tx & rx |
---|
746 | * payloads up to 8 bytes). |
---|
747 | * \param mcanConfig Pointer to a MCAN instance. |
---|
748 | */ |
---|
749 | void MCAN_RequestIso11898_1(const MCan_ConfigType *mcanConfig) |
---|
750 | { |
---|
751 | Mcan *mcan = mcanConfig->pMCan; |
---|
752 | uint32_t regVal32; |
---|
753 | |
---|
754 | regVal32 = mcan->MCAN_CCCR & ~MCAN_CCCR_CMR_Msk; |
---|
755 | mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CMR_ISO11898_1; |
---|
756 | |
---|
757 | while ((mcan->MCAN_CCCR & (MCAN_CCCR_FDBS | MCAN_CCCR_FDO)) != 0) |
---|
758 | { /* wait */ } |
---|
759 | } |
---|
760 | |
---|
761 | /** |
---|
762 | * \brief Requests switch to FD mode (tx & rx payloads up to 64 bytes) but |
---|
763 | * transmits WITHOUT bit |
---|
764 | * rate switching. requested mode should have been enabled at initialization |
---|
765 | * \param mcanConfig Pointer to a MCAN instance. |
---|
766 | */ |
---|
767 | void MCAN_RequestFd(const MCan_ConfigType *mcanConfig) |
---|
768 | { |
---|
769 | Mcan *mcan = mcanConfig->pMCan; |
---|
770 | uint32_t regVal32; |
---|
771 | |
---|
772 | if ((mcan->MCAN_CCCR & MCAN_CCCR_CME_Msk) == MCAN_CCCR_CME(1)) { |
---|
773 | regVal32 = mcan->MCAN_CCCR & ~MCAN_CCCR_CMR_Msk; |
---|
774 | mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CMR_FD; |
---|
775 | |
---|
776 | while ((mcan->MCAN_CCCR & MCAN_CCCR_FDO) == 0) { /* wait */ } |
---|
777 | } |
---|
778 | } |
---|
779 | |
---|
780 | /** |
---|
781 | * \brief Request switch to FD mode (tx & rx payloads up to 64 bytes) and |
---|
782 | * transmits WITH bit rate switching. |
---|
783 | * requested mode should have been enabled at initialization |
---|
784 | * \param mcanConfig Pointer to a MCAN instance. |
---|
785 | */ |
---|
786 | void MCAN_RequestFdBitRateSwitch(const MCan_ConfigType *mcanConfig) |
---|
787 | { |
---|
788 | Mcan *mcan = mcanConfig->pMCan; |
---|
789 | uint32_t regVal32; |
---|
790 | |
---|
791 | if ((mcan->MCAN_CCCR & MCAN_CCCR_CME_Msk) == MCAN_CCCR_CME(2)) { |
---|
792 | regVal32 = mcan->MCAN_CCCR & ~MCAN_CCCR_CMR_Msk; |
---|
793 | mcan->MCAN_CCCR = regVal32 | MCAN_CCCR_CMR_FD_BITRATE_SWITCH; |
---|
794 | |
---|
795 | while ((mcan->MCAN_CCCR & (MCAN_CCCR_FDBS | MCAN_CCCR_FDO)) != |
---|
796 | (MCAN_CCCR_FDBS | MCAN_CCCR_FDO)) { /* wait */ } |
---|
797 | } |
---|
798 | } |
---|
799 | |
---|
800 | /** |
---|
801 | * \brief Switch on loop back mode. |
---|
802 | * TEST must be set in MCAN_CCCR - e.g. by a prior call to MCAN_InitLoopback() |
---|
803 | * \param mcanConfig Pointer to a MCAN instance. |
---|
804 | */ |
---|
805 | void MCAN_LoopbackOn(const MCan_ConfigType *mcanConfig) |
---|
806 | { |
---|
807 | Mcan *mcan = mcanConfig->pMCan; |
---|
808 | mcan->MCAN_TEST |= MCAN_TEST_LBCK_ENABLED; |
---|
809 | } |
---|
810 | |
---|
811 | /** |
---|
812 | * \brief Switch off loop back mode. |
---|
813 | * \param mcanConfig Pointer to a MCAN instance. |
---|
814 | */ |
---|
815 | void MCAN_LoopbackOff(const MCan_ConfigType *mcanConfig) |
---|
816 | { |
---|
817 | Mcan *mcan = mcanConfig->pMCan; |
---|
818 | mcan->MCAN_TEST &= ~MCAN_TEST_LBCK_ENABLED; |
---|
819 | } |
---|
820 | |
---|
821 | /** |
---|
822 | * \brief Enable message line and message stored to Dedicated Receive Buffer |
---|
823 | * Interrupt Line. |
---|
824 | * \param mcanConfig Pointer to a MCAN instance. |
---|
825 | * \param line Message line. |
---|
826 | */ |
---|
827 | void MCAN_IEnableMessageStoredToRxDedBuffer(const MCan_ConfigType *mcanConfig, |
---|
828 | MCan_IntrLineType line) |
---|
829 | { |
---|
830 | Mcan *mcan = mcanConfig->pMCan; |
---|
831 | |
---|
832 | if (line == CAN_INTR_LINE_0) { |
---|
833 | mcan->MCAN_ILS &= ~MCAN_ILS_DRXL; |
---|
834 | mcan->MCAN_ILE |= MCAN_ILE_EINT0; |
---|
835 | } else { |
---|
836 | // Interrupt Line 1 |
---|
837 | mcan->MCAN_ILS |= MCAN_ILS_DRXL; |
---|
838 | mcan->MCAN_ILE |= MCAN_ILE_EINT1; |
---|
839 | } |
---|
840 | |
---|
841 | mcan->MCAN_IR = MCAN_IR_DRX; // clear previous flag |
---|
842 | mcan->MCAN_IE |= MCAN_IE_DRXE; // enable it |
---|
843 | } |
---|
844 | |
---|
845 | /** |
---|
846 | * \brief Configures a Dedicated TX Buffer. |
---|
847 | * \param mcanConfig Pointer to a MCAN instance. |
---|
848 | * \param buffer Pointer to buffer. |
---|
849 | * \param id Message ID. |
---|
850 | * \param idType Type of ID |
---|
851 | * \param dlc Type of dlc. |
---|
852 | */ |
---|
853 | uint8_t *MCAN_ConfigTxDedBuffer(const MCan_ConfigType *mcanConfig, |
---|
854 | uint8_t buffer, uint32_t id, MCan_IdType idType, MCan_DlcType dlc) |
---|
855 | { |
---|
856 | Mcan *mcan = mcanConfig->pMCan; |
---|
857 | uint32_t *pThisTxBuf = 0; |
---|
858 | |
---|
859 | if (buffer < mcanConfig->nmbrTxDedBufElmts) { |
---|
860 | pThisTxBuf = mcanConfig->msgRam.pTxDedBuf + (buffer * |
---|
861 | (mcanConfig->txBufElmtSize & ELMT_SIZE_MASK)); |
---|
862 | |
---|
863 | if (idType == CAN_STD_ID) |
---|
864 | *pThisTxBuf++ = ((id << 18) & (CAN_11_BIT_ID_MASK << 18)); |
---|
865 | else |
---|
866 | *pThisTxBuf++ = BUFFER_XTD_MASK | (id & CAN_29_BIT_ID_MASK); |
---|
867 | |
---|
868 | *pThisTxBuf++ = (uint32_t) dlc << 16; |
---|
869 | /* enable transmit from buffer to set TC interrupt bit in IR, but |
---|
870 | interrupt will not happen unless TC interrupt is enabled*/ |
---|
871 | mcan->MCAN_TXBTIE = (1 << buffer); |
---|
872 | } |
---|
873 | |
---|
874 | return (uint8_t *) pThisTxBuf; // now it points to the data field |
---|
875 | } |
---|
876 | |
---|
877 | /** |
---|
878 | * \brief Send Tx buffer. |
---|
879 | * \param mcanConfig Pointer to a MCAN instance. |
---|
880 | * \param buffer Pointer to buffer. |
---|
881 | */ |
---|
882 | void MCAN_SendTxDedBuffer(const MCan_ConfigType *mcanConfig, uint8_t buffer) |
---|
883 | { |
---|
884 | Mcan *mcan = mcanConfig->pMCan; |
---|
885 | |
---|
886 | if (buffer < mcanConfig->nmbrTxDedBufElmts) |
---|
887 | mcan->MCAN_TXBAR = (1 << buffer); |
---|
888 | } |
---|
889 | |
---|
890 | /** |
---|
891 | * \brief Adds Message to TX Fifo / Queue |
---|
892 | * \param mcanConfig Pointer to a MCAN instance. |
---|
893 | * \param id Message ID. |
---|
894 | * \param idType Type of ID |
---|
895 | * \param dlc Type of dlc. |
---|
896 | * \param data Pointer to data. |
---|
897 | */ |
---|
898 | uint32_t MCAN_AddToTxFifoQ(const MCan_ConfigType *mcanConfig, |
---|
899 | uint32_t id, MCan_IdType idType, MCan_DlcType dlc, uint8_t *data) |
---|
900 | { |
---|
901 | Mcan *mcan = mcanConfig->pMCan; |
---|
902 | uint32_t putIdx = 255; |
---|
903 | uint32_t *pThisTxBuf = 0; |
---|
904 | uint8_t *pTxData; |
---|
905 | uint8_t msgLength; |
---|
906 | uint8_t cnt; |
---|
907 | |
---|
908 | // Configured for FifoQ and FifoQ not full? |
---|
909 | if ((mcanConfig->nmbrTxFifoQElmts > 0) && |
---|
910 | ((mcan->MCAN_TXFQS & MCAN_TXFQS_TFQF) == 0)) { |
---|
911 | putIdx = (mcan->MCAN_TXFQS & MCAN_TXFQS_TFQPI_Msk) >> MCAN_TXFQS_TFQPI_Pos; |
---|
912 | pThisTxBuf = mcanConfig->msgRam.pTxDedBuf + (putIdx * |
---|
913 | (mcanConfig->txBufElmtSize & ELMT_SIZE_MASK)); |
---|
914 | |
---|
915 | if (idType == CAN_STD_ID) |
---|
916 | *pThisTxBuf++ = ((id << 18) & (CAN_11_BIT_ID_MASK << 18)); |
---|
917 | else |
---|
918 | *pThisTxBuf++ = BUFFER_XTD_MASK | (id & CAN_29_BIT_ID_MASK); |
---|
919 | |
---|
920 | *pThisTxBuf++ = (uint32_t) dlc << 16; |
---|
921 | pTxData = (uint8_t *) pThisTxBuf; |
---|
922 | msgLength = dlcToMsgLength[dlc]; |
---|
923 | |
---|
924 | for (cnt = 0; cnt < msgLength; cnt++) |
---|
925 | *pTxData++ = *data++; |
---|
926 | |
---|
927 | /* enable transmit from buffer to set TC interrupt bit in IR, but |
---|
928 | interrupt will not happen unless TC interrupt is enabled */ |
---|
929 | mcan->MCAN_TXBTIE = (1 << putIdx); |
---|
930 | // request to send |
---|
931 | mcan->MCAN_TXBAR = (1 << putIdx); |
---|
932 | } |
---|
933 | |
---|
934 | return putIdx; // now it points to the data field |
---|
935 | } |
---|
936 | |
---|
937 | /** |
---|
938 | * \brief Check if data transmitted from buffer/fifo/queue |
---|
939 | * \param mcanConfig Pointer to a MCAN instance. |
---|
940 | * \param buffer Pointer to data buffer. |
---|
941 | */ |
---|
942 | uint8_t MCAN_IsBufferTxd(const MCan_ConfigType *mcanConfig, uint8_t buffer) |
---|
943 | { |
---|
944 | Mcan *mcan = mcanConfig->pMCan; |
---|
945 | |
---|
946 | return (mcan->MCAN_TXBTO & (1 << buffer)); |
---|
947 | } |
---|
948 | |
---|
949 | /** |
---|
950 | * \brief Configure RX Buffer Filter |
---|
951 | * ID must match exactly for a RX Buffer Filter |
---|
952 | * \param mcanConfig Pointer to a MCAN instance. |
---|
953 | * \param buffer Pointer to data buffer. |
---|
954 | * \param filter data of filter. |
---|
955 | * \param idType Type of ID |
---|
956 | */ |
---|
957 | void MCAN_ConfigRxBufferFilter(const MCan_ConfigType *mcanConfig, |
---|
958 | uint32_t buffer, uint32_t filter, uint32_t id, MCan_IdType idType) |
---|
959 | { |
---|
960 | uint32_t *pThisRxFilt = 0; |
---|
961 | |
---|
962 | if (buffer < mcanConfig->nmbrRxDedBufElmts) { |
---|
963 | if (idType == CAN_STD_ID) { |
---|
964 | if ((filter < mcanConfig->nmbrStdFilts) |
---|
965 | && (id <= CAN_11_BIT_ID_MASK)) { |
---|
966 | pThisRxFilt = mcanConfig->msgRam.pStdFilts + filter; |
---|
967 | // 1 word per filter |
---|
968 | *pThisRxFilt = STD_FILT_SFEC_BUFFER | (id << 16) | |
---|
969 | STD_FILT_SFID2_RX_BUFFER | buffer; |
---|
970 | } |
---|
971 | } else { |
---|
972 | // extended ID |
---|
973 | if ((filter < mcanConfig->nmbrExtFilts) && |
---|
974 | (id <= CAN_29_BIT_ID_MASK)) { |
---|
975 | pThisRxFilt = mcanConfig->msgRam.pExtFilts + (2 * filter); |
---|
976 | // 2 words per filter |
---|
977 | *pThisRxFilt++ = (uint32_t) EXT_FILT_EFEC_BUFFER | id; |
---|
978 | *pThisRxFilt = EXT_FILT_EFID2_RX_BUFFER | buffer; |
---|
979 | } |
---|
980 | } |
---|
981 | } |
---|
982 | } |
---|
983 | |
---|
984 | /** |
---|
985 | * \brief Configure Classic Filter |
---|
986 | * Classic Filters direct accepted messages to a FIFO & include both a ID and |
---|
987 | * a ID mask |
---|
988 | * \param mcanConfig Pointer to a MCAN instance. |
---|
989 | * \param buffer Pointer to data buffer. |
---|
990 | * \param fifo fifo Number. |
---|
991 | * \param filter data of filter. |
---|
992 | * \param idType Type of ID |
---|
993 | * \param mask Mask to be match |
---|
994 | */ |
---|
995 | void MCAN_ConfigRxClassicFilter(const MCan_ConfigType *mcanConfig, |
---|
996 | MCan_FifoType fifo, uint8_t filter, uint32_t id, |
---|
997 | MCan_IdType idType, uint32_t mask) |
---|
998 | { |
---|
999 | uint32_t *pThisRxFilt = 0; |
---|
1000 | uint32_t filterTemp; |
---|
1001 | |
---|
1002 | if (idType == CAN_STD_ID) { |
---|
1003 | if ((filter < mcanConfig->nmbrStdFilts) && (id <= CAN_11_BIT_ID_MASK) |
---|
1004 | && (mask <= CAN_11_BIT_ID_MASK)) { |
---|
1005 | pThisRxFilt = mcanConfig->msgRam.pStdFilts + filter; |
---|
1006 | // 1 word per filter |
---|
1007 | filterTemp = (uint32_t) STD_FILT_SFT_CLASSIC | (id << 16) | mask; |
---|
1008 | |
---|
1009 | if (fifo == CAN_FIFO_0) |
---|
1010 | *pThisRxFilt = STD_FILT_SFEC_FIFO0 | filterTemp; |
---|
1011 | else if (fifo == CAN_FIFO_1) |
---|
1012 | *pThisRxFilt = STD_FILT_SFEC_FIFO1 | filterTemp; |
---|
1013 | } |
---|
1014 | } else { |
---|
1015 | // extended ID |
---|
1016 | if ((filter < mcanConfig->nmbrExtFilts) |
---|
1017 | && (id <= CAN_29_BIT_ID_MASK) |
---|
1018 | && (mask <= CAN_29_BIT_ID_MASK)) { |
---|
1019 | pThisRxFilt = mcanConfig->msgRam.pExtFilts + (2 * filter); |
---|
1020 | |
---|
1021 | // 2 words per filter |
---|
1022 | if (fifo == CAN_FIFO_0) |
---|
1023 | *pThisRxFilt++ = EXT_FILT_EFEC_FIFO0 | id; |
---|
1024 | else if (fifo == CAN_FIFO_1) |
---|
1025 | *pThisRxFilt++ = EXT_FILT_EFEC_FIFO1 | id; |
---|
1026 | |
---|
1027 | *pThisRxFilt = (uint32_t) EXT_FILT_EFT_CLASSIC | mask; |
---|
1028 | } |
---|
1029 | } |
---|
1030 | } |
---|
1031 | |
---|
1032 | /** |
---|
1033 | * \brief check if data received into buffer |
---|
1034 | * \param mcanConfig Pointer to a MCAN instance. |
---|
1035 | * \param buffer Pointer to data buffer. |
---|
1036 | */ |
---|
1037 | uint8_t MCAN_IsNewDataInRxDedBuffer(const MCan_ConfigType *mcanConfig, |
---|
1038 | uint8_t buffer) |
---|
1039 | { |
---|
1040 | Mcan *mcan = mcanConfig->pMCan; |
---|
1041 | |
---|
1042 | if (buffer < 32) |
---|
1043 | return (mcan->MCAN_NDAT1 & (1 << buffer)); |
---|
1044 | else if (buffer < 64) |
---|
1045 | return (mcan->MCAN_NDAT1 & (1 << (buffer - 32))); |
---|
1046 | else |
---|
1047 | return 0; |
---|
1048 | } |
---|
1049 | |
---|
1050 | /** |
---|
1051 | * \brief Get Rx buffer |
---|
1052 | * \param mcanConfig Pointer to a MCAN instance. |
---|
1053 | * \param buffer Pointer to data buffer. |
---|
1054 | * \param pRxMailbox Pointer to rx Mailbox. |
---|
1055 | */ |
---|
1056 | void MCAN_GetRxDedBuffer(const MCan_ConfigType *mcanConfig, |
---|
1057 | uint8_t buffer, Mailbox64Type *pRxMailbox) |
---|
1058 | { |
---|
1059 | Mcan *mcan = mcanConfig->pMCan; |
---|
1060 | uint32_t *pThisRxBuf = 0; |
---|
1061 | uint32_t tempRy; // temp copy of RX buffer word |
---|
1062 | uint32_t dlc; |
---|
1063 | uint8_t *pRxData; |
---|
1064 | uint8_t idx; |
---|
1065 | |
---|
1066 | if (buffer < mcanConfig->nmbrRxDedBufElmts) { |
---|
1067 | pThisRxBuf = mcanConfig->msgRam.pRxDedBuf |
---|
1068 | + (buffer * (mcanConfig->rxBufElmtSize & ELMT_SIZE_MASK)); |
---|
1069 | tempRy = *pThisRxBuf++; // word R0 contains ID |
---|
1070 | |
---|
1071 | if (tempRy & BUFFER_XTD_MASK) { |
---|
1072 | // extended ID? |
---|
1073 | pRxMailbox->info.id = tempRy & BUFFER_EXT_ID_MASK; |
---|
1074 | } else { |
---|
1075 | // standard ID |
---|
1076 | pRxMailbox->info.id = (tempRy & BUFFER_STD_ID_MASK) >> 18; |
---|
1077 | } |
---|
1078 | |
---|
1079 | tempRy = *pThisRxBuf++; // word R1 contains DLC & time stamp |
---|
1080 | dlc = (tempRy & BUFFER_DLC_MASK) >> 16; |
---|
1081 | pRxMailbox->info.length = dlcToMsgLength[dlc]; |
---|
1082 | pRxMailbox->info.timestamp = tempRy & BUFFER_RXTS_MASK; |
---|
1083 | // copy the data from the buffer to the mailbox |
---|
1084 | pRxData = (uint8_t *) pThisRxBuf; |
---|
1085 | |
---|
1086 | SCB_CleanDCache_by_Addr((uint32_t *)pRxData, pRxMailbox->info.length); |
---|
1087 | SCB_CleanDCache_by_Addr((uint32_t *) & (pRxMailbox->data[0]), |
---|
1088 | pRxMailbox->info.length); |
---|
1089 | |
---|
1090 | for (idx = 0; idx < pRxMailbox->info.length; idx++) |
---|
1091 | pRxMailbox->data[idx] = *pRxData++; |
---|
1092 | |
---|
1093 | /* clear the new data flag for the buffer */ |
---|
1094 | |
---|
1095 | if (buffer < 32) |
---|
1096 | mcan->MCAN_NDAT1 = (1 << buffer); |
---|
1097 | else |
---|
1098 | mcan->MCAN_NDAT1 = (1 << (buffer - 32)); |
---|
1099 | |
---|
1100 | } |
---|
1101 | } |
---|
1102 | |
---|
1103 | /** |
---|
1104 | * \brief Get from the receive FIFO and place in a application mailbox |
---|
1105 | * \param mcanConfig Pointer to a MCAN instance. |
---|
1106 | * \param fifo Fifo Number |
---|
1107 | * \param pRxMailbox Pointer to rx Mailbox. |
---|
1108 | * \return: # of fifo entries at the start of the function |
---|
1109 | * 0 -> FIFO was empty at start |
---|
1110 | * 1 -> FIFO had 1 entry at start, but is empty at finish |
---|
1111 | * 2 -> FIFO had 2 entries at start, has 1 entry at finish |
---|
1112 | */ |
---|
1113 | uint32_t MCAN_GetRxFifoBuffer(const MCan_ConfigType *mcanConfig, |
---|
1114 | MCan_FifoType fifo, Mailbox64Type *pRxMailbox) |
---|
1115 | { |
---|
1116 | Mcan *mcan = mcanConfig->pMCan; |
---|
1117 | uint32_t *pThisRxBuf = 0; |
---|
1118 | uint32_t tempRy; // temp copy of RX buffer word |
---|
1119 | uint32_t dlc; |
---|
1120 | uint8_t *pRxData; |
---|
1121 | uint8_t idx; |
---|
1122 | uint32_t *fifo_ack_reg; |
---|
1123 | uint32_t get_index; |
---|
1124 | uint32_t fill_level; |
---|
1125 | uint32_t element_size; |
---|
1126 | |
---|
1127 | // default: fifo empty |
---|
1128 | fill_level = 0; |
---|
1129 | |
---|
1130 | if (fifo == CAN_FIFO_0) { |
---|
1131 | get_index = (mcan->MCAN_RXF0S & MCAN_RXF0S_F0GI_Msk) >> MCAN_RXF0S_F0GI_Pos; |
---|
1132 | fill_level = (mcan->MCAN_RXF0S & MCAN_RXF0S_F0FL_Msk) >> MCAN_RXF0S_F0FL_Pos; |
---|
1133 | pThisRxBuf = mcanConfig->msgRam.pRxFifo0; |
---|
1134 | element_size = mcanConfig->rxFifo0ElmtSize & ELMT_SIZE_MASK; |
---|
1135 | fifo_ack_reg = (uint32_t *) &mcan->MCAN_RXF0A; |
---|
1136 | } else if (fifo == CAN_FIFO_1) { |
---|
1137 | get_index = (mcan->MCAN_RXF1S & MCAN_RXF1S_F1GI_Msk) >> MCAN_RXF1S_F1GI_Pos; |
---|
1138 | fill_level = (mcan->MCAN_RXF1S & MCAN_RXF1S_F1FL_Msk) >> MCAN_RXF1S_F1FL_Pos; |
---|
1139 | pThisRxBuf = mcanConfig->msgRam.pRxFifo1; |
---|
1140 | element_size = mcanConfig->rxFifo1ElmtSize & ELMT_SIZE_MASK; |
---|
1141 | fifo_ack_reg = (uint32_t *) &mcan->MCAN_RXF1A; |
---|
1142 | } |
---|
1143 | |
---|
1144 | if (fill_level > 0) { |
---|
1145 | pThisRxBuf = pThisRxBuf + (get_index * element_size); |
---|
1146 | tempRy = *pThisRxBuf++; // word R0 contains ID |
---|
1147 | |
---|
1148 | if (tempRy & BUFFER_XTD_MASK) { |
---|
1149 | // extended ID? |
---|
1150 | pRxMailbox->info.id = tempRy & BUFFER_EXT_ID_MASK; |
---|
1151 | } else { |
---|
1152 | // standard ID |
---|
1153 | pRxMailbox->info.id = (tempRy & BUFFER_STD_ID_MASK) >> 18; |
---|
1154 | } |
---|
1155 | |
---|
1156 | tempRy = *pThisRxBuf++; // word R1 contains DLC & timestamps |
---|
1157 | dlc = (tempRy & BUFFER_DLC_MASK) >> 16; |
---|
1158 | pRxMailbox->info.length = dlcToMsgLength[dlc]; |
---|
1159 | pRxMailbox->info.timestamp = tempRy & BUFFER_RXTS_MASK; |
---|
1160 | /* copy the data from the buffer to the mailbox */ |
---|
1161 | pRxData = (uint8_t *) pThisRxBuf; |
---|
1162 | |
---|
1163 | for (idx = 0; idx < pRxMailbox->info.length; idx++) |
---|
1164 | pRxMailbox->data[idx] = *pRxData++; |
---|
1165 | |
---|
1166 | // acknowledge reading the fifo entry |
---|
1167 | *fifo_ack_reg = get_index; |
---|
1168 | /* return entries remaining in FIFO */ |
---|
1169 | } |
---|
1170 | |
---|
1171 | return (fill_level); |
---|
1172 | } |
---|
1173 | |
---|
1174 | /**@}*/ |
---|
1175 | |
---|