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