0% found this document useful (0 votes)
48 views15 pages

XMC Can C

can

Uploaded by

Roberto Dias
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
48 views15 pages

XMC Can C

can

Uploaded by

Roberto Dias
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

1 /**

2 * @file xmc_can.c
3 * @date 2020-03-17
4 *
5 * @cond
6 *****************************************************************************
7 * XMClib v2.2.0 - XMC Peripheral Driver Library
8 *
9 * Copyright (c) 2015-2020, Infineon Technologies AG
10 * All rights reserved.
11 *
12 * Boost Software License - Version 1.0 - August 17th, 2003
13 *
14 * Permission is hereby granted, free of charge, to any person or organization
15 * obtaining a copy of the software and accompanying documentation covered by
16 * this license (the "Software") to use, reproduce, display, distribute,
17 * execute, and transmit the Software, and to prepare derivative works of the
18 * Software, and to permit third-parties to whom the Software is furnished to
19 * do so, all subject to the following:
20 *
21 * The copyright notices in the Software and this entire statement, including
22 * the above license grant, this restriction and the following disclaimer,
23 * must be included in all copies of the Software, in whole or in part, and
24 * all derivative works of the Software, unless such copies or derivative
25 * works are solely in the form of machine-executable object code generated by
26 * a source language processor.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
31 * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
32 * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
33 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
34 * DEALINGS IN THE SOFTWARE.
35 *
36 * To improve the quality of the software, users are encouraged to share
37 * modifications, enhancements or bug fixes with Infineon Technologies AG
38 * at [email protected].
39 *****************************************************************************
40 *
41 * Change History
42 * --------------
43 *
44 * 2015-02-20:
45 * - Initial draft <br>
46 *
47 * 2015-05-20:
48 * - New API added: XMC_CAN_MO_ReceiveData() <br>
49 * - XMC_CAN_MO_Config() signature has changed <br>
50 * - Minor fix in XMC_CAN_TXFIFO_ConfigMOSlaveObject(). <br>
51 *
52 * 2015-06-20:
53 * - Removed version macros and declaration of GetDriverVersion API
54 *
55 * 2015-09-01:
56 * - Removed fCANB clock support <br>
57 *
58 * 2015-09-08:
59 * - Fixed bug in XMC_CAN_Init() <br>
60 *
61 * 2016-06-07:
62 * - Changed XMC_CAN_AllocateMOtoNodeList to wait for ready status of list
controller
63 *
64 * 2016-06-20:
65 * - Fixed bug in XMC_CAN_MO_Config() <br>
66 *
67 * 2017-11-09:
68 * - Added XMC_CAN_InitEx() and XMC_CAN_NODE_NominalBitTimeConfigureEx()
69 * - Make XMC_CAN_GetBaudrateClockSource(), XMC_CAN_SetBaudrateClockSource() and
XMC_CAN_GetBaudrateClockFrequency() available to all devices
70 * - Changed refactoring XMC_CAN_MO_Config() to configure MOCTR depending on
transmit or receive message type
71 *
72 * 2018-06-21:
73 * - Fixed XMC_CAN_NODE_NominalBitTimeConfigureEx()
74 *
75 * 2018-11-12:
76 * - Fixed assertion at XMC_CAN_InitEx()
77 *
78 * 2019-05-07:
79 * - Fixed compilation warnings
80 *
81 * 2019-06-26:
82 * - Fixed XMC_CAN_NODE_NominalBitTimeConfigureEx() non returning, decrementing
ntq before continuing with next iteration
83 * - Added XMC_CAN_GetClockFrequency()
84 * - Fixed XMC_CAN_InitEx() so that XMC_CAN_SetBaudrateClockSource() is invoked
before XMC_CAN_GetBaudrateClockFrequency()
85 *
86 * 2020-03-17:
87 * - Fixed XMC_CAN_MO_ReceiveData() according to description in the reference
manual
88 * - Fixed XMC_CAN_MO_SetAcceptanceMask(), checking for matching message IDE
89 *
90 * @endcond
91 *
92 */
93
94 /*******************************************************************************
95 * HEADER FILES
96 *******************************************************************************/
97 #include "xmc_can.h"
98
99 #if defined(CAN)
100 #include "xmc_scu.h"
101
102 __STATIC_INLINE uint32_t max(uint32_t a, uint32_t b)
103 {
104 return (a > b) ? a : b;
105 }
106
107 __STATIC_INLINE uint32_t min(uint32_t a, uint32_t b)
108 {
109 return (a < b) ? a : b;
110 }
111
112 /*******************************************************************************
113 * API IMPLEMENTATION
114 *******************************************************************************/
115
116 /* The max prescaler is the equal to max BRP setting (64) multiply by 8 (DIV8) */
117 #define XMC_CAN_NODE_MAX_PRESCALER 512
118
119 /* maximum TSEG1 is 16 and maximum TSEG2 is 8, plus one fix sync tq */
120 #define XMC_CAN_NODE_MAX_NTQ 25
121 #define XMC_CAN_NODE_MIN_NTQ 8
122
123 #define XMC_CAN_NODE_MIN_TSEG1 3
124 #define XMC_CAN_NODE_MIN_TSEG2 2
125
126 #define XMC_CAN_NODE_MAX_TSEG1 15
127 #define XMC_CAN_NODE_MAX_TSEG2 7
128
129
130 int32_t XMC_CAN_NODE_NominalBitTimeConfigureEx(XMC_CAN_NODE_t *const can_node,
131 const XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t *const bit_time_config)
132 {
133 /* Check that the CAN frequency is a multiple of the required baudrate */
134 if ((bit_time_config->can_frequency % bit_time_config->baudrate) == 0)
135 {
136 uint32_t prescaler = 0;
137 uint32_t div8 = 0;
138
139 /* Calculate the factor between can frequency and required baudrate, this is
equal to (prescaler x ntq) */
140 uint32_t fcan_div = bit_time_config->can_frequency / bit_time_config->baudrate;
141
142 /* start with highest ntq, i.e as much as possible time quanta should be used to
construct a bit time */
143 uint32_t ntq = XMC_CAN_NODE_MAX_NTQ;
144 uint32_t tseg1 = 0;
145 uint32_t tseg2 = 0;
146 while (ntq >= XMC_CAN_NODE_MIN_NTQ)
147 {
148 /* consider this ntq, only if fcan_div is multiple of ntq */
149 if ((fcan_div % ntq) == 0)
150 {
151 div8 = 0;
152 prescaler = fcan_div / ntq;
153 if ((prescaler > 0) && (prescaler <= XMC_CAN_NODE_MAX_PRESCALER))
154 {
155 if (prescaler >= 64)
156 {
157 /* consider prescaler >=64, if it is integer divisible by 8*/
158 if ((prescaler & 0x7U) != 0)
159 {
160 --ntq;
161 continue;
162 }
163 else
164 {
165 div8 = 1;
166 }
167 }
168
169 tseg1 = ((ntq - 1) * bit_time_config->sample_point) / 10000;
170 tseg2 = ntq - tseg1 - 1;
171
172 if ((XMC_CAN_NODE_MIN_TSEG1 <= tseg1) && (tseg1 <= XMC_CAN_NODE_MAX_TSEG1)
&&
173 (XMC_CAN_NODE_MIN_TSEG2 <= tseg2) && (tseg2 < XMC_CAN_NODE_MAX_TSEG2) &&
(tseg2 >= bit_time_config->sjw))
174 {
175 break;
176 }
177
178
179 }
180 }
181 --ntq;
182 }
183
184 if (ntq >= XMC_CAN_NODE_MIN_NTQ)
185 {
186
187 XMC_ASSERT("XMC_CAN_NODE_NominalBitTimeConfigureEx: prescaler", (prescaler != 0
));
188 XMC_ASSERT("XMC_CAN_NODE_NominalBitTimeConfigureEx: tseg1", (tseg1 != 0));
189 XMC_ASSERT("XMC_CAN_NODE_NominalBitTimeConfigureEx: tseg2", (tseg2 != 0));
190
191 XMC_CAN_NODE_EnableConfigurationChange(can_node);
192
193 /* Configure bit timing register */
194 can_node->NBTR = (((tseg2 - 1u) << CAN_NODE_NBTR_TSEG2_Pos) & (uint32_t)
CAN_NODE_NBTR_TSEG2_Msk) |
195 (((bit_time_config->sjw - 1U) << CAN_NODE_NBTR_SJW_Pos) & (
uint32_t)CAN_NODE_NBTR_SJW_Msk) |
196 (((tseg1 - 1U) << CAN_NODE_NBTR_TSEG1_Pos) & (uint32_t)
CAN_NODE_NBTR_TSEG1_Msk) |
197 ((((prescaler >> (3 * div8)) - 1U) << CAN_NODE_NBTR_BRP_Pos) &
(uint32_t)CAN_NODE_NBTR_BRP_Msk) |
198 ((div8 << CAN_NODE_NBTR_DIV8_Pos) & (uint32_t)
CAN_NODE_NBTR_DIV8_Msk);
199
200 XMC_CAN_NODE_DisableConfigurationChange(can_node);
201
202 return XMC_CAN_STATUS_SUCCESS;
203 }
204 }
205
206 return XMC_CAN_STATUS_ERROR;
207 }
208
209 /* Baudrate Configuration */
210 void XMC_CAN_NODE_NominalBitTimeConfigure (XMC_CAN_NODE_t *const can_node,
211 const XMC_CAN_NODE_NOMINAL_BIT_TIME_CONFIG_t *const can_bit_time)
212 {
213 uint32_t temp_brp = 12U ;
214 uint32_t temp_tseg1 = 12U;
215 uint32_t best_brp = 0U;
216 uint32_t best_tseg1 = 1U;
217 uint32_t best_tseg2 = 0U;
218 uint32_t best_tbaud = 0U;
219 uint32_t best_error = 10000U;
220
221 XMC_ASSERT("XMC_CAN_NODE_NOMINAL_BIT_TIME_Configure: rate not supported", (
can_bit_time->baudrate < 1000000U) ||
222 (can_bit_time->baudrate >= 100000U));
223 XMC_ASSERT("XMC_CAN_NODE_NOMINAL_BIT_TIME_Configure: fCAN not supported",
224 can_bit_time->can_frequency <= 120000000U);
225 XMC_ASSERT("XMC_CAN_NODE_NOMINAL_BIT_TIME_Configure: fCAN not supported",
226 can_bit_time->can_frequency > 5000000U);
227 XMC_ASSERT("XMC_CAN_NODE_NOMINAL_BIT_TIME_Configure: sample point not supported",
228 (can_bit_time->sample_point < 10000U) && ((can_bit_time->sample_point >
0U)));
229
230 /*
231 * Bit timing & sampling
232 * Tq = (BRP+1)/Fcan if DIV8 = 0
233 * Tq = 8*(BRP+1)/Fcan if DIV8 = 1
234 * TSync = 1.Tq
235 * TSeg1 = (TSEG1+1)*Tq >= 3Tq
236 * TSeg2 = (TSEG2+1)*Tq >= 2Tq
237 * Bit Time = TSync + TSeg1 + TSeg2 >= 8Tq
238 *
239 * Resynchronization:
240 *
241 * Tsjw = (SJW + 1)*Tq
242 * TSeg1 >= Tsjw + Tprop
243 * TSeg2 >= Tsjw
244 */
245 /* search for best baudrate */
246 for (temp_brp = 1U; temp_brp <= 64U; temp_brp++)
247 {
248
249 uint32_t f_quanta = (uint32_t)((can_bit_time->can_frequency * 10U) / temp_brp);
250 uint32_t temp_tbaud = (uint32_t)(f_quanta / (can_bit_time->baudrate));
251 uint32_t temp_baudrate;
252 uint32_t error;
253
254 if ((temp_tbaud % 10U) > 5U)
255 {
256 temp_tbaud = (uint32_t)(temp_tbaud / 10U);
257 temp_tbaud++;
258 }
259 else
260 {
261 temp_tbaud = (uint32_t)(temp_tbaud / 10U);
262 }
263
264 if (temp_tbaud > 0U)
265 {
266 temp_baudrate = (uint32_t) (f_quanta / (temp_tbaud * 10U));
267 }
268 else
269 {
270 temp_baudrate = f_quanta / 10U;
271 temp_tbaud = 1;
272 }
273
274 if (temp_baudrate >= can_bit_time->baudrate)
275 {
276 error = temp_baudrate - can_bit_time->baudrate;
277 }
278 else
279 {
280 error = can_bit_time->baudrate - temp_baudrate;
281 }
282
283 if ((temp_tbaud <= 20U) && (best_error > error))
284 {
285 best_brp = temp_brp;
286 best_tbaud = temp_tbaud;
287 best_error = (error);
288
289 if (error < 1000U)
290 {
291 break;
292 }
293 }
294 }
295 /* search for best sample point */
296 best_error = 10000U;
297
298 for (temp_tseg1 = 64U; temp_tseg1 >= 3U; temp_tseg1--)
299 {
300 uint32_t tempSamplePoint = ((temp_tseg1 + 1U) * 10000U) / best_tbaud;
301 uint32_t error;
302 if (tempSamplePoint >= can_bit_time->sample_point)
303 {
304 error = tempSamplePoint - can_bit_time->sample_point;
305 }
306 else
307 {
308 error = can_bit_time->sample_point - tempSamplePoint;
309 }
310 if (best_error > error)
311 {
312 best_tseg1 = temp_tseg1;
313 best_error = error;
314 }
315 if (tempSamplePoint < (can_bit_time->sample_point))
316 {
317 break;
318 }
319 }
320
321 best_tseg2 = best_tbaud - best_tseg1 - 1U;
322
323 XMC_CAN_NODE_EnableConfigurationChange(can_node);
324 /* Configure bit timing register */
325 can_node->NBTR = (((uint32_t)(best_tseg2 - 1u) << CAN_NODE_NBTR_TSEG2_Pos) & (
uint32_t)CAN_NODE_NBTR_TSEG2_Msk) |
326 ((((uint32_t)((uint32_t)(can_bit_time->sjw) - 1U) <<
CAN_NODE_NBTR_SJW_Pos)) & (uint32_t)CAN_NODE_NBTR_SJW_Msk) |
327 (((uint32_t)(best_tseg1 - 1U) << CAN_NODE_NBTR_TSEG1_Pos) & (
uint32_t)CAN_NODE_NBTR_TSEG1_Msk) |
328 (((uint32_t)(best_brp - 1U) << CAN_NODE_NBTR_BRP_Pos) & (uint32_t)
CAN_NODE_NBTR_BRP_Msk) |
329 (((uint32_t)0U << CAN_NODE_NBTR_DIV8_Pos) & (uint32_t)
CAN_NODE_NBTR_DIV8_Msk);
330 XMC_CAN_NODE_DisableConfigurationChange(can_node);
331 }
332 /* Function to allocate message object from free list to node list */
333 void XMC_CAN_AllocateMOtoNodeList(XMC_CAN_t *const obj, const uint8_t node_num, const
uint8_t mo_num)
334 {
335 /* wait while panel operation is in progress. */
336 while (XMC_CAN_IsPanelControlReady(obj) == false)
337 {
338 /*Do nothing*/
339 };
340
341 /* Panel Command for allocation of MO to node list */
342 XMC_CAN_PanelControl(obj, XMC_CAN_PANCMD_STATIC_ALLOCATE, mo_num, (node_num + 1U));
343 }
344
345 /* Disable XMC_CAN Peripheral */
346 void XMC_CAN_Disable(XMC_CAN_t *const obj)
347 {
348 /* Disable CAN Module */
349 obj->CLC = CAN_CLC_DISR_Msk;
350 #if defined(PERIPHERAL_RESET_SUPPORTED)
351 XMC_SCU_RESET_AssertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_MCAN);
352 #endif
353 #if defined(CLOCK_GATING_SUPPORTED)
354 XMC_SCU_CLOCK_GatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_MCAN);
355 #endif
356 }
357
358 /* Enable XMC_CAN Peripheral */
359 void XMC_CAN_Enable(XMC_CAN_t *const obj)
360 {
361 #if defined(CLOCK_GATING_SUPPORTED)
362 XMC_SCU_CLOCK_UngatePeripheralClock(XMC_SCU_PERIPHERAL_CLOCK_MCAN);
363 #endif
364 #if defined(PERIPHERAL_RESET_SUPPORTED)
365 XMC_SCU_RESET_DeassertPeripheralReset(XMC_SCU_PERIPHERAL_RESET_MCAN);
366 #endif
367 /* Enable CAN Module */
368 obj->CLC &= ~(uint32_t)CAN_CLC_DISR_Msk;
369 while (obj->CLC & CAN_CLC_DISS_Msk)
370 {
371 /*Do nothing*/
372 };
373 }
374
375 #if defined(MULTICAN_PLUS)
376 void XMC_CAN_Init(XMC_CAN_t *const obj, XMC_CAN_CANCLKSRC_t clksrc, uint32_t
can_frequency)
377 {
378 uint32_t step_n, step_f;
379 bool normal_divider;
380 uint32_t freq_n, freq_f;
381 uint32_t step;
382 uint32_t can_frequency_khz;
383 uint32_t peripheral_frequency_khz;
384 XMC_CAN_DM_t can_divider_mode;
385
386 uint32_t peripheral_frequency;
387 /*Enabling the module*/
388 XMC_CAN_Enable(obj);
389
390 XMC_CAN_SetBaudrateClockSource(obj, clksrc);
391
392 peripheral_frequency = XMC_CAN_GetBaudrateClockFrequency(obj);
393
394 XMC_ASSERT("XMC_CAN_Init: frequency not supported", can_frequency <=
peripheral_frequency);
395
396 /* Normal divider mode */
397 step_n = (uint32_t)min(max(0U, (1024U - (peripheral_frequency / can_frequency))),
1023U);
398 freq_n = (uint32_t) (peripheral_frequency / (1024U - step_n));
399
400 /* Fractional divider mode */
401 can_frequency_khz = (uint32_t) (can_frequency >> 6);
402 peripheral_frequency_khz = (uint32_t)(peripheral_frequency >> 6);
403
404 step_f = (uint32_t)(min( (((1024U * can_frequency_khz) / peripheral_frequency_khz)
), 1023U ));
405 freq_f = (uint32_t)((peripheral_frequency_khz * step_f) / 1024U);
406 freq_f = freq_f << 6;
407
408 normal_divider = (uint32_t)(can_frequency - freq_n) <= (can_frequency - freq_f);
409
410 step = (normal_divider != 0U) ? step_n : step_f;
411 can_divider_mode = (normal_divider != 0U) ? XMC_CAN_DM_NORMAL :
XMC_CAN_DM_FRACTIONAL;
412
413 obj->FDR &= (uint32_t) ~(CAN_FDR_DM_Msk | CAN_FDR_STEP_Msk);
414 obj->FDR |= ((uint32_t)can_divider_mode << CAN_FDR_DM_Pos) | ((uint32_t)step <<
CAN_FDR_STEP_Pos);
415
416 }
417
418 #else
419 /* Initialization of XMC_CAN GLOBAL Object */
420 void XMC_CAN_Init(XMC_CAN_t *const obj, uint32_t can_frequency)
421 {
422 uint32_t step_n, step_f;
423 bool normal_divider;
424 uint32_t freq_n, freq_f;
425 uint32_t step;
426 uint32_t can_frequency_khz;
427 uint32_t peripheral_frequency_khz;
428 XMC_CAN_DM_t can_divider_mode;
429
430 uint32_t peripheral_frequency = (XMC_SCU_CLOCK_GetPeripheralClockFrequency());
431
432 XMC_ASSERT("XMC_CAN_Init: frequency not supported", can_frequency <=
peripheral_frequency);
433
434 /*Enabling the module*/
435 XMC_CAN_Enable(obj);
436
437 /* Normal divider mode */
438 step_n = (uint32_t)min(max(0U, (1024U - (peripheral_frequency / can_frequency))),
1023U);
439 freq_n = (uint32_t) (peripheral_frequency / (1024U - step_n));
440
441 /* Fractional divider mode */
442 can_frequency_khz = (uint32_t) (can_frequency >> 6);
443 peripheral_frequency_khz = (uint32_t)(peripheral_frequency >> 6);
444
445 step_f = (uint32_t)(min( (((1024U * can_frequency_khz) / peripheral_frequency_khz)
), 1023U ));
446 freq_f = (uint32_t)((peripheral_frequency_khz * step_f) / 1024U);
447 freq_f = freq_f << 6;
448
449 normal_divider = (uint32_t)(can_frequency - freq_n) <= (can_frequency - freq_f);
450
451 step = (normal_divider != 0U) ? step_n : step_f;
452 can_divider_mode = (normal_divider != 0U) ? XMC_CAN_DM_NORMAL :
XMC_CAN_DM_FRACTIONAL;
453
454 obj->FDR &= (uint32_t) ~(CAN_FDR_DM_Msk | CAN_FDR_STEP_Msk);
455 obj->FDR |= ((uint32_t)can_divider_mode << CAN_FDR_DM_Pos) | ((uint32_t)step <<
CAN_FDR_STEP_Pos);
456 }
457 #endif
458
459 void XMC_CAN_SetBaudrateClockSource(XMC_CAN_t *const obj, const XMC_CAN_CANCLKSRC_t
source)
460 {
461 #if defined(MULTICAN_PLUS)
462 obj->MCR = (obj->MCR & ~CAN_MCR_CLKSEL_Msk) | source ;
463 #else
464 XMC_UNUSED_ARG(obj);
465 XMC_UNUSED_ARG(source);
466 #endif
467 }
468
469 XMC_CAN_CANCLKSRC_t XMC_CAN_GetBaudrateClockSource(XMC_CAN_t *const obj)
470 {
471 #if defined(MULTICAN_PLUS)
472 return ((XMC_CAN_CANCLKSRC_t)((obj->MCR & CAN_MCR_CLKSEL_Msk) >> CAN_MCR_CLKSEL_Pos
));
473 #elif (UC_FAMILY == XMC4)
474 XMC_UNUSED_ARG(obj);
475 return XMC_CAN_CANCLKSRC_FPERI;
476 #endif
477 }
478
479 uint32_t XMC_CAN_GetBaudrateClockFrequency(XMC_CAN_t *const obj)
480 {
481 uint32_t frequency = 0;
482
483 #if defined(MULTICAN_PLUS)
484 switch (XMC_CAN_GetBaudrateClockSource(obj))
485 {
486 #if UC_FAMILY == XMC4
487 case XMC_CAN_CANCLKSRC_FPERI:
488 frequency = XMC_SCU_CLOCK_GetPeripheralClockFrequency();
489 break;
490 #else
491 case XMC_CAN_CANCLKSRC_MCLK:
492 frequency = XMC_SCU_CLOCK_GetPeripheralClockFrequency();
493 break;
494 #endif
495 case XMC_CAN_CANCLKSRC_FOHP:
496 frequency = OSCHP_GetFrequency();
497 break;
498 }
499 #else
500 XMC_UNUSED_ARG(obj);
501 frequency = XMC_SCU_CLOCK_GetPeripheralClockFrequency();
502 #endif
503
504 return frequency;
505 }
506
507 uint32_t XMC_CAN_InitEx(XMC_CAN_t *const obj, XMC_CAN_CANCLKSRC_t clksrc, uint32_t
can_frequency)
508 {
509 uint32_t step_n;
510 uint32_t freq_n;
511 uint32_t peripheral_frequency;
512
513 /*Enabling the module*/
514 XMC_CAN_Enable(obj);
515
516 XMC_CAN_SetBaudrateClockSource(obj, clksrc);
517 peripheral_frequency = XMC_CAN_GetBaudrateClockFrequency(obj);
518 XMC_ASSERT("XMC_CAN_Init: frequency not supported", can_frequency <=
peripheral_frequency);
519
520 /* Normal divider mode */
521 step_n = (uint32_t)min(max(0U, (1024U - (peripheral_frequency / can_frequency))),
1023U);
522 freq_n = (uint32_t)(peripheral_frequency / (1024U - step_n));
523
524 obj->FDR &= (uint32_t) ~(CAN_FDR_DM_Msk | CAN_FDR_STEP_Msk);
525 obj->FDR |= ((uint32_t)XMC_CAN_DM_NORMAL << CAN_FDR_DM_Pos) | ((uint32_t)step_n <<
CAN_FDR_STEP_Pos);
526
527 return freq_n;
528 }
529
530 uint32_t XMC_CAN_GetClockFrequency(XMC_CAN_t *const obj)
531 {
532 uint32_t step_n = (obj->FDR & CAN_FDR_STEP_Msk) >> CAN_FDR_STEP_Pos;
533 return (XMC_CAN_GetBaudrateClockFrequency(obj) * (1024U - step_n));
534 }
535
536 /* Sets the Identifier of the MO */
537 void XMC_CAN_MO_SetIdentifier(XMC_CAN_MO_t *const can_mo, const uint32_t
can_identifier)
538 {
539 if ((can_mo->can_mo_ptr->MOAR & CAN_MO_MOAR_IDE_Msk) != (uint32_t)
CAN_MO_MOAR_IDE_Msk)
540 {
541 can_mo->can_mo_ptr->MOAR = ((can_mo->can_mo_ptr->MOAR) & ~(uint32_t)(
CAN_MO_MOAR_ID_Msk)) |
542 ((can_identifier << XMC_CAN_MO_MOAR_STDID_Pos) & (
uint32_t)CAN_MO_MOAR_ID_Msk);
543 }
544 else
545 {
546 can_mo->can_mo_ptr->MOAR = ((can_mo->can_mo_ptr->MOAR) & ~(uint32_t)(
CAN_MO_MOAR_ID_Msk)) |
547 (can_identifier & (uint32_t)CAN_MO_MOAR_ID_Msk);
548 }
549 can_mo->can_identifier = can_identifier;
550 }
551
552
553 /* Gets the Identifier of the MO */
554 uint32_t XMC_CAN_MO_GetIdentifier(const XMC_CAN_MO_t *const can_mo)
555 {
556 uint32_t identifier;
557 if ((can_mo->can_mo_ptr->MOAR & CAN_MO_MOAR_IDE_Msk) != (uint32_t)
CAN_MO_MOAR_IDE_Msk)
558 {
559 identifier = ((can_mo->can_mo_ptr->MOAR) & (uint32_t)(CAN_MO_MOAR_ID_Msk)) >>
XMC_CAN_MO_MOAR_STDID_Pos;
560 }
561 else
562 {
563 identifier = ((can_mo->can_mo_ptr->MOAR) & (uint32_t)(CAN_MO_MOAR_ID_Msk));
564 }
565 return identifier;
566 }
567
568 /* Gets the acceptance mask for the CAN MO. */
569 uint32_t XMC_CAN_MO_GetAcceptanceMask(const XMC_CAN_MO_t *const can_mo)
570 {
571 uint32_t identifier_mask;
572 if (((can_mo->can_mo_ptr->MOAMR & CAN_MO_MOAMR_MIDE_Msk) != (uint32_t)
CAN_MO_MOAMR_MIDE_Msk)
573 && ((can_mo->can_mo_ptr->MOAR & CAN_MO_MOAR_IDE_Msk) != (uint32_t)
CAN_MO_MOAR_IDE_Msk))
574 {
575 identifier_mask = ((can_mo->can_mo_ptr->MOAMR) & (uint32_t)(CAN_MO_MOAMR_AM_Msk))
>> XMC_CAN_MO_MOAR_STDID_Pos;
576 }
577 else
578 {
579 identifier_mask = ((can_mo->can_mo_ptr->MOAMR) & (uint32_t)(CAN_MO_MOAMR_AM_Msk));
580 }
581 return identifier_mask;
582 }
583
584 /* Sets the acceptance mask of the MO */
585 void XMC_CAN_MO_SetAcceptanceMask(XMC_CAN_MO_t *const can_mo, const uint32_t
can_id_mask)
586 {
587 if (((can_mo->can_mo_ptr->MOAMR & CAN_MO_MOAMR_MIDE_Msk) != 0)
588 && ((can_mo->can_mo_ptr->MOAR & CAN_MO_MOAR_IDE_Msk) == 0))
589 {
590 /* Message object n receives frames only with matching IDE bit. */
591 can_mo->can_mo_ptr->MOAMR = ((can_mo->can_mo_ptr->MOAMR) & ~(uint32_t)(
CAN_MO_MOAMR_AM_Msk)) |
592 ((can_id_mask << XMC_CAN_MO_MOAR_STDID_Pos) & (
uint32_t)XMC_CAN_MO_MOAR_STDID_Msk);
593 }
594 else
595 {
596 can_mo->can_mo_ptr->MOAMR = ((can_mo->can_mo_ptr->MOAMR) & ~(uint32_t)(
CAN_MO_MOAMR_AM_Msk)) |
597 (can_id_mask & (uint32_t)CAN_MO_MOAMR_AM_Msk);
598 }
599
600 can_mo->can_id_mask = can_id_mask;
601 }
602
603 /* Initialization of XMC_CAN MO Object */
604 void XMC_CAN_MO_Config(const XMC_CAN_MO_t *const can_mo)
605 {
606 uint32_t reg;
607
608 /* Configure MPN */
609 uint32_t num = ((uint32_t)(can_mo->can_mo_ptr) - CAN_BASE - 0x1000U) / 0x0020U;
610 uint32_t set = (((uint32_t)(num / 32) << (CAN_MO_MOIPR_MPN_Pos + 5U)) | ((uint32_t)(
num % 32) << CAN_MO_MOIPR_MPN_Pos));
611 can_mo->can_mo_ptr->MOIPR &= ~(CAN_MO_MOIPR_MPN_Msk);
612 can_mo->can_mo_ptr->MOIPR |= set;
613
614 if (((can_mo->can_id_mode != (uint32_t) XMC_CAN_FRAME_TYPE_STANDARD_11BITS) &&
615 (can_mo->can_id_mode != (uint32_t) XMC_CAN_FRAME_TYPE_EXTENDED_29BITS)) ||
616 ((can_mo->can_mo_type != XMC_CAN_MO_TYPE_RECMSGOBJ) &&
617 (can_mo->can_mo_type != XMC_CAN_MO_TYPE_TRANSMSGOBJ)))
618 {
619 /*Do nothing*/
620 }
621 else
622 {
623
624 /* Disable Message object */
625 can_mo->can_mo_ptr->MOCTR = CAN_MO_MOCTR_RESMSGVAL_Msk;
626 if (can_mo->can_id_mode == (uint32_t)XMC_CAN_FRAME_TYPE_STANDARD_11BITS)
627 {
628 reg = can_mo->mo_ar;
629 reg &= (uint32_t) ~(CAN_MO_MOAR_ID_Msk);
630 reg |= (can_mo->can_identifier << XMC_CAN_MO_MOAR_STDID_Pos);
631 can_mo->can_mo_ptr->MOAR = reg;
632
633 reg = can_mo->mo_amr;
634 reg &= (uint32_t) ~(CAN_MO_MOAMR_AM_Msk);
635 reg |= (can_mo->can_id_mask << XMC_CAN_MO_MOAR_STDID_Pos);
636 can_mo->can_mo_ptr->MOAMR = reg;
637 }
638 else
639 {
640 can_mo->can_mo_ptr->MOAR = can_mo->mo_ar;
641 can_mo->can_mo_ptr->MOAMR = can_mo->mo_amr;
642 }
643 /* Check whether message object is transmit message object */
644 if (can_mo->can_mo_type == XMC_CAN_MO_TYPE_TRANSMSGOBJ)
645 {
646 /* Set MO as Transmit message object */
647 XMC_CAN_MO_UpdateData(can_mo);
648 can_mo->can_mo_ptr->MOCTR = CAN_MO_MOCTR_SETDIR_Msk;
649
650 /* Reset RTSEL and Set MSGVAL, TXEN0 and TXEN1 bits */
651 can_mo->can_mo_ptr->MOCTR = (CAN_MO_MOCTR_SETTXEN0_Msk |
CAN_MO_MOCTR_SETTXEN1_Msk | CAN_MO_MOCTR_SETMSGVAL_Msk |
652 CAN_MO_MOCTR_RESRXEN_Msk |
CAN_MO_MOCTR_RESRTSEL_Msk);
653 }
654 else
655 {
656 /* Set MO as Receive message object and set RXEN bit */
657 can_mo->can_mo_ptr->MOCTR = CAN_MO_MOCTR_RESDIR_Msk;
658
659 /* Reset RTSEL, TXEN1 and TXEN2 and Set MSGVAL and RXEN bits */
660 can_mo->can_mo_ptr->MOCTR = (CAN_MO_MOCTR_RESTXEN0_Msk |
CAN_MO_MOCTR_RESTXEN1_Msk | CAN_MO_MOCTR_SETMSGVAL_Msk |
661 CAN_MO_MOCTR_SETRXEN_Msk |
CAN_MO_MOCTR_RESRTSEL_Msk);
662 }
663
664 }
665 }
666
667 /* Update of XMC_CAN Object */
668 XMC_CAN_STATUS_t XMC_CAN_MO_UpdateData(const XMC_CAN_MO_t *const can_mo)
669 {
670 XMC_CAN_STATUS_t error = XMC_CAN_STATUS_MO_NOT_ACCEPTABLE;
671 /* Check whether message object is transmit message object */
672 if (can_mo->can_mo_type == XMC_CAN_MO_TYPE_TRANSMSGOBJ)
673 {
674 can_mo->can_mo_ptr->MOCTR = CAN_MO_MOCTR_RESMSGVAL_Msk;
675 /* Configure data length */
676 can_mo->can_mo_ptr->MOFCR = ((can_mo->can_mo_ptr->MOFCR) & ~(uint32_t)(
CAN_MO_MOFCR_DLC_Msk)) |
677 (((uint32_t) can_mo->can_data_length <<
CAN_MO_MOFCR_DLC_Pos) & (uint32_t)CAN_MO_MOFCR_DLC_Msk
);
678 /* Configure Data registers*/
679 can_mo->can_mo_ptr->MODATAL = can_mo->can_data[0];
680 can_mo->can_mo_ptr->MODATAH = can_mo->can_data[1];
681 /* Reset RTSEL and Set MSGVAL ,TXEN0 and TXEN1 bits */
682 can_mo->can_mo_ptr->MOCTR = (CAN_MO_MOCTR_SETNEWDAT_Msk |
CAN_MO_MOCTR_SETMSGVAL_Msk | CAN_MO_MOCTR_RESRTSEL_Msk);
683 error = XMC_CAN_STATUS_SUCCESS;
684 }
685 else
686 {
687 error = XMC_CAN_STATUS_MO_NOT_ACCEPTABLE;
688 }
689 return error;
690 }
691
692 /* This function is will put a transmit request to transmit message object */
693 XMC_CAN_STATUS_t XMC_CAN_MO_Transmit(const XMC_CAN_MO_t *const can_mo)
694 {
695 XMC_CAN_STATUS_t error = XMC_CAN_STATUS_ERROR;
696 uint32_t mo_type = (uint32_t)(((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_MSGVAL_Msk) >> CAN_MO_MOSTAT_MSGVAL_Pos);
697 uint32_t mo_transmission_ongoing = (uint32_t) ((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_TXRQ_Msk) >> CAN_MO_MOSTAT_TXRQ_Pos;
698 /* check if message is disabled */
699 if (mo_type == 0U)
700 {
701 error = XMC_CAN_STATUS_MO_DISABLED;
702 }
703 /* check if transmission is ongoing on message object */
704 else if (mo_transmission_ongoing == 1U)
705 {
706 error = XMC_CAN_STATUS_BUSY;
707 }
708 else
709 {
710 /* set TXRQ bit */
711 can_mo->can_mo_ptr-> MOCTR = CAN_MO_MOCTR_SETTXRQ_Msk | CAN_MO_MOCTR_SETTXEN0_Msk
| CAN_MO_MOCTR_SETTXEN1_Msk;
712 error = XMC_CAN_STATUS_SUCCESS;
713 }
714 return error;
715 }
716
717 /* This function is will read the message object data bytes */
718 XMC_CAN_STATUS_t XMC_CAN_MO_ReceiveData (XMC_CAN_MO_t *can_mo)
719 {
720 XMC_CAN_STATUS_t error = XMC_CAN_STATUS_ERROR;
721 uint8_t rx_pnd = 0U;
722 uint8_t new_data = 0U;
723 uint32_t mo_type = (uint32_t)((can_mo->can_mo_ptr->MOSTAT) & CAN_MO_MOSTAT_DIR_Msk)
>> CAN_MO_MOSTAT_DIR_Pos;
724 uint32_t mo_recepcion_ongoing = (uint32_t)((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_RXUPD_Msk) >> CAN_MO_MOSTAT_RXUPD_Pos;
725 /* check if message object is a receive message object */
726 if (mo_type != (uint32_t)XMC_CAN_MO_TYPE_RECMSGOBJ)
727 {
728 error = XMC_CAN_STATUS_MO_NOT_ACCEPTABLE;
729 }
730 /* check if reception is ongoing on message object */
731 else if (mo_recepcion_ongoing == 1U)
732 {
733 error = XMC_CAN_STATUS_BUSY;
734 }
735 else
736 {
737 /* read message parameters */
738 do
739 {
740 can_mo->can_data[0] = can_mo->can_mo_ptr->MODATAL;
741 can_mo->can_data[1] = can_mo->can_mo_ptr->MODATAH;
742
743 rx_pnd = (uint8_t)((uint32_t)((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_RXUPD_Msk) >> CAN_MO_MOSTAT_RXUPD_Pos);
744 new_data = (uint8_t)((uint32_t)((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_NEWDAT_Msk) >> CAN_MO_MOSTAT_NEWDAT_Pos);
745 }
746 while ((rx_pnd != 0U) || (new_data != 0U));
747
748 error = XMC_CAN_STATUS_SUCCESS;
749 }
750 return error;
751 }
752
753
754 /* This function is will read the message object data bytes */
755 XMC_CAN_STATUS_t XMC_CAN_MO_Receive (XMC_CAN_MO_t *can_mo)
756 {
757 XMC_CAN_STATUS_t error = XMC_CAN_STATUS_ERROR;
758 uint8_t rx_pnd = 0U;
759 uint8_t new_data = 0U;
760 uint32_t mo_type = (uint32_t)((can_mo->can_mo_ptr->MOSTAT) & CAN_MO_MOSTAT_DIR_Msk)
>> CAN_MO_MOSTAT_DIR_Pos;
761 uint32_t mo_recepcion_ongoing = (uint32_t)((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_RXUPD_Msk) >> CAN_MO_MOSTAT_RXUPD_Pos;
762 /* check if message object is a receive message object */
763 if (mo_type != (uint32_t)XMC_CAN_MO_TYPE_RECMSGOBJ)
764 {
765 error = XMC_CAN_STATUS_MO_NOT_ACCEPTABLE;
766 }
767 /* check if reception is ongoing on message object */
768 else if (mo_recepcion_ongoing == 1U)
769 {
770 error = XMC_CAN_STATUS_BUSY;
771 }
772 else
773 {
774 /* read message parameters */
775 do
776 {
777 can_mo->can_mo_ptr->MOCTR = CAN_MO_MOCTR_RESNEWDAT_Msk;
778 if ((((can_mo->can_mo_ptr->MOAR) & CAN_MO_MOAR_IDE_Msk) >> CAN_MO_MOAR_IDE_Pos)
== 0U)
779 {
780 can_mo->can_id_mode = (uint32_t)XMC_CAN_FRAME_TYPE_STANDARD_11BITS;
781 can_mo->can_identifier = (can_mo->can_mo_ptr->MOAR & XMC_CAN_MO_MOAR_STDID_Msk
) >> XMC_CAN_MO_MOAR_STDID_Pos;
782 can_mo->can_ide_mask = (uint32_t)(can_mo->can_mo_ptr->MOAMR &
CAN_MO_MOAMR_MIDE_Msk) >> CAN_MO_MOAMR_MIDE_Pos;
783 if (can_mo->can_ide_mask == 1U)
784 {
785 can_mo->can_id_mask = (uint32_t)(can_mo->can_mo_ptr->MOAMR &
XMC_CAN_MO_MOAR_STDID_Msk) >> XMC_CAN_MO_MOAR_STDID_Pos;
786 }
787 else
788 {
789 can_mo->can_id_mask = (uint32_t)(can_mo->can_mo_ptr->MOAMR &
CAN_MO_MOAMR_AM_Msk);
790 }
791 }
792 else
793 {
794 can_mo->can_id_mode = (uint32_t)XMC_CAN_FRAME_TYPE_EXTENDED_29BITS;
795 can_mo->can_identifier = (can_mo->can_mo_ptr->MOAR & CAN_MO_MOAR_ID_Msk);
796 can_mo->can_id_mask = (uint32_t)(can_mo->can_mo_ptr->MOAMR &
CAN_MO_MOAMR_AM_Msk);
797 can_mo->can_ide_mask = (uint32_t)(can_mo->can_mo_ptr->MOAMR &
CAN_MO_MOAMR_MIDE_Msk) >> CAN_MO_MOAMR_MIDE_Pos;
798 }
799 can_mo->can_data_length = (uint8_t)((uint32_t)((can_mo->can_mo_ptr->MOFCR) &
CAN_MO_MOFCR_DLC_Msk) >> CAN_MO_MOFCR_DLC_Pos);
800
801 can_mo->can_data[0] = can_mo->can_mo_ptr->MODATAL;
802 can_mo->can_data[1] = can_mo->can_mo_ptr->MODATAH;
803
804 rx_pnd = (uint8_t)((uint32_t)((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_RXUPD_Msk) >> CAN_MO_MOSTAT_RXUPD_Pos);
805 new_data = (uint8_t)((uint32_t)((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_NEWDAT_Msk) >> CAN_MO_MOSTAT_NEWDAT_Pos);
806 }
807 while ((rx_pnd != 0U) && (new_data != 0U));
808
809 can_mo->can_mo_type = XMC_CAN_MO_TYPE_RECMSGOBJ;
810 error = XMC_CAN_STATUS_SUCCESS;
811 }
812 return error;
813 }
814
815 /* Function to enable node event */
816 void XMC_CAN_NODE_EnableEvent(XMC_CAN_NODE_t *const can_node, const
XMC_CAN_NODE_EVENT_t event)
817 {
818 if (event != XMC_CAN_NODE_EVENT_CFCIE)
819 {
820 can_node->NCR |= (uint32_t)event;
821 }
822 else
823 {
824 can_node->NFCR |= (uint32_t)event;
825 }
826 }
827
828 /* Function to disable node event */
829 void XMC_CAN_NODE_DisableEvent(XMC_CAN_NODE_t *const can_node, const
XMC_CAN_NODE_EVENT_t event)
830 {
831 if (event != XMC_CAN_NODE_EVENT_CFCIE)
832 {
833 can_node->NCR &= ~(uint32_t)event;
834 }
835 else
836 {
837 can_node->NFCR &= ~(uint32_t)event;
838 }
839 }
840 /* Function to transmit MO from the FIFO */
841 XMC_CAN_STATUS_t XMC_CAN_TXFIFO_Transmit(const XMC_CAN_MO_t *const can_mo)
842 {
843 XMC_CAN_STATUS_t error = XMC_CAN_STATUS_ERROR;
844 uint32_t mo_type = ((uint32_t)((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_MSGVAL_Msk) >> CAN_MO_MOSTAT_MSGVAL_Pos);
845 uint32_t mo_transmission_ongoing = (uint32_t)((can_mo->can_mo_ptr->MOSTAT) &
CAN_MO_MOSTAT_TXRQ_Msk) >> CAN_MO_MOSTAT_TXRQ_Pos;
846 uint32_t mo_cur = (uint32_t)(can_mo->can_mo_ptr-> MOFGPR & CAN_MO_MOFGPR_CUR_Msk)
>> CAN_MO_MOFGPR_CUR_Pos;
847 CAN_MO_TypeDef *mo = (CAN_MO_TypeDef *)(CAN_BASE + 0x1000UL + (mo_cur * 0x0020UL));
848 /* check if message is disabled */
849 if (mo_type == 0U)
850 {
851 error = XMC_CAN_STATUS_MO_DISABLED;
852 }
853 /* check if transmission is ongoing on message object */
854 else if (mo_transmission_ongoing == 1U)
855 {
856 error = XMC_CAN_STATUS_BUSY;
857 }
858 else
859 {
860 mo->MOCTR = CAN_MO_MOCTR_SETTXRQ_Msk | CAN_MO_MOCTR_SETTXEN0_Msk |
CAN_MO_MOCTR_SETTXEN1_Msk;
861 error = XMC_CAN_STATUS_SUCCESS;
862 }
863 return error;
864 }
865
866 /* Function to initialize the transmit FIFO MO base object */
867 void XMC_CAN_TXFIFO_ConfigMOBaseObject(const XMC_CAN_MO_t *const can_mo, const
XMC_CAN_FIFO_CONFIG_t can_fifo)
868 {
869 can_mo->can_mo_ptr->MOFCR = ((can_mo->can_mo_ptr->MOFCR ) & ~(uint32_t)(
CAN_MO_MOFCR_MMC_Msk)) |
870 (((uint32_t)0x2U << CAN_MO_MOFCR_MMC_Pos) & (uint32_t)
CAN_MO_MOFCR_MMC_Msk);
871 can_mo->can_mo_ptr->MOFGPR = ((can_mo->can_mo_ptr->MOFGPR ) & ~(uint32_t)(
CAN_MO_MOFGPR_BOT_Msk |
872 CAN_MO_MOFGPR_TOP_Msk |
873 CAN_MO_MOFGPR_CUR_Msk)) |
874 (((uint32_t)can_fifo.fifo_bottom <<
CAN_MO_MOFGPR_BOT_Pos) & (uint32_t)
CAN_MO_MOFGPR_BOT_Msk) |
875 (((uint32_t)can_fifo.fifo_base << CAN_MO_MOFGPR_CUR_Pos
) & (uint32_t) CAN_MO_MOFGPR_CUR_Msk) |
876 (((uint32_t)can_fifo.fifo_top << CAN_MO_MOFGPR_TOP_Pos)
& (uint32_t) CAN_MO_MOFGPR_TOP_Msk);
877 }
878 /* Function to Initialize the receive FIFO MO base object */
879 void XMC_CAN_RXFIFO_ConfigMOBaseObject(const XMC_CAN_MO_t *const can_mo, const
XMC_CAN_FIFO_CONFIG_t can_fifo)
880 {
881 can_mo->can_mo_ptr->MOFCR = ((can_mo->can_mo_ptr->MOFCR ) & ~(uint32_t)(
CAN_MO_MOFCR_MMC_Msk)) |
882 (((uint32_t)0x1U << CAN_MO_MOFCR_MMC_Pos) & (uint32_t)
CAN_MO_MOFCR_MMC_Msk);
883 can_mo->can_mo_ptr->MOFGPR = ((can_mo->can_mo_ptr->MOFGPR ) & ~( uint32_t)(
CAN_MO_MOFGPR_BOT_Msk |
884 CAN_MO_MOFGPR_TOP_Msk |
885 CAN_MO_MOFGPR_CUR_Msk)) |
886 (((uint32_t)can_fifo.fifo_bottom <<
CAN_MO_MOFGPR_BOT_Pos) & (uint32_t)
CAN_MO_MOFGPR_BOT_Msk) |
887 (((uint32_t)can_fifo.fifo_base << CAN_MO_MOFGPR_CUR_Pos
) & (uint32_t)CAN_MO_MOFGPR_CUR_Msk) |
888 (((uint32_t)can_fifo.fifo_top << CAN_MO_MOFGPR_TOP_Pos)
& (uint32_t)CAN_MO_MOFGPR_TOP_Msk);
889 }
890
891 /* Function to Initialize the FIFO MO slave object */
892 void XMC_CAN_TXFIFO_ConfigMOSlaveObject(const XMC_CAN_MO_t *const can_mo, const
XMC_CAN_FIFO_CONFIG_t can_fifo)
893 {
894 can_mo->can_mo_ptr->MOFCR = ((can_mo->can_mo_ptr->MOFCR ) & ~(uint32_t)(
CAN_MO_MOFCR_MMC_Msk)) |
895 (((uint32_t)0x3U << CAN_MO_MOFCR_MMC_Pos) & (uint32_t)
CAN_MO_MOFCR_MMC_Msk);
896 can_mo->can_mo_ptr->MOFGPR = ((can_mo->can_mo_ptr->MOFGPR ) & ~(uint32_t)(
CAN_MO_MOFGPR_CUR_Msk)) |
897 (((uint32_t)can_fifo.fifo_base << CAN_MO_MOFGPR_CUR_Pos
) & (uint32_t)CAN_MO_MOFGPR_CUR_Msk);
898
899 can_mo->can_mo_ptr->MOCTR = CAN_MO_MOCTR_SETTXEN0_Msk |
900 CAN_MO_MOCTR_RESTXEN1_Msk;
901 }
902
903 /* Function to Initialize the Gateway Source Object */
904 void XMC_CAN_GATEWAY_InitSourceObject(const XMC_CAN_MO_t *const can_mo, const
XMC_CAN_GATEWAY_CONFIG_t can_gateway)
905 {
906 can_mo->can_mo_ptr->MOFCR = (((uint32_t)0x4U << CAN_MO_MOFCR_MMC_Pos) & (uint32_t)
CAN_MO_MOFCR_MMC_Msk) |
907 ((((uint32_t)can_gateway.gateway_data_frame_send) <<
CAN_MO_MOFCR_GDFS_Pos) & (uint32_t)CAN_MO_MOFCR_GDFS_Msk
) |
908 ((((uint32_t)can_gateway.gateway_data_length_code_copy)
<< CAN_MO_MOFCR_DLCC_Pos) & (uint32_t)
CAN_MO_MOFCR_DLCC_Msk) |
909 ((((uint32_t)can_gateway.gateway_identifier_copy) <<
CAN_MO_MOFCR_IDC_Pos) & (uint32_t)CAN_MO_MOFCR_IDC_Msk)
|
910 ((((uint32_t)can_gateway.gateway_data_copy) <<
CAN_MO_MOFCR_DATC_Pos) & (uint32_t)CAN_MO_MOFCR_DATC_Msk
) ;
911 can_mo->can_mo_ptr->MOFGPR = (uint32_t)((((uint32_t)can_gateway.gateway_bottom <<
CAN_MO_MOFGPR_BOT_Pos) & (uint32_t)CAN_MO_MOFGPR_BOT_Msk) |
912 (((uint32_t)can_gateway.gateway_base <<
CAN_MO_MOFGPR_CUR_Pos) & (uint32_t)
CAN_MO_MOFGPR_CUR_Msk) |
913 (((uint32_t)can_gateway.gateway_top <<
CAN_MO_MOFGPR_TOP_Pos) & (uint32_t)
CAN_MO_MOFGPR_TOP_Msk));
914 }
915
916 #endif /* XMC_CAN_H */
917

You might also like