Download as pdf or txt
Download as pdf or txt
You are on page 1of 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 XMCSupport@infineon.com.
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