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