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