1 /*
2 * Copyright 2021-2024 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 /**
8 * @file CanEXCEL_Ip.c
9 *
10 * @addtogroup CanEXCEL
11 * @{
12 */
13
14 #include "CanEXCEL_Ip.h"
15 #include "CanEXCEL_Ip_HwAccess.h"
16 #include "SchM_Can_43_CANEXCEL.h"
17
18 #define CAN_43_CANEXCEL_START_SEC_VAR_INIT_UNSPECIFIED
19 #include "Can_43_CANEXCEL_MemMap.h"
20
21 static CANXL_SIC_Type * EXL_SIC_PTR[] = IP_CANXL_SIC_BASE_PTRS;
22 static CANXL_MRU_Type * EXL_MRU_PTR[] = IP_CANXL_MRU_BASE_PTRS;
23 static CANXL_GRP_CONTROL_Type * EXL_GRP_PTR[] = IP_CANXL_GRP_CONTROL_BASE_PTRS;
24 static CANXL_DSC_CONTROL_Type * EXL_DESC_CTR_PTR[] = IP_CANXL_DSC_CONTROL_BASE_PTRS;
25 static CANXL_MSG_DESCRIPTORS_Type * EXL_MSGD_PTR[] = IP_CANXL_MSG_DESCRIPTORS_BASE_PTRS;
26 static CANXL_RXFIFO_CONTROL_Type * EXL_RXF_CNT_PTR[] = IP_CANXL_RXFIFO_CONTROL_BASE_PTRS;
27 static CANXL_RXFIFO_Type * EXL_RXFIFO_PTR[] = IP_CANXL_RXFIFO_BASE_PTRS;
28 static CANXL_FILTER_BANK_Type * EXL_FILTER_PTR[] = IP_CANXL_FILTER_BANK_BASE_PTRS;
29 #if (CANEXCEL_IP_HAS_TS_ENABLE == STD_ON)
30 static CAN_TBS_Type * EXL_TBS_PTR[] = IP_CANXL_TBS_BASE_PTRS;
31 #endif
32
33 #define CAN_43_CANEXCEL_STOP_SEC_VAR_INIT_UNSPECIFIED
34 #include "Can_43_CANEXCEL_MemMap.h"
35
36 #define CAN_43_CANEXCEL_START_SEC_VAR_CLEARED_UNSPECIFIED
37 #include "Can_43_CANEXCEL_MemMap.h"
38
39 static CANEXCEL_StructType CANEXCEL;
40
41 /* Pointer to runtime state structure.*/
42 static Canexcel_Ip_StateType * Canexcel_Ip_apxState[CANXL_SIC_INSTANCE_COUNT];
43
44 #define CAN_43_CANEXCEL_STOP_SEC_VAR_CLEARED_UNSPECIFIED
45 #include "Can_43_CANEXCEL_MemMap.h"
46
47 #define CAN_43_CANEXCEL_START_SEC_CODE
48 #include "Can_43_CANEXCEL_MemMap.h"
49
50 static void Canexcel_Ip_MainFunction(uint8 instance, uint8 mb_idx);
51
52 static void ValidateFrameDLC(uint8 instance,uint32 mb_idx, Canexcel_Ip_StateType * state);
53
54 static void Canexcel_CompleteTxBuffers(uint8 instance,uint32 mb_idx, Canexcel_Ip_StateType * state);
55
56 static Canexcel_Ip_StatusType Canexcel_GetControllerMRU(uint8 instance, uint32 * pValue, uint8 command);
57
58 static void Canexcel_Ip_ConfInit(uint8 instance, const Canexcel_Ip_ConfigType * Config);
59
60 static void Canexcel_ProcessErrIRQ(uint8 instance,const Canexcel_Ip_StateType * state, uint32 bcanXlStatus, uint32 sysStatus);
61
62 /*!
63 * @brief Set the corresponding Message Descriptor interrupt
64 *
65 * @param base The CanXL MSG Grup Control base address
66 * @param mb_idx Index of the message descriptor
67 */
CanXL_SetMsgBuffIntCmd(CANXL_GRP_CONTROL_Type * base,uint32 msgBuffIdx)68 static inline void CanXL_SetMsgBuffIntCmd(CANXL_GRP_CONTROL_Type * base, uint32 msgBuffIdx)
69 {
70 uint8 ImaskCnt = (uint8)(msgBuffIdx/32U) ;
71 /* Enable the corresponding message buffer Interrupt */
72 uint32 temp = 1UL << (msgBuffIdx % 32U);
73 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_04();
74 base->MSGIMASK[ImaskCnt] |= temp;
75 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_04();
76 }
77 /*!
78 * @brief Disable the corresponding Message Descriptor interrupt
79 *
80 * @param base The CanXL MSG Grup Control base address
81 * @param mb_idx Index of the message descriptor
82 */
CanXL_ClearMsgBuffIntCmd(CANXL_GRP_CONTROL_Type * base,uint32 mb_idx)83 static inline void CanXL_ClearMsgBuffIntCmd(CANXL_GRP_CONTROL_Type * base, uint32 mb_idx)
84 {
85 uint8 ImaskCnt = (uint8)(mb_idx/32U) ;
86 /* Enable the corresponding message buffer Interrupt */
87 uint32 temp = 1UL << (mb_idx % 32U);
88 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_13();
89 base->MSGIMASK[ImaskCnt] &= (~temp);
90 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_13();
91 }
92
93 /*!
94 * @brief Enables/Disables Listen Only Mode
95 *
96 * @param base The CanXL SIC base address
97 * @param enable TRUE to enable; FALSE to disable
98 */
CanXL_SetListenOnlyMode(CANXL_SIC_Type * base,boolean enable)99 static inline void CanXL_SetListenOnlyMode(CANXL_SIC_Type * base, boolean enable)
100 {
101 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_05();
102 base->BCFG2 = (base->BCFG2 & ~CANXL_SIC_BCFG2_LOM_MASK) | CANXL_SIC_BCFG2_LOM(enable ? 1UL : 0UL);
103 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_05();
104 }
105
106 /*!
107 * @brief Enables/Disables Flexible Data rate (if supported).
108 *
109 * @param base The CanXL SIC base address
110 * @param enable TRUE to enable; FALSE to disable
111 */
CanXL_SetFDEnabled(CANXL_SIC_Type * base,boolean enableFD,boolean enableBRS)112 static inline void CanXL_SetFDEnabled(CANXL_SIC_Type * base,
113 boolean enableFD,
114 boolean enableBRS
115 )
116 {
117 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_00();
118 base->BCFG2 = (base->BCFG2 & ~CANXL_SIC_BCFG2_FDEN_MASK) | CANXL_SIC_BCFG2_FDEN(enableFD ? 1UL : 0UL);
119 /* Enable BitRate Switch support */
120 base->BCFG1 = (base->BCFG1 & ~CANXL_SIC_BCFG1_FDRSDIS_MASK) | CANXL_SIC_BCFG1_FDRSDIS(enableBRS ? 0UL : 1UL);
121 /* Disable Transmission Delay Compensation by default */
122 base->BTDCC &= ~(CANXL_SIC_BTDCC_FTDCEN_MASK | CANXL_SIC_BTDCC_FTDCOFF_MASK);
123 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_00();
124 }
125
126 /*!
127 * @brief Enables/Disables XL Frame Support
128 *
129 * @param base The CanXL SIC base address
130 * @param enable TRUE to enable; FALSE to disable
131 */
CanXL_SetXLEnable(CANXL_SIC_Type * base,boolean enableXL)132 static inline void CanXL_SetXLEnable(CANXL_SIC_Type * base,
133 boolean enableXL
134 )
135 {
136 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_14();
137 base->BCFG2 = (base->BCFG2 & ~CANXL_SIC_BCFG2_XLEN_MASK) | CANXL_SIC_BCFG2_XLEN(enableXL ? 1UL : 0UL);
138 /* Disable Transmission Delay Compensation by default */
139 base->BTDCC &= ~(CANXL_SIC_BTDCC_XTDCEN_MASK | CANXL_SIC_BTDCC_XTDCOFF_MASK);
140 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_14();
141 }
142
143 /*!
144 * @brief Enable/disable TDC and TDCM and TDC offset for FD phase
145 *
146 */
CanXL_SetTDCOffsetFD(CANXL_SIC_Type * base,boolean TDCEnable,boolean TDCMEnable,uint8 Offset)147 static inline void CanXL_SetTDCOffsetFD(CANXL_SIC_Type * base, boolean TDCEnable, boolean TDCMEnable, uint8 Offset)
148 {
149 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_10();
150 base->BTDCC &= ~(CANXL_SIC_BTDCC_FTDCEN_MASK | CANXL_SIC_BTDCC_FTDMDIS_MASK | CANXL_SIC_BTDCC_FTDCOFF_MASK);
151 base->BTDCC |= (CANXL_SIC_BTDCC_FTDCEN(TDCEnable ? 1UL : 0UL) | CANXL_SIC_BTDCC_FTDMDIS(TDCMEnable ? 1UL : 0UL) | CANXL_SIC_BTDCC_FTDCOFF(Offset));
152 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_10();
153 }
154
155 /*!
156 * @brief Enable/disable TDC and TDCM and TDC offset for XL phase
157 *
158 */
CanXL_SetTDCOffsetXL(CANXL_SIC_Type * base,boolean TDCEnable,boolean TDCMEnable,uint8 Offset)159 static inline void CanXL_SetTDCOffsetXL(CANXL_SIC_Type * base, boolean TDCEnable, boolean TDCMEnable, uint8 Offset)
160 {
161 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_11();
162 base->BTDCC &= ~(CANXL_SIC_BTDCC_XTDCEN_MASK | CANXL_SIC_BTDCC_XTDMDIS_MASK | CANXL_SIC_BTDCC_XTDCOFF_MASK);
163 base->BTDCC |= (CANXL_SIC_BTDCC_XTDCEN(TDCEnable ? 1UL : 0UL) | CANXL_SIC_BTDCC_XTDMDIS(TDCMEnable ? 1UL : 0UL) | CANXL_SIC_BTDCC_XTDCOFF(Offset));
164 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_11();
165 }
166 /*FUNCTION**********************************************************************
167 *
168 * Function Name : Canexcel_GetControllerMRU
169 * Description : This function will handle MRU operation, by read MRU requested value
170 * This is not a public API as it is called from other driver functions.
171 *
172 *END**************************************************************************/
Canexcel_GetControllerMRU(uint8 instance,uint32 * pValue,uint8 command)173 static Canexcel_Ip_StatusType Canexcel_GetControllerMRU(uint8 instance, uint32 * pValue, uint8 command)
174 {
175 CANXL_MRU_Type * base = CANEXCEL.EXL_MRU[instance];
176 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
177 Canexcel_Ip_StatusType status = CANEXCEL_STATUS_SUCCESS;
178 uint32 uS2Ticks = OsIf_MicrosToTicks(CANEXCEL_IP_TIMEOUT_DURATION, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
179 uint32 timeStart = 0U;
180 uint32 timeElapsed = 0U;
181 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
182 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
183 DevAssert(pValue != NULL_PTR);
184 #endif
185 CanXL_MruEnable(base);
186 /* Check the is available MRU Mailbox */
187 if ((base->CHXCONFIG[0u].CH_MBSTAT & CANXL_MRU_CH_MBSTAT_MBS0_MASK) != 0U)
188 {
189 status = CANEXCEL_STATUS_ERROR;
190 }
191 if (CANEXCEL_STATUS_SUCCESS == status)
192 {
193 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_08();
194 base->CHXCONFIG[0u].CH_CFG0 |= CANXL_MRU_CH_CFG0_MBE0_MASK | CANXL_MRU_CH_CFG0_MBE3_MASK | CANXL_MRU_CH_CFG0_IE_MASK;
195 base->CHXCONFIG[0u].CH_CFG1 |= CANXL_MRU_CH_CFG1_MBIC3_MASK;
196 base->CHXCONFIG[0u].CH_MBSTAT |= CANXL_MRU_CH_MBSTAT_MBS3_MASK;
197 state->u8MruMailboxAct &= (uint8)(~(1U<<CANXL_MRU_MBOX3));
198 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_08();
199 base->CH1_MB0 = command;
200 timeStart = OsIf_GetCounter(CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
201 while ((state->u8MruMailboxAct & (1U<<CANXL_MRU_MBOX3)) == 0U)
202 {
203 timeElapsed += OsIf_GetElapsed(&timeStart, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
204 if (timeElapsed >= uS2Ticks)
205 {
206 status = CANEXCEL_STATUS_TIMEOUT;
207 break;
208 }
209 }
210 if ((state->u8MruMailboxAct & (1U<<CANXL_MRU_MBOX3)) == (1U<<CANXL_MRU_MBOX3))
211 {
212 * pValue = base->CH1_MB3;
213 }
214 }
215 CanXL_MruDisable(base);
216 return status;
217 }
218 /*FUNCTION**********************************************************************
219 *
220 * Function Name : Canexcel_Ip_MainFunction
221 * Description : This function will process in polling Mode an Tx\Rx operation
222 * This is not a public API as it is called from other driver functions.
223 *
224 *END**************************************************************************/
Canexcel_Ip_MainFunction(uint8 instance,uint8 mb_idx)225 static void Canexcel_Ip_MainFunction(uint8 instance, uint8 mb_idx)
226 {
227 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
228 uint32 flag_reg;
229 uint8 total_mb = (uint8)((((CANEXCEL.EXL_SIC[instance]->SYSMCFG & CANXL_SIC_SYSMCFG_MAXTXMB_MASK) >> CANXL_SIC_SYSMCFG_MAXTXMB_SHIFT) + ((CANEXCEL.EXL_SIC[instance]->SYSMCFG & CANXL_SIC_SYSMCFG_MAXRXMB_MASK) >> CANXL_SIC_SYSMCFG_MAXRXMB_SHIFT)));
230 uint8 queue_depth = 0U;
231 uint8 CurrentHwIdx = 0U;
232
233 /* Check if instance initialized */
234 if ((NULL_PTR != state) && (mb_idx <= total_mb))
235 {
236 flag_reg = CanXL_GetMsgDescIntStatusFlag(CANEXCEL.EXL_GRP[instance], mb_idx);
237
238 if (0U != flag_reg)
239 {
240 queue_depth = CanXL_GetMDQueueDepth(CANEXCEL.EXL_GRP[instance], mb_idx) + 1U;
241 /* This check ensures that the HwPointer read is always sync with the IFLAG flag.
242 * It's necessary because if the IFLAG is set again(a new message received/transmited) just after it was cleared but before read CurrentHwIdx,
243 * the new message is consider to be processed(the hwpointer was plus by 1) while IFLAG is still set and the lastHwIdex is equal to CurrentHwIdx
244 * so in next time driver will calculate wrongly the no of pointers (consider a roll over)
245 * Note: the calculation of number of pointers based on hwpointer will not work in the case of KEEPLST is set because when UNDERUN occurred, the last buffer will be overwite,
246 * but the hwpointer will not change(Hw implementation).
247 */
248 uint8 timeout = 0U;
249 do
250 {
251 CanXL_ClearMsgDescIntStatusFlag(CANEXCEL.EXL_GRP[instance], mb_idx);
252 CurrentHwIdx = (uint8)((CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[mb_idx].DCSTA & CANXL_DSC_CONTROL_DCSTA_HWPOINTER_MASK) >> CANXL_DSC_CONTROL_DCSTA_HWPOINTER_SHIFT);
253 timeout++;
254 } while ((0U != CanXL_GetMsgDescIntStatusFlag(CANEXCEL.EXL_GRP[instance], mb_idx)) && (timeout < queue_depth));
255
256 if (CurrentHwIdx > (state->msgDesc[mb_idx].lastHwIdex))
257 {
258 state->msgDesc[mb_idx].noPointers = CurrentHwIdx - (state->msgDesc[mb_idx].lastHwIdex);
259 }
260 else
261 {
262 state->msgDesc[mb_idx].noPointers = queue_depth - (state->msgDesc[mb_idx].lastHwIdex) + CurrentHwIdx;
263 }
264 /* First descriptors are always allocated for Transmission */
265 if (mb_idx <= CANEXCEL.EXL_GRP[instance]->DSCCTRL)
266 {
267 Canexcel_CompleteTxBuffers(instance, mb_idx, state);
268 /* Process Tx MDESC */
269 if (NULL_PTR != state->callback)
270 {
271 state->callback(instance, CANEXCEL_EVENT_TX_COMPLETE, mb_idx, state);
272 }
273 }
274 else
275 {
276 ValidateFrameDLC(instance, mb_idx, state);
277 /* Process Rx MDESC */
278 if (NULL_PTR != state->callback)
279 {
280 state->callback(instance, CANEXCEL_EVENT_RX_COMPLETE, mb_idx, state);
281 }
282 }
283 state->msgDesc[mb_idx].lastHwIdex = CurrentHwIdx;
284 }
285 }
286 if ((NULL_PTR != state) && (mb_idx == CANEXCEL_IP_MB_RXFIFO))
287 {
288 if (1U == CANEXCEL.EXL_RXF_CNT[instance]->RXFSYSACT)
289 {
290 if ((CANEXCEL.EXL_RXF_CNT[instance]->RXFS & CANXL_RXFIFO_CONTROL_RXFS_RXFF_MASK) != 0U)
291 {
292 CANEXCEL.EXL_RXF_CNT[instance]->RXFS |= CANXL_RXFIFO_CONTROL_RXFS_RXFF_MASK;
293 state->rxFifo.noPointers = (uint8)(((CANEXCEL.EXL_RXF_CNT[instance]->RXFCSTA & CANXL_RXFIFO_CONTROL_RXFCSTA_HWPOINTER_MASK) >> CANXL_RXFIFO_CONTROL_RXFCSTA_HWPOINTER_SHIFT));
294
295 /* Process RxFifo for Reception */
296 if (NULL_PTR != state->callback)
297 {
298 state->callback(instance, CANEXCEL_EVENT_RXFIFO_COMPLETE, mb_idx, state);
299 }
300 }
301 }
302 }
303 }
304 /*FUNCTION**********************************************************************
305 *
306 * Function Name : CanXL_InitBaudrate
307 * Description : Init baudrate for given controller.
308 * This is not a public API as it is called from other driver functions.
309 *
310 *END**************************************************************************/
CanXL_InitBaudrate(CANXL_SIC_Type * pBase,const Canexcel_Ip_ConfigType * Canxl_Ip_pData)311 static void CanXL_InitBaudrate(CANXL_SIC_Type * pBase, const Canexcel_Ip_ConfigType * Canxl_Ip_pData)
312 {
313 CanXL_SetBaudRate(pBase, &Canxl_Ip_pData->bitrate);
314 if (Canxl_Ip_pData->fd_enable)
315 {
316 CanXL_SetFDBaudRate(pBase, &Canxl_Ip_pData->Fd_bitrate);
317 }
318 if (Canxl_Ip_pData->xl_enable)
319 {
320 CanXL_SetXLBaudRate(pBase, &Canxl_Ip_pData->Xl_bitrate);
321 }
322 }
323
324 /*FUNCTION**********************************************************************
325 *
326 * Function Name : Canexcel_Ip_ConfInit
327 * Description : Partially configure CANEXCEL instance
328 * This is not a public API as it is called from other driver functions.
329 *
330 *END**************************************************************************/
Canexcel_Ip_ConfInit(uint8 instance,const Canexcel_Ip_ConfigType * Config)331 static void Canexcel_Ip_ConfInit(uint8 instance, const Canexcel_Ip_ConfigType * Config)
332 {
333 CanXL_SetFDEnabled(CANEXCEL.EXL_SIC[instance], Config->fd_enable, Config->bitRateSwitch);
334 CanXL_SetXLEnable(CANEXCEL.EXL_SIC[instance], Config->xl_enable);
335 CanXL_InitBaudrate(CANEXCEL.EXL_SIC[instance], Config);
336 CanXL_SetOperationMode(CANEXCEL.EXL_SIC[instance], Config->CanxlMode);
337 /** To be develop for Queue Operation Config */
338 CanXL_SetMDQueueConfigs(CANEXCEL.EXL_GRP[instance], Config->QueueMDConfig);
339 }
340
341 /*FUNCTION**********************************************************************
342 *
343 * Function Name : Canexcel_InitRxFIFO
344 * Description : Configure Rx FIFO
345 * This is not a public API as it is called from other driver functions.
346 *
347 *END**************************************************************************/
Canexcel_InitRxFIFO(uint8 instance,const Canexcel_Ip_ConfigType * Config)348 static void Canexcel_InitRxFIFO(uint8 instance, const Canexcel_Ip_ConfigType * Config)
349 {
350 uint16 dlcValue = 0u;
351
352 CANEXCEL.EXL_RXF_CNT[instance]->RXFC = CANXL_RXFIFO_CONTROL_RXFC_RXFD((uint32)Config->pRxFifoConfig.Rx_Fifo_Depth-1U)|CANXL_RXFIFO_CONTROL_RXFC_RXFWTM((uint32)Config->pRxFifoConfig.Rx_Fifo_Watermark - 1U);
353
354 if (CANEXCEL_XL_FRAME == Config->pRxFifoConfig.frameType)
355 {
356 Canexcel_Ip_apxState[instance]->rxFifo.isXLFrame = TRUE;
357 dlcValue = Config->pRxFifoConfig.Rx_Fifo_Msg_Size - 1u;
358 const Canexcel_RxXlMsg * RxFifoMsgBuff= (Canexcel_RxXlMsg *)Config->pRxFifoConfig.MsgBuffersPtr;
359 for (uint8 idx = 0; idx < Config->pRxFifoConfig.Rx_Fifo_Depth; idx++)
360 {
361 CANEXCEL.EXL_RXFIFO[instance]->RXFMBP[idx] = (uint32)&RxFifoMsgBuff[idx];
362 }
363 }
364 else
365 {
366 Canexcel_Ip_apxState[instance]->rxFifo.isXLFrame = FALSE;
367 dlcValue = (uint16)CAN_ComputeDLCValue((uint8)(Config->pRxFifoConfig.Rx_Fifo_Msg_Size));
368 const Canexcel_RxFdMsg * RxFifoMsgBuff= (Canexcel_RxFdMsg *)Config->pRxFifoConfig.MsgBuffersPtr;
369 for (uint8 idx = 0; idx < Config->pRxFifoConfig.Rx_Fifo_Depth; idx++)
370 {
371 CANEXCEL.EXL_RXFIFO[instance]->RXFMBP[idx] = (uint32)&RxFifoMsgBuff[idx];
372 }
373 }
374 uint8 aux = (Config->pRxFifoConfig.Rx_Fifo_KeepLast == FALSE) ? 1U : 0U;
375 CANEXCEL.EXL_RXFIFO[instance]->RXFFCTR = (CANXL_RXFIFO_RXFFCTR_MBSIZE((uint32)dlcValue) | CANXL_RXFIFO_RXFFCTR_KEEPLST((uint32)aux));
376 /* Activate RxFifo */
377 CANEXCEL.EXL_RXF_CNT[instance]->RXFSYSACT = CANXL_RXFIFO_CONTROL_RXFSYSACT_ACT_MASK;
378 Canexcel_Ip_apxState[instance]->rxFifo.isPolling = Config->pRxFifoConfig.isPolling;
379 }
380
381 /*FUNCTION**********************************************************************
382 *
383 * Function Name : Canexcel_Ip_GetStartMode
384 * Description : Check if the Canexcel instance is STARTED.
385 *
386 *END**************************************************************************/
387 /* implements Canexcel_Ip_GetStartMode_Activity */
Canexcel_Ip_GetStartMode(uint8 instance)388 boolean Canexcel_Ip_GetStartMode(uint8 instance)
389 {
390 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
391 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
392 #endif
393 const CANXL_SIC_Type * base = CANEXCEL.EXL_SIC[instance];
394 return ((0U == (base->SYSS & CANXL_SIC_SYSS_NTRDY_MASK))? TRUE : FALSE);
395 }
396
397 #if (CANEXCEL_IP_HAS_TS_ENABLE == STD_ON)
398 /*FUNCTION**********************************************************************
399 *
400 * Function Name : Canexcel_Ip_ConfigTimeStamp
401 * Description : Timestamp configuration
402 *
403 *END**************************************************************************/
404 /* implements Canexcel_Ip_ConfigTimeStamp_Activity */
Canexcel_Ip_ConfigTimeStamp(uint8 instance,const Canexcel_Ip_TimeStampConf_Type * time_stamp)405 Canexcel_Ip_StatusType Canexcel_Ip_ConfigTimeStamp(uint8 instance, const Canexcel_Ip_TimeStampConf_Type * time_stamp)
406 {
407 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_ERROR;
408 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
409 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
410 #endif
411
412 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[instance]))
413 {
414 CanXL_SetTimeStampCaputre(CANEXCEL.EXL_SIC[instance], time_stamp->capture);
415 /* If ts64bit True will enable the timestamp as 64 bits if false will set to 32 bits */
416 CANEXCEL.EXL_SIC[instance]->BCFG2 |= (TRUE == time_stamp->ts64bit) ? CANXL_SIC_BCFG2_TSS(1U) : CANXL_SIC_BCFG2_TSS(0U);
417 returnResult = CANEXCEL_STATUS_SUCCESS;
418 CanXL_SetTimeBaseSource(CANEXCEL.EXL_TBS[instance], time_stamp->src);
419 }
420 return returnResult;
421 }
422 #endif
423
424 /*FUNCTION**********************************************************************
425 *
426 * Function Name : Canexcel_Ip_SetStopMode
427 * Description : Set the Canexcel instance in STOP mode.
428 *
429 *END**************************************************************************/
430 /* implements Canexcel_Ip_SetStopMode_Activity */
Canexcel_Ip_SetStopMode(uint8 instance)431 Canexcel_Ip_StatusType Canexcel_Ip_SetStopMode(uint8 instance)
432 {
433 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
434 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
435 #endif
436 CANXL_SIC_Type * base = CANEXCEL.EXL_SIC[instance];
437 Canexcel_Ip_StatusType status;
438 status = CanXL_EnterFreezeMode(base);
439 return status;
440 }
441
442 /*FUNCTION**********************************************************************
443 *
444 * Function Name : Canexcel_ResetController
445 * Description : Reset controller and put it into freeze mode
446 * This is not a public API as it is called from other driver functions.
447 *
448 *END**************************************************************************/
Canexcel_ResetController(uint8 instance)449 static Canexcel_Ip_StatusType Canexcel_ResetController(uint8 instance)
450 {
451 uint32 timeStart = 0U;
452 uint32 timeElapsed = 0U;
453 uint32 uS2Ticks = OsIf_MicrosToTicks(CANEXCEL_IP_TIMEOUT_DURATION, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
454 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_SUCCESS;
455
456 timeStart = OsIf_GetCounter(CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
457 /* Wait Hardware to became available after clock start */
458 while ((CANEXCEL.EXL_SIC[instance]->SYSS & CANXL_SIC_SYSS_FRZACKF_MASK) == 0U)
459 {
460 timeElapsed += OsIf_GetElapsed(&timeStart, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
461 if (timeElapsed >= uS2Ticks)
462 {
463 returnResult = CANEXCEL_STATUS_TIMEOUT;
464 break;
465 }
466 }
467
468 if (CANEXCEL_STATUS_SUCCESS == returnResult)
469 {
470 returnResult = CanXL_SoftReset(CANEXCEL.EXL_SIC[instance]);
471 }
472
473 if (CANEXCEL_STATUS_SUCCESS == returnResult)
474 {
475 returnResult = CanXL_EnterFreezeMode(CANEXCEL.EXL_SIC[instance]);
476 }
477
478 return returnResult;
479 }
480
481 /*FUNCTION**********************************************************************
482 *
483 * Function Name : Canexcel_Ip_Init
484 * Description : Initialize the driver with the configuration
485 *
486 *END**************************************************************************/
487 /* implements Canexcel_Ip_Init_Activity */
Canexcel_Ip_Init(uint8 instance,const Canexcel_Ip_ConfigType * Config,Canexcel_Ip_StateType * pState)488 Canexcel_Ip_StatusType Canexcel_Ip_Init(uint8 instance, const Canexcel_Ip_ConfigType * Config, Canexcel_Ip_StateType * pState)
489 {
490
491 CANEXCEL.EXL_SIC = EXL_SIC_PTR;
492 CANEXCEL.EXL_MRU = EXL_MRU_PTR;
493 CANEXCEL.EXL_GRP = EXL_GRP_PTR;
494 CANEXCEL.EXL_DESC_CTR = EXL_DESC_CTR_PTR;
495 CANEXCEL.EXL_MSGD = EXL_MSGD_PTR;
496 CANEXCEL.EXL_RXFIFO = EXL_RXFIFO_PTR;
497 CANEXCEL.EXL_RXF_CNT = EXL_RXF_CNT_PTR;
498 CANEXCEL.EXL_FILTER = EXL_FILTER_PTR;
499 #if (CANEXCEL_IP_HAS_TS_ENABLE == STD_ON)
500 CANEXCEL.EXL_TBS = EXL_TBS_PTR;
501 #endif
502 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_SUCCESS;
503 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
504 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
505 DevAssert(Config != NULL_PTR);
506 DevAssert(pState != NULL_PTR);
507 #endif
508 uint8 u8MdCnt = 0U;
509 uint8 u8MbCnt = 0U;
510
511 /* Reset and put controller to freeze mode before setting registers */
512 returnResult = Canexcel_ResetController(instance);
513
514 if (CANEXCEL_STATUS_SUCCESS == returnResult)
515 {
516 /* CANEXCEL Data Memory Write Access Enable for Host */
517 CANEXCEL.EXL_SIC[instance]->SYSMCFG &= ~CANXL_SIC_SYSMCFG_DRWRDIS_MASK;
518 /* Clear Memory ram and initialize it */
519 CanXL_ClearRAM(&CANEXCEL, instance);
520 CANEXCEL.EXL_GRP[instance]->DSCCTRL = CANXL_GRP_CONTROL_DSCCTRL_TXDSC((uint32)Config->tx_mbdesc-1u);
521 CANEXCEL.EXL_SIC[instance]->SYSMCFG |= (CANXL_SIC_SYSMCFG_MAXTXMB(Config->tx_mbdesc) | CANXL_SIC_SYSMCFG_MAXRXMB(Config->rx_mbdesc));
522 Canexcel_Ip_ConfInit(instance, Config);
523
524 returnResult = CanXL_ConfigCtrlOptions(CANEXCEL.EXL_SIC[instance], Config->ctrlOptions);
525 if (CANEXCEL_STATUS_SUCCESS == returnResult)
526 {
527 Canexcel_Ip_apxState[instance] = pState;
528 for (u8MdCnt = 0U; u8MdCnt<Config->tx_mbdesc; u8MdCnt++)
529 {
530 /* Better to be moved at init because requires Freeze mode */
531 CANEXCEL.EXL_MSGD[instance]->MSGDSC[u8MdCnt].LSTPNT.TXLSTPTR = (uint32)&pState->msgDesc[u8MdCnt].list;
532 }
533 for (; u8MdCnt < (Config->rx_mbdesc + Config->tx_mbdesc); u8MdCnt++)
534 {
535 /* Better to be moved at init because requires Freeze mode */
536 CANEXCEL.EXL_MSGD[instance]->MSGDSC[u8MdCnt].LSTPNT.RXLSTPTR = (uint32)&pState->msgDesc[u8MdCnt].list;
537 }
538
539 if (TRUE == Config->is_rx_fifo_needed)
540 {
541 Canexcel_InitRxFIFO(instance, Config);
542 }
543 CanXL_ResetImaskBuff(CANEXCEL.EXL_GRP[instance]);
544 /* Clear Callbacks in case of autovariables garbage */
545 Canexcel_Ip_apxState[instance]->u8MruMailboxAct = 0U;
546 Canexcel_Ip_apxState[instance]->callback = Config->Callback;
547 Canexcel_Ip_apxState[instance]->callbackParam = NULL_PTR;
548 Canexcel_Ip_apxState[instance]->error_callback = Config->ErrorCallback;
549 Canexcel_Ip_apxState[instance]->errorCallbackParam = NULL_PTR;
550 Canexcel_Ip_apxState[instance]->isIntActive = FALSE;
551 /* Clear all pending flags */
552 for (u8MdCnt = 0U; u8MdCnt < CANXL_DSC_CONTROL_DSCMBCTRLAR_COUNT; u8MdCnt++)
553 {
554 Canexcel_Ip_apxState[instance]->msgDesc[u8MdCnt].lastHwIdex = 0U;
555 Canexcel_Ip_apxState[instance]->msgDesc[u8MdCnt].noPointers = 0U;
556 for (u8MbCnt = 0U; u8MbCnt < 16U; u8MbCnt++)
557 {
558 Canexcel_Ip_apxState[instance]->msgDesc[u8MdCnt].isPending[u8MbCnt] = FALSE;
559 }
560 }
561 #if (CANEXCEL_IP_HAS_TS_ENABLE == STD_ON)
562 returnResult = Canexcel_Ip_ConfigTimeStamp(instance, &Config->TimestampConfig);
563 #endif
564 }
565 }
566 return returnResult;
567 }
568
569 /*FUNCTION**********************************************************************
570 *
571 * Function Name : Canexcel_Ip_SetRxIndividualMask
572 * Description : Set Individual Rx Mask ID for Message Descriptor, and frame type.
573 *
574 *END**************************************************************************/
575 /* implements Canexcel_Ip_SetRxIndividualMask_Activity */
Canexcel_Ip_SetRxIndividualMask(uint8 instance,uint8 descNo,Canexcel_Ip_FrameType frameType,uint32 mask)576 void Canexcel_Ip_SetRxIndividualMask(uint8 instance, uint8 descNo, Canexcel_Ip_FrameType frameType, uint32 mask)
577 {
578 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
579 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
580 DevAssert(descNo < CANXL_DSC_CONTROL_DSCMBCTRLAR_COUNT);
581 #endif
582 if (CANEXCEL_XL_FRAME == frameType)
583 {
584 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CFG1.MDFLT1XL = mask;
585 }
586 else
587 {
588 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CFG1.MDFLT1FD = mask;
589 }
590 }
591
592 /*FUNCTION**********************************************************************
593 *
594 * Function Name : Canexcel_Ip_ConfigRx
595 * Description : Set Individual Rx ID for Message Descriptor, and config the frame parameters from DataInfoType.
596 *
597 *END**************************************************************************/
598 /* implements Canexcel_Ip_ConfigRx_Activity */
Canexcel_Ip_ConfigRx(uint8 instance,uint8 descNo,uint32 msgId,const Canexcel_Ip_DataInfoType * info)599 Canexcel_Ip_StatusType Canexcel_Ip_ConfigRx(uint8 instance, uint8 descNo, uint32 msgId,const Canexcel_Ip_DataInfoType * info)
600 {
601 uint16 dlcValue = 0U;
602 uint32 timeStart = 0U;
603 uint32 uS2Ticks = 0U;
604 uint32 timeElapsed = 0U;
605 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
606 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_SUCCESS;
607
608 /* TODO: consider to remove this check */
609 if (CanXL_GetDesciptorState(CANEXCEL.EXL_DESC_CTR[instance], descNo) >= CANEXCEL_DESC_STATE_FULL)
610 {
611 returnResult = CANEXCEL_STATUS_BUSY;
612 }
613
614 if (CANEXCEL_STATUS_SUCCESS == returnResult)
615 {
616 /* Lock the Descriptor before re-configure it */
617 #if (CANEXCEL_IP_HAS_SYSLOCK01 == STD_ON)
618 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 1U;
619 #else
620 (void)CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK;
621 #endif
622
623 /* Wait until syslock is retrieved */
624 uS2Ticks = OsIf_MicrosToTicks(CANEXCEL_IP_TIMEOUT_DURATION, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
625 timeStart = OsIf_GetCounter(CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
626 while (CANEXCEL_DESCNTSTATUS_LOCKED_SYS != CanXL_GetDescControlStatus(CANEXCEL.EXL_DESC_CTR[instance], descNo))
627 {
628 timeElapsed += OsIf_GetElapsed(&timeStart, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
629 if (timeElapsed >= uS2Ticks)
630 {
631 returnResult = CANEXCEL_STATUS_TIMEOUT;
632 break;
633 }
634 #if (CANEXCEL_IP_HAS_SYSLOCK01 == STD_ON)
635 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 1U;
636 #else
637 (void)CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK;
638 #endif
639 }
640 }
641
642 if (CANEXCEL_STATUS_SUCCESS == returnResult)
643 {
644 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CTRL.RXCTRL = 0U;
645 if (info->frame == CANEXCEL_XL_FRAME)
646 {
647 state->msgDesc[descNo].isXLFrame = TRUE;
648 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CTRL.RXCTRL = CANXL_MSG_DESCRIPTORS_RXCTRL_RXXLFRM_MASK;
649 dlcValue = info->dataLength - 1U;
650 if (info->idType == CANEXCEL_MSG_ID_EXT)
651 {
652 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
653 /* CanXL frame type supports only STD ID frame types */
654 DevAssert(FALSE);
655 #endif
656 }
657 else
658 {
659 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CFG2.MDFLT2XL = (CANXL_MSG_DESCRIPTORS_MDFLT2XL_IDSTDa_H(msgId) |
660 ((info->SEC) ? CANXL_MSG_DESCRIPTORS_MDFLT2XL_SEC(1U) : CANXL_MSG_DESCRIPTORS_MDFLT2XL_SEC(0U)) |
661 CANXL_MSG_DESCRIPTORS_MDFLT2XL_RJCT_SDU(info->SDT) |
662 CANXL_MSG_DESCRIPTORS_MDFLT2XL_RJCT_VCAN(info->VCID));
663 }
664 }
665 else if (CANEXCEL_FD_FRAME == info->frame)
666 {
667 state->msgDesc[descNo].isXLFrame = FALSE;
668 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CTRL.RXCTRL = CANXL_MSG_DESCRIPTORS_RXCTRL_RXFDFRM_MASK;
669 dlcValue = (uint16)CAN_ComputeDLCValue((uint8)(info->dataLength));
670 if (CANEXCEL_MSG_ID_EXT == info->idType)
671 {
672 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CFG2.MDFLT2FD = CANXL_MSG_DESCRIPTORS_MDFLT2FD_IDE_MASK | msgId;
673 }
674 else
675 {
676 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CFG2.MDFLT2FD = CANXL_MSG_DESCRIPTORS_MDFLT2FD_IDSTDa_H(msgId);
677 }
678 }
679 else
680 {
681 /* expected Classic Frame Type */
682 state->msgDesc[descNo].isXLFrame = FALSE;
683 dlcValue = (uint16)CAN_ComputeDLCValue((uint8)(info->dataLength));
684 if (CANEXCEL_MSG_ID_EXT == info->idType)
685 {
686 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CFG2.MDFLT2FD = CANXL_MSG_DESCRIPTORS_MDFLT2FD_IDE_MASK | msgId;
687 }
688 else
689 {
690 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CFG2.MDFLT2FD = CANXL_MSG_DESCRIPTORS_MDFLT2FD_IDSTDa_H(msgId);
691 }
692 }
693 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_03();
694 CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CTRL.RXCTRL |= CANXL_MSG_DESCRIPTORS_RXCTRL_MBSIZE(dlcValue);
695 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_03();
696
697 /* Activate the Descriptor */
698 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCACT = 1U;
699
700 /* Release System lock in order to read to receive */
701 #if (CANEXCEL_IP_HAS_SYSLOCK01 == STD_ON)
702 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 0U;
703 #else
704 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 1U;
705 #endif
706 }
707 return returnResult;
708 }
709
710 /*FUNCTION**********************************************************************
711 *
712 * Function Name : Canexcel_Ip_RxDescriptor
713 * Description : Push the new memory location for the Rx Message Buffer on the desired Descriptor.
714 *
715 *END**************************************************************************/
716 /* implements Canexcel_Ip_RxDescriptor_Activity */
Canexcel_Ip_RxDescriptor(uint8 instance,uint8 descNo,uint32 rxPtrList)717 Canexcel_Ip_StatusType Canexcel_Ip_RxDescriptor(uint8 instance, uint8 descNo, uint32 rxPtrList)
718 {
719 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
720 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_SUCCESS;
721 uint8 Active = 0U;
722 boolean bSysLock = FALSE;
723
724 #if (CANEXCEL_IP_FEATURE_HAS_MSGDESC_RXCTRL_MODE == (STD_ON))
725 /* Check if previous was called the ConfigRx API, the MODE bit was cleared and Descriptor was ACTIVE and release system lock */
726 if (CANXL_MSG_DESCRIPTORS_RXCTRL_MODE_MASK == (CANEXCEL.EXL_MSGD[instance]->MSGDSC[descNo].CTRL.RXCTRL & CANXL_MSG_DESCRIPTORS_RXCTRL_MODE_MASK))
727 {
728 returnResult = CANEXCEL_STATUS_ERROR;
729 }
730 else
731 #endif
732 {
733 Active = (uint8)(CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCACT & CANXL_DSC_CONTROL_DCACT_ACT_MASK);
734 bSysLock = (CANEXCEL_DESCNTSTATUS_LOCKED_SYS == CanXL_GetDescControlStatus(CANEXCEL.EXL_DESC_CTR[instance], descNo)) ? TRUE : FALSE;
735
736 /* Push without syslock and the descriptor must be activated first, require to call ConfigRx first */
737 if ((1U == Active) && (FALSE == bSysLock))
738 {
739 /* Check if the descriptor is empty, notfull or inactive */
740 if (CanXL_GetDesciptorState(CANEXCEL.EXL_DESC_CTR[instance], descNo) <= CANEXCEL_DESC_STATE_NOTFULL)
741 {
742 uint8 noOfPtrList = (uint8)((CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSTA & CANXL_DSC_CONTROL_DCSTA_SYSPOINTER_MASK) >> CANXL_DSC_CONTROL_DCSTA_SYSPOINTER_SHIFT);
743
744 if (noOfPtrList >= (CanXL_GetMDQueueDepth(CANEXCEL.EXL_GRP[instance], descNo)+1U))
745 {
746 /* Roll Over */
747 noOfPtrList = 0U;
748 }
749 /* The buffer must be processed in MainFunction/ISR before using it */
750 if (FALSE == state->msgDesc[descNo].isPending[noOfPtrList])
751 {
752 state->msgDesc[descNo].isPending[noOfPtrList] = TRUE;
753 state->msgDesc[descNo].list[noOfPtrList] = rxPtrList;
754 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSPUSH = 0U;
755 }
756 else
757 {
758 returnResult = CANEXCEL_STATUS_ERROR;
759 }
760 }
761 else
762 {
763 returnResult = CANEXCEL_STATUS_ERROR;
764 }
765 }
766 else
767 {
768 returnResult = CANEXCEL_STATUS_ERROR;
769 }
770 }
771 return returnResult;
772 }
773 /*FUNCTION**********************************************************************
774 *
775 * Function Name : Canexcel_Ip_ReceiveFD
776 * Description : Receive a Classic or FD CAN Format Message
777 *
778 *END**************************************************************************/
779 /* implements Canexcel_Ip_ReceiveFD_Activity */
Canexcel_Ip_ReceiveFD(uint8 instance,uint8 descNo,const Canexcel_RxFdMsg * RxMsg,boolean isPolling)780 Canexcel_Ip_StatusType Canexcel_Ip_ReceiveFD(uint8 instance, uint8 descNo, const Canexcel_RxFdMsg * RxMsg, boolean isPolling)
781 {
782 Canexcel_Ip_StatusType returnResult;
783 returnResult = Canexcel_Ip_RxDescriptor(instance, descNo, (uint32)&RxMsg->Header.Id);
784 if ((CANEXCEL_STATUS_SUCCESS == returnResult) && (FALSE == isPolling))
785 {
786 CanXL_SetMsgBuffIntCmd(CANEXCEL.EXL_GRP[instance], descNo);
787 }
788 return returnResult;
789 }
790 /*FUNCTION**********************************************************************
791 *
792 * Function Name : Canexcel_Ip_ReceiveXL
793 * Description : Receive a CAN XL Format Message
794 *
795 *END**************************************************************************/
796 /* implements Canexcel_Ip_ReceiveXL_Activity */
Canexcel_Ip_ReceiveXL(uint8 instance,uint8 descNo,const Canexcel_RxXlMsg * RxMsg,boolean isPolling)797 Canexcel_Ip_StatusType Canexcel_Ip_ReceiveXL(uint8 instance, uint8 descNo, const Canexcel_RxXlMsg * RxMsg, boolean isPolling)
798 {
799 Canexcel_Ip_StatusType returnResult;
800 returnResult = Canexcel_Ip_RxDescriptor(instance, descNo, (uint32)&RxMsg->Header.Id);
801 if ((CANEXCEL_STATUS_SUCCESS == returnResult) && (FALSE == isPolling))
802 {
803 CanXL_SetMsgBuffIntCmd(CANEXCEL.EXL_GRP[instance], descNo);
804 }
805 return returnResult;
806 }
807
808 /*FUNCTION**********************************************************************
809 *
810 * Function Name : Canexcel_Ip_TxDescriptor
811 * Description : Push the new memory location for the Tx Message Buffer on the desired Descriptor.
812 *
813 *END**************************************************************************/
814 /* implements Canexcel_Ip_TxDescriptor_Activity */
Canexcel_Ip_TxDescriptor(uint8 instance,uint8 descNo,uint32 txPtrList)815 Canexcel_Ip_StatusType Canexcel_Ip_TxDescriptor(uint8 instance, uint8 descNo, uint32 txPtrList)
816 {
817 uint32 timeStart = 0U;
818 uint32 timeElapsed = 0U;
819 uint32 uS2Ticks = OsIf_MicrosToTicks(CANEXCEL_IP_TIMEOUT_DURATION, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
820 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
821 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_SUCCESS;
822
823 /* Ensure that the buffer given was already configured by Canexcel_Ip_ConfigXlTx/Canexcel_Ip_ConfigFdTx before start the transmission */
824 if (0U == ((((Canexcel_TxMsgHeaderType *)txPtrList)->word2) & CANXL_TX_HEADER_MODE_MASK))
825 {
826 returnResult = CANEXCEL_STATUS_ERROR;
827 }
828 else
829 {
830 /* Set system lock Status */
831 #if (CANEXCEL_IP_HAS_SYSLOCK01 == STD_ON)
832 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 1U;
833 #else
834 (void)CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK;
835 #endif
836 timeStart = OsIf_GetCounter(CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
837 while (CANEXCEL_DESCNTSTATUS_LOCKED_HW == CanXL_GetDescControlStatus(CANEXCEL.EXL_DESC_CTR[instance], descNo))
838 {
839 timeElapsed += OsIf_GetElapsed(&timeStart, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
840 if (timeElapsed >= uS2Ticks)
841 {
842 returnResult = CANEXCEL_STATUS_TIMEOUT;
843 break;
844 }
845 }
846 if (CANEXCEL_STATUS_SUCCESS == returnResult)
847 {
848 /* Check if the descriptor is empty, notfull or inactive */
849 if (CanXL_GetDesciptorState(CANEXCEL.EXL_DESC_CTR[instance], descNo) <= CANEXCEL_DESC_STATE_NOTFULL)
850 {
851 uint8 noOfPtrList = (uint8)((CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSTA & CANXL_DSC_CONTROL_DCSTA_SYSPOINTER_MASK) >> CANXL_DSC_CONTROL_DCSTA_SYSPOINTER_SHIFT);
852
853 if (noOfPtrList >= (CanXL_GetMDQueueDepth(CANEXCEL.EXL_GRP[instance], descNo)+1U))
854 {
855 /* Roll Over */
856 noOfPtrList = 0U;
857 }
858 /* The buffer must be processed in MainFunction/ISR before using it */
859 if (FALSE == state->msgDesc[descNo].isPending[noOfPtrList])
860 {
861 state->msgDesc[descNo].isPending[noOfPtrList] = TRUE;
862 state->msgDesc[descNo].list[noOfPtrList] = txPtrList;
863 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCACT = 1U;
864 #if (CANEXCEL_IP_HAS_SYSLOCK01 == STD_ON)
865 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 0U;
866 #else
867 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 1U;
868 #endif
869 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSPUSH = 0U;
870 }
871 else
872 {
873 returnResult = CANEXCEL_STATUS_ERROR;
874 }
875 }
876 else
877 {
878 returnResult = CANEXCEL_STATUS_ERROR;
879 }
880 }
881 }
882
883 return returnResult;
884 }
885
886 /*FUNCTION**********************************************************************
887 *
888 * Function Name : Canexcel_Ip_ConfigXlTx
889 * Description : Config the MessageBuffer for Tx with CAN XL Format and the desired parameters from DataInfoType
890 *
891 *END**************************************************************************/
892 /* implements Canexcel_Ip_ConfigXlTx_Activity */
Canexcel_Ip_ConfigXlTx(uint8 instance,uint8 mbIdx,uint32 id,const Canexcel_Ip_DataInfoType * info,Canexcel_TxXlMsgType * TxMsg)893 void Canexcel_Ip_ConfigXlTx(uint8 instance, uint8 mbIdx, uint32 id,const Canexcel_Ip_DataInfoType * info, Canexcel_TxXlMsgType * TxMsg)
894 {
895 Canexcel_Ip_apxState[instance]->msgDesc[mbIdx].isXLFrame = TRUE;
896 TxMsg->Header.timeStampL = 0U;
897 TxMsg->Header.timeStampL = 0U;
898 TxMsg->Header.word3 = 0U;
899 TxMsg->Header.word2 = 0U;
900 TxMsg->Header.word4 = 0U;
901 TxMsg->Header.word2 = CANXL_TX_HEADER_MODE_MASK | (((uint32)info->priority << CANXL_TX_HEADER_PRIO_SHIFT) & CANXL_TX_HEADER_PRIO_MASK)
902 | (((uint32)info->retransmission << CANXL_TX_HEADER_RETR_SHIFT) & CANXL_TX_HEADER_RETR_MASK);
903 if (CANEXCEL_MSG_ID_EXT == info->idType)
904 {
905 TxMsg->Header.word3 = CANXL_TX_HEADER_IDE_MASK | (id & CANXL_IP_ID_EXT_MASK) | CANXL_TX_HEADER_XLF_MASK;
906 }
907 else
908 {
909 TxMsg->Header.word3 = ((id << CANXL_IP_ID_STD_SHIFT) & CANXL_IP_ID_STD_MASK) | CANXL_TX_HEADER_XLF_MASK;
910 }
911 TxMsg->Header.word4 = (CANXL_TX_HEADER_FDF_MASK | ((((uint32)info->dataLength - 1u) << CANXL_TX_HEADER_DLC_SHIFT) & CANXL_TX_HEADER_DLC_MASK)) | (((uint32)info->SDT << CANXL_TX_HEADER_SDT_SHIFT)&CANXL_TX_HEADER_SDT_MASK);
912 TxMsg->Header.word4 |= info->VCID;
913 TxMsg->AF = info->AF;
914 }
915
916 /*FUNCTION**********************************************************************
917 *
918 * Function Name : Canexcel_Ip_ConfigFdTx
919 * Description : Config the MessageBuffer for Tx with CAN FD Format and the desired parameters from DataInfoType
920 *
921 *END**************************************************************************/
Canexcel_Ip_ConfigFdTx(uint8 instance,uint8 mbIdx,uint32 id,const Canexcel_Ip_DataInfoType * info,Canexcel_TxFdMsgType * TxMsg)922 static void Canexcel_Ip_ConfigFdTx(uint8 instance, uint8 mbIdx, uint32 id,const Canexcel_Ip_DataInfoType * info, Canexcel_TxFdMsgType * TxMsg)
923 {
924 Canexcel_Ip_apxState[instance]->msgDesc[mbIdx].isXLFrame = FALSE;
925 uint16 dlcValue = 0U;
926 TxMsg->Header.timeStampL = 0U;
927 TxMsg->Header.timeStampL = 0U;
928 TxMsg->Header.word3 = 0U;
929 TxMsg->Header.word2 = 0U;
930 TxMsg->Header.word4 = 0U;
931 TxMsg->Header.word2 = CANXL_TX_HEADER_MODE_MASK | (((uint32)info->priority << CANXL_TX_HEADER_PRIO_SHIFT) & CANXL_TX_HEADER_PRIO_MASK)
932 | (((uint32)info->retransmission << CANXL_TX_HEADER_RETR_SHIFT) & CANXL_TX_HEADER_RETR_MASK);
933 if (CANEXCEL_MSG_ID_EXT == info->idType)
934 {
935 TxMsg->Header.word3 = CANXL_TX_HEADER_IDE_MASK | (id & CANXL_IP_ID_EXT_MASK);
936 }
937 else
938 {
939 TxMsg->Header.word3 = ((id << CANXL_IP_ID_STD_SHIFT) & CANXL_IP_ID_STD_MASK);
940 }
941
942 dlcValue = (uint16)CAN_ComputeDLCValue((uint8)(info->dataLength));
943 if (CANEXCEL_FD_FRAME == info->frame)
944 {
945 if (TRUE == info->enable_brs)
946 {
947 TxMsg->Header.word4 = CANXL_TX_HEADER_BRS_MASK | CANXL_TX_HEADER_FDF_MASK | (((uint32)dlcValue << CANXL_TX_HEADER_DLC_SHIFT) & CANXL_TX_HEADER_DLC_MASK);
948 }
949 else
950 {
951 TxMsg->Header.word4 = CANXL_TX_HEADER_FDF_MASK | (((uint32)dlcValue << CANXL_TX_HEADER_DLC_SHIFT) & CANXL_TX_HEADER_DLC_MASK);
952 }
953 }
954 else
955 {
956 TxMsg->Header.word4 = (((uint32)dlcValue << CANXL_TX_HEADER_DLC_SHIFT) & CANXL_TX_HEADER_DLC_MASK);
957 }
958 }
959 /*FUNCTION**********************************************************************
960 *
961 * Function Name : Canexcel_Ip_SendFDMsg
962 * Description : Send a CAN Classic or FD Format Message
963 *
964 *END**************************************************************************/
965 /* implements Canexcel_Ip_SendFDMsg_Activity */
Canexcel_Ip_SendFDMsg(uint8 instance,uint8 mbIdx,const Canexcel_Ip_DataInfoType * info,uint32 id,const uint8 * dataPtr,Canexcel_TxFdMsgType * TxMsg)966 Canexcel_Ip_StatusType Canexcel_Ip_SendFDMsg(uint8 instance, uint8 mbIdx,const Canexcel_Ip_DataInfoType * info, uint32 id,const uint8 * dataPtr, Canexcel_TxFdMsgType * TxMsg)
967 {
968 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_ERROR;
969
970 if (!CanXL_IsListenOnlyModeEnabled(CANEXCEL.EXL_SIC[instance]))
971 {
972 if (FALSE == CanXL_IsPwmModeEnable(CANEXCEL.EXL_SIC[instance]))
973 {
974 Canexcel_Ip_ConfigFdTx(instance, mbIdx, id, info, TxMsg);
975 CanXL_SetTxMsgBuffData(info, dataPtr, (uint8 *)&TxMsg->data[0]);
976 if (FALSE == info->is_polling)
977 {
978 CanXL_SetMsgBuffIntCmd(CANEXCEL.EXL_GRP[instance], mbIdx);
979 }
980 returnResult = Canexcel_Ip_TxDescriptor(instance, mbIdx, (uint32)&TxMsg->Header.timeStampL);
981 }
982 }
983 return returnResult;
984 }
985 /*FUNCTION**********************************************************************
986 *
987 * Function Name : Canexcel_Ip_SendXLMsg
988 * Description : Send a CAN XL Format Message
989 *
990 *END**************************************************************************/
991 /* implements Canexcel_Ip_SendXLMsg_Activity */
Canexcel_Ip_SendXLMsg(uint8 instance,uint8 mbIdx,const Canexcel_Ip_DataInfoType * info,uint32 id,const uint8 * dataPtr,Canexcel_TxXlMsgType * TxMsg)992 Canexcel_Ip_StatusType Canexcel_Ip_SendXLMsg(uint8 instance, uint8 mbIdx,const Canexcel_Ip_DataInfoType * info, uint32 id,const uint8 * dataPtr, Canexcel_TxXlMsgType * TxMsg)
993 {
994 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_ERROR;
995 if (!CanXL_IsListenOnlyModeEnabled(CANEXCEL.EXL_SIC[instance]))
996 {
997 Canexcel_Ip_ConfigXlTx(instance, mbIdx, id, info, TxMsg);
998 CanXL_SetTxMsgBuffData(info, dataPtr, (uint8 *)&TxMsg->data[0]);
999 if (FALSE == info->is_polling)
1000 {
1001 CanXL_SetMsgBuffIntCmd(CANEXCEL.EXL_GRP[instance], mbIdx);
1002 }
1003 returnResult = Canexcel_Ip_TxDescriptor(instance, mbIdx, (uint32)&TxMsg->Header.timeStampL);
1004 }
1005 return returnResult;
1006 }
1007 /*FUNCTION**********************************************************************
1008 *
1009 * Function Name : Canexcel_Ip_GetTransferStatus
1010 * Description : Check the status transfer for a Message Descriptor
1011 *
1012 *END**************************************************************************/
1013 /* implements Canexcel_Ip_GetTransferStatus_Activity */
Canexcel_Ip_GetTransferStatus(uint8 instance,uint8 descIdx)1014 Canexcel_Ip_StatusType Canexcel_Ip_GetTransferStatus(uint8 instance, uint8 descIdx)
1015 {
1016 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_NO_TRANSFER_IN_PROGRESS;
1017 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1018 DevAssert(descIdx < CANXL_DSC_CONTROL_DSCMBCTRLAR_COUNT);
1019 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
1020 #endif
1021 /* Check if the descriptor is active */
1022 if (CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descIdx].DCACT == CANXL_DSC_CONTROL_DCACT_ACT_MASK)
1023 {
1024 if (0U == CanXL_GetMDQueueDepth(CANEXCEL.EXL_GRP[instance], descIdx))
1025 {
1026 /* In case of MD Queue depth = 0 */
1027 if (CANEXCEL_DESC_STATE_EMPTY == CanXL_GetDesciptorState(CANEXCEL.EXL_DESC_CTR[instance], descIdx))
1028 {
1029 returnResult = CANEXCEL_STATUS_SUCCESS;
1030 }
1031 if (CANEXCEL_DESC_STATE_FULL == CanXL_GetDesciptorState(CANEXCEL.EXL_DESC_CTR[instance], descIdx))
1032 {
1033 returnResult = CANEXCEL_STATUS_BUSY;
1034 }
1035 }
1036 else
1037 {
1038 if (CanXL_GetDesciptorHWIndex(CANEXCEL.EXL_DESC_CTR[instance], descIdx) == CanXL_GetDesciptorSysIndex(CANEXCEL.EXL_DESC_CTR[instance], descIdx))
1039 {
1040 returnResult = CANEXCEL_STATUS_SUCCESS;
1041 }
1042 else
1043 {
1044 returnResult = CANEXCEL_STATUS_BUSY;
1045 }
1046 }
1047 if (CANEXCEL_DESC_STATE_OVERRUN == CanXL_GetDesciptorState(CANEXCEL.EXL_DESC_CTR[instance], descIdx))
1048 {
1049 returnResult = CANEXCEL_STATUS_ERROR;
1050 }
1051 }
1052 return returnResult;
1053 }
1054 /*FUNCTION**********************************************************************
1055 *
1056 * Function Name : Canexcel_Ip_EnterFreezeMode
1057 * Description : Set the HW in FreezeMode
1058 *
1059 *END**************************************************************************/
1060 /* implements Canexcel_Ip_EnterFreezeMode_Activity */
Canexcel_Ip_EnterFreezeMode(uint8 instance)1061 Canexcel_Ip_StatusType Canexcel_Ip_EnterFreezeMode(uint8 instance)
1062 {
1063 return CanXL_EnterFreezeMode(CANEXCEL.EXL_SIC[instance]);
1064 }
1065 /*FUNCTION**********************************************************************
1066 *
1067 * Function Name : Canexcel_Ip_ExitFreezeMode
1068 * Description : Set the HW in normal Run Mode
1069 *
1070 *END**************************************************************************/
1071 /* implements Canexcel_Ip_ExitFreezeMode_Activity */
Canexcel_Ip_ExitFreezeMode(uint8 instance)1072 Canexcel_Ip_StatusType Canexcel_Ip_ExitFreezeMode(uint8 instance)
1073 {
1074 return CanXL_ExitFreezeMode(CANEXCEL.EXL_SIC[instance]);
1075 }
1076 /*FUNCTION**********************************************************************
1077 *
1078 * Function Name : Canexcel_Ip_EnableInterrupts
1079 * Description : Enable CanExcel Instance Interrupts
1080 *
1081 *END**************************************************************************/
1082 /* implements Canexcel_Ip_EnableInterrupts_Activity */
Canexcel_Ip_EnableInterrupts(uint8 u8Instance)1083 Canexcel_Ip_StatusType Canexcel_Ip_EnableInterrupts(uint8 u8Instance)
1084 {
1085 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[u8Instance];
1086 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_ERROR;
1087
1088 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[u8Instance]))
1089 {
1090 CanXL_EnableInterrupts(CANEXCEL.EXL_SIC[u8Instance]);
1091 if ((CANXL_RXFIFO_CONTROL_RXFSYSACT_ACT_MASK == (CANEXCEL.EXL_RXF_CNT[u8Instance]->RXFSYSACT & CANXL_RXFIFO_CONTROL_RXFSYSACT_ACT_MASK)) && (FALSE == Canexcel_Ip_apxState[u8Instance]->rxFifo.isPolling))
1092 {
1093 /* Activate RxFifo Interrupts */
1094 CANEXCEL.EXL_RXF_CNT[u8Instance]->RXFIEN = CANXL_RXFIFO_CONTROL_RXFIEN_RXFIE_MASK | CANXL_RXFIFO_CONTROL_RXFIEN_RXFEIE_MASK;
1095 }
1096 state->isIntActive = TRUE;
1097 returnResult = CANEXCEL_STATUS_SUCCESS;
1098 }
1099
1100 return returnResult;
1101 }
1102 /*FUNCTION**********************************************************************
1103 *
1104 * Function Name : Canexcel_Ip_DisableInterrupts
1105 * Description : Disable CanExcel Instance Interrupts
1106 *
1107 *END**************************************************************************/
1108 /* implements Canexcel_Ip_DisableInterrupts_Activity */
Canexcel_Ip_DisableInterrupts(uint8 u8Instance)1109 Canexcel_Ip_StatusType Canexcel_Ip_DisableInterrupts(uint8 u8Instance)
1110 {
1111 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[u8Instance];
1112 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_ERROR;
1113
1114 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[u8Instance]))
1115 {
1116 CanXL_DisableInterrupts(CANEXCEL.EXL_SIC[u8Instance]);
1117 if (((CANEXCEL.EXL_RXF_CNT[u8Instance]->RXFSYSACT & CANXL_RXFIFO_CONTROL_RXFSYSACT_ACT_MASK) == CANXL_RXFIFO_CONTROL_RXFSYSACT_ACT_MASK) && (FALSE == Canexcel_Ip_apxState[u8Instance]->rxFifo.isPolling))
1118 {
1119 /* Clear RxFifo Interrupts */
1120 CANEXCEL.EXL_RXF_CNT[u8Instance]->RXFIEN = ~(CANXL_RXFIFO_CONTROL_RXFIEN_RXFIE_MASK | CANXL_RXFIFO_CONTROL_RXFIEN_RXFEIE_MASK);
1121 }
1122 state->isIntActive = FALSE;
1123 returnResult = CANEXCEL_STATUS_SUCCESS;
1124 }
1125 return returnResult;
1126 }
ValidateFrameDLC(uint8 instance,uint32 mb_idx,Canexcel_Ip_StateType * state)1127 static void ValidateFrameDLC(uint8 instance,uint32 mb_idx, Canexcel_Ip_StateType * state)
1128 {
1129 uint8 i = 0U;
1130 uint8 bufferIdx = 0U;
1131 uint16 dlcValueConfig = (uint16)(CANEXCEL.EXL_MSGD[instance]->MSGDSC[mb_idx].CTRL.RXCTRL & CANXL_MSG_DESCRIPTORS_RXCTRL_MBSIZE_MASK) >> CANXL_MSG_DESCRIPTORS_RXCTRL_MBSIZE_SHIFT;
1132
1133 bufferIdx = state->msgDesc[mb_idx].lastHwIdex;
1134 do
1135 {
1136 if (bufferIdx > CanXL_GetMDQueueDepth(CANEXCEL.EXL_GRP[instance], (uint8)mb_idx))
1137 {
1138 bufferIdx = 0U;
1139 }
1140 Canexcel_RxHeader * RxHeader = (Canexcel_RxHeader *)state->msgDesc[mb_idx].list[bufferIdx];
1141 uint16 dlcValue = (uint16)(RxHeader->Control & CANXL_TX_HEADER_DLC_MASK) >> CANXL_TX_HEADER_DLC_SHIFT;
1142 if(dlcValue > dlcValueConfig)
1143 {
1144 /* Clear priveous value of DLC */
1145 RxHeader->Control &= ~CANXL_TX_HEADER_DLC_MASK;
1146 /* Set the truncated value of the frame as DLC */
1147 RxHeader->Control |= ((uint32)dlcValueConfig << CANXL_TX_HEADER_DLC_SHIFT) & CANXL_TX_HEADER_DLC_MASK;
1148 }
1149 /* The Buffer was processed, ready to be used */
1150 state->msgDesc[mb_idx].isPending[bufferIdx] = FALSE;
1151 i++;
1152 bufferIdx++;
1153 } while (i < (state->msgDesc[mb_idx].noPointers));
1154 }
1155
1156 /* This function will set MODE field of all buffers completed transfering to 0 */
Canexcel_CompleteTxBuffers(uint8 instance,uint32 mb_idx,Canexcel_Ip_StateType * state)1157 static void Canexcel_CompleteTxBuffers(uint8 instance,uint32 mb_idx, Canexcel_Ip_StateType * state)
1158 {
1159 uint8 i = 0U;
1160 uint8 bufferIdx = 0U;
1161 Canexcel_TxMsgHeaderType * TxHeader = NULL_PTR;
1162
1163 bufferIdx = state->msgDesc[mb_idx].lastHwIdex;
1164 do
1165 {
1166 if (bufferIdx > CanXL_GetMDQueueDepth(CANEXCEL.EXL_GRP[instance], (uint8)mb_idx))
1167 {
1168 bufferIdx = 0U;
1169 }
1170 TxHeader = (Canexcel_TxMsgHeaderType *)state->msgDesc[mb_idx].list[bufferIdx];
1171 /* */
1172 TxHeader->word2 &= ~CANXL_TX_HEADER_MODE_MASK;
1173 /* The Buffer was processed, ready to be used */
1174 state->msgDesc[mb_idx].isPending[bufferIdx] = FALSE;
1175 i++;
1176 bufferIdx++;
1177 } while (i < (state->msgDesc[mb_idx].noPointers));
1178 }
1179 /*FUNCTION**********************************************************************
1180 *
1181 * Function Name : Canexcel_Ip_RxTxIRQHandler
1182 * Description : IrqHandler for Rx\Tx and RxFIFO
1183 *
1184 *END**************************************************************************/
1185 /* implements CAN_X_MB_Y_ISR_Activity */
Canexcel_Ip_RxTxIRQHandler(uint8 instance)1186 void Canexcel_Ip_RxTxIRQHandler(uint8 instance)
1187 {
1188 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
1189 uint32 flag_reg;
1190 uint32 mb_idx = 0U;
1191 uint8 total_mb = (uint8)((((CANEXCEL.EXL_SIC[instance]->SYSMCFG & CANXL_SIC_SYSMCFG_MAXTXMB_MASK) >> CANXL_SIC_SYSMCFG_MAXTXMB_SHIFT) + ((CANEXCEL.EXL_SIC[instance]->SYSMCFG & CANXL_SIC_SYSMCFG_MAXRXMB_MASK) >> CANXL_SIC_SYSMCFG_MAXRXMB_SHIFT)));
1192 uint8 CurrentHwIdx = 0U;
1193 uint8 queue_depth = 0U;
1194
1195 /* Check if instance initialized */
1196 if (NULL_PTR != state)
1197 {
1198 flag_reg = CanXL_GetMsgBuffIntStatusFlag(CANEXCEL.EXL_GRP[instance], mb_idx);
1199 while ((0U == flag_reg) && (mb_idx < total_mb))
1200 {
1201 mb_idx++;
1202 flag_reg = CanXL_GetMsgBuffIntStatusFlag(CANEXCEL.EXL_GRP[instance], mb_idx);
1203 }
1204
1205 if (0U != flag_reg)
1206 {
1207 queue_depth = CanXL_GetMDQueueDepth(CANEXCEL.EXL_GRP[instance], (uint8)mb_idx) + 1U;
1208 /* This check ensures that the HwPointer read is always sync with the IFLAG flag.
1209 * It's necessary because if the IFLAG is set again(a new message received/transmited) just after it was cleared but before read CurrentHwIdx,
1210 * the new message is consider to be processed(the hwpointer was plus by 1) while IFLAG is still set and the lastHwIdex is equal to CurrentHwIdx
1211 * so in next time driver will calculate wrongly the no of pointers (consider a roll over)
1212 * Note: the calculation of number of pointers based on hwpointer will not work in the case of KEEPLST is set because when UNDERUN occurred, the last buffer will be overwite,
1213 * but the hwpointer will not change(Hw implementation).
1214 */
1215 uint8 timeout = 0U;
1216 do
1217 {
1218 CanXL_ClearMsgDescIntStatusFlag(CANEXCEL.EXL_GRP[instance], mb_idx);
1219 CurrentHwIdx = (uint8)((CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[mb_idx].DCSTA & CANXL_DSC_CONTROL_DCSTA_HWPOINTER_MASK) >> CANXL_DSC_CONTROL_DCSTA_HWPOINTER_SHIFT);
1220 timeout++;
1221 } while ((0U != CanXL_GetMsgDescIntStatusFlag(CANEXCEL.EXL_GRP[instance], mb_idx)) && (timeout < queue_depth));
1222
1223 if (CurrentHwIdx > (state->msgDesc[mb_idx].lastHwIdex))
1224 {
1225 state->msgDesc[mb_idx].noPointers = CurrentHwIdx - (state->msgDesc[mb_idx].lastHwIdex);
1226 }
1227 else
1228 {
1229 state->msgDesc[mb_idx].noPointers = queue_depth - (state->msgDesc[mb_idx].lastHwIdex) + CurrentHwIdx;
1230 }
1231 /* First descriptors are always allocated for Transmission */
1232 if (mb_idx <= CANEXCEL.EXL_GRP[instance]->DSCCTRL)
1233 {
1234 Canexcel_CompleteTxBuffers(instance, mb_idx, state);
1235 /* Process Tx MDESC */
1236 if (NULL_PTR != state->callback)
1237 {
1238 state->callback(instance, CANEXCEL_EVENT_TX_COMPLETE, mb_idx, state);
1239 }
1240 }
1241 else
1242 {
1243 ValidateFrameDLC(instance, mb_idx, state);
1244 /* Process Rx MDESC */
1245 if (NULL_PTR != state->callback)
1246 {
1247 state->callback(instance, CANEXCEL_EVENT_RX_COMPLETE, mb_idx, state);
1248 }
1249 }
1250 state->msgDesc[mb_idx].lastHwIdex = CurrentHwIdx;
1251 }
1252 if (CANEXCEL.EXL_RXF_CNT[instance]->RXFSYSACT == 1U)
1253 {
1254 if (((CANEXCEL.EXL_RXF_CNT[instance]->RXFIEN & CANXL_RXFIFO_CONTROL_RXFIEN_RXFIE_MASK) != 0U) && ((CANEXCEL.EXL_RXF_CNT[instance]->RXFS & CANXL_RXFIFO_CONTROL_RXFS_RXFF_MASK) != 0U))
1255 {
1256 /* Clear the fifo flag */
1257 CANEXCEL.EXL_RXF_CNT[instance]->RXFS = CANXL_RXFIFO_CONTROL_RXFS_RXFF_MASK;
1258 /* Process RxFifo for Reception */
1259 if (NULL_PTR != state->callback)
1260 {
1261 state->callback(instance, CANEXCEL_EVENT_RXFIFO_COMPLETE, CANEXCEL_IP_MB_RXFIFO, state);
1262 }
1263 }
1264 }
1265 }
1266 else
1267 {
1268 for (mb_idx=0U; mb_idx<CANXL_DSC_CONTROL_DSCMBCTRLAR_COUNT; mb_idx++)
1269 {
1270 CanXL_ClearMsgDescIntStatusFlag(CANEXCEL.EXL_GRP[instance], mb_idx);
1271 }
1272 /* Clear the fifo flag */
1273 CANEXCEL.EXL_RXF_CNT[instance]->RXFS = CANXL_RXFIFO_CONTROL_RXFS_RXFF_MASK;
1274 }
1275 }
1276 /*FUNCTION**********************************************************************
1277 *
1278 * Function Name : Canexcel_ProcessErrIRQ
1279 * Description : This is a function in order to reduce CCM of Canexcel_Ip_ErrIRQHandler
1280 *
1281 *END**************************************************************************/
Canexcel_ProcessErrIRQ(uint8 instance,const Canexcel_Ip_StateType * state,uint32 bcanXlStatus,uint32 sysStatus)1282 static void Canexcel_ProcessErrIRQ(uint8 instance, const Canexcel_Ip_StateType * state, uint32 bcanXlStatus, uint32 sysStatus)
1283 {
1284 if (CANXL_SIC_SYSIE_CERRIE_MASK == ((CANEXCEL.EXL_SIC[instance]->SYSIE & CANXL_SIC_SYSIE_CERRIE_MASK) & sysStatus))
1285 {
1286 CANEXCEL.EXL_SIC[instance]->SYSS = CANXL_SIC_SYSS_CERR_MASK;
1287 /* Check if callback is registered */
1288 if (NULL_PTR != state->error_callback)
1289 {
1290 state->error_callback(instance, CANEXCEL_EVENT_ERROR, bcanXlStatus, state);
1291 }
1292 }
1293 if (CANXL_SIC_SYSIE_CFDPERRIE_MASK == ((CANEXCEL.EXL_SIC[instance]->SYSIE & CANXL_SIC_SYSIE_CFDPERRIE_MASK) & sysStatus))
1294 {
1295 CANEXCEL.EXL_SIC[instance]->SYSS = CANXL_SIC_SYSS_CFDPERR_MASK;
1296 if (NULL_PTR != state->error_callback)
1297 {
1298 state->error_callback(instance, CANEXCEL_EVENT_ERROR_FD, bcanXlStatus, state);
1299 }
1300 }
1301 if (CANXL_SIC_SYSIE_CRXWRNIE_MASK == ((CANEXCEL.EXL_SIC[instance]->SYSIE & CANXL_SIC_SYSIE_CRXWRNIE_MASK) & sysStatus))
1302 {
1303 CANEXCEL.EXL_SIC[instance]->SYSS = CANXL_SIC_SYSS_CRXWRN_MASK;
1304 if (NULL_PTR != state->error_callback)
1305 {
1306 state->error_callback(instance, CANEXCEL_EVENT_RX_WARNING, bcanXlStatus, state);
1307 }
1308 }
1309 if (CANXL_SIC_SYSIE_CTXWRNIE_MASK == ((CANEXCEL.EXL_SIC[instance]->SYSIE & CANXL_SIC_SYSIE_CTXWRNIE_MASK) & sysStatus))
1310 {
1311 CANEXCEL.EXL_SIC[instance]->SYSS = CANXL_SIC_SYSS_CTXWRN_MASK;
1312 if (NULL_PTR != state->error_callback)
1313 {
1314 state->error_callback(instance, CANEXCEL_EVENT_TX_WARNING, bcanXlStatus, state);
1315 }
1316 }
1317 if (CANXL_SIC_SYSIE_CDPERRIE_MASK == ((CANEXCEL.EXL_SIC[instance]->SYSIE & CANXL_SIC_SYSIE_CDPERRIE_MASK) & sysStatus))
1318 {
1319 CANEXCEL.EXL_SIC[instance]->SYSS = CANXL_SIC_SYSS_CXDPERR_MASK;
1320 if (NULL_PTR != state->error_callback)
1321 {
1322 state->error_callback(instance, CANEXCEL_EVENT_ERROR_XL, bcanXlStatus, state);
1323 }
1324 }
1325 if (CANXL_SIC_SYSIE_CPERRIE_MASK == ((CANEXCEL.EXL_SIC[instance]->SYSIE & CANXL_SIC_SYSIE_CPERRIE_MASK) & sysStatus))
1326 {
1327 CANEXCEL.EXL_SIC[instance]->SYSS = CANXL_SIC_SYSS_CPASERR_MASK;
1328 if (NULL_PTR != state->error_callback)
1329 {
1330 state->error_callback(instance, CANEXCEL_EVENT_PASSIVE, bcanXlStatus, state);
1331 }
1332 }
1333 if (CANXL_SIC_SYSIE_CBOFFIE_MASK == ((CANEXCEL.EXL_SIC[instance]->SYSIE & CANXL_SIC_SYSIE_CBOFFIE_MASK) & sysStatus))
1334 {
1335 CANEXCEL.EXL_SIC[instance]->SYSS = CANXL_SIC_SYSS_CBOFF_MASK;
1336 if (NULL_PTR != state->error_callback)
1337 {
1338 state->error_callback(instance, CANEXCEL_EVENT_BUSOFF, bcanXlStatus, state);
1339 }
1340 }
1341 }
1342 /*FUNCTION**********************************************************************
1343 *
1344 * Function Name : Canexcel_Ip_ErrIRQHandler
1345 * Description : IrqHandler for Errors
1346 *
1347 *END**************************************************************************/
1348 /* implements CAN_X_BUSOFF_ERROR_ISR_Activity */
Canexcel_Ip_ErrIRQHandler(uint8 instance)1349 void Canexcel_Ip_ErrIRQHandler(uint8 instance)
1350 {
1351 const Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
1352 uint32 sysStatus = CANEXCEL.EXL_SIC[instance]->SYSS;
1353 uint32 bcanXlStatus = 0U;
1354 /* Process CANEXCEL Error */
1355 if (NULL_PTR != state)
1356 {
1357 if (CANEXCEL_STATUS_SUCCESS == Canexcel_GetControllerMRU(instance, &bcanXlStatus, CANXL_MRU_CMD_LAST_ST))
1358 {
1359 Canexcel_ProcessErrIRQ(instance, state, bcanXlStatus, sysStatus);
1360 }
1361 }
1362 else
1363 {
1364 /* Clear all errors */
1365 CANEXCEL.EXL_SIC[instance]->SYSS = CANEXCEL_IP_SYSS_CLEAR_DEFAULT_VALUE_U32;
1366 }
1367 }
1368 /*FUNCTION**********************************************************************
1369 *
1370 * Function Name : Canexcel_Ip_MruIRQHandler
1371 * Description : IrqHandler for MRU service unit
1372 *
1373 *END**************************************************************************/
Canexcel_Ip_MruIRQHandler(uint8 instance)1374 void Canexcel_Ip_MruIRQHandler(uint8 instance)
1375 {
1376 CANXL_MRU_Type * base = CANEXCEL.EXL_MRU[instance];
1377 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
1378 uint8 mbIdx = 0u;
1379 uint32 mask = 0u;
1380 if (NULL_PTR != state)
1381 {
1382 if (CANXL_MRU_CH_CFG0_IE_MASK == (base->CHXCONFIG[0u].CH_CFG0 & CANXL_MRU_CH_CFG0_IE_MASK))
1383 {
1384 for (;mbIdx < CANXL_IP_MRU_MAILBOX_NO; mbIdx++)
1385 {
1386 uint32 tmp = base->CHXCONFIG[0u].CH_CFG1;
1387 mask = (uint32)(tmp & ((uint32)1U << ((uint32)mbIdx + (uint32)CANXL_MRU_CH_MBSTAT_MBS0_SHIFT)));
1388 if ((base->CHXCONFIG[0u].CH_MBSTAT & mask) != 0U)
1389 {
1390 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_09();
1391 state->u8MruMailboxAct |= (1U<<mbIdx);
1392 base->CHXCONFIG[0u].CH_MBSTAT |= mask;
1393 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_09();
1394 }
1395 }
1396 }
1397 }
1398 else
1399 {
1400 base->CHXCONFIG[0u].CH_MBSTAT = CANEXCEL_IP_CH1_MBSTAT_CLEAR_DEFAULT_VALUE_U32;
1401 }
1402 }
1403
1404 /*FUNCTION**********************************************************************
1405 *
1406 * Function Name : Canexcel_Ip_SetErrorInt
1407 * Description : Enable\Disable Error or BusOff Interrupt
1408 *
1409 *END**************************************************************************/
1410 /* implements Canexcel_Ip_SetErrorInt_Activity */
Canexcel_Ip_SetErrorInt(uint8 u8Instance,Canexcel_Ip_ErrorIntType type,boolean enable)1411 Canexcel_Ip_StatusType Canexcel_Ip_SetErrorInt(uint8 u8Instance, Canexcel_Ip_ErrorIntType type, boolean enable)
1412 {
1413 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_ERROR;
1414 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[u8Instance]))
1415 {
1416 switch (type)
1417 {
1418 case CANEXCEL_IP_INT_RX_WARNING:
1419 {
1420 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_RX_WARNING, enable);
1421 returnResult = CANEXCEL_STATUS_SUCCESS;
1422 break;
1423 }
1424 case CANEXCEL_IP_INT_TX_WARNING:
1425 {
1426 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_TX_WARNING, enable);
1427 returnResult = CANEXCEL_STATUS_SUCCESS;
1428 break;
1429 }
1430 case CANEXCEL_IP_INT_ERR:
1431 {
1432 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_ERR, enable);
1433 returnResult = CANEXCEL_STATUS_SUCCESS;
1434 break;
1435 }
1436 case CANEXCEL_IP_INT_ERR_FAST:
1437 {
1438 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_ERR_FAST, enable);
1439 returnResult = CANEXCEL_STATUS_SUCCESS;
1440 break;
1441 }
1442 case CANEXCEL_IP_INT_ERR_XL:
1443 {
1444 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_ERR_XL, enable);
1445 returnResult = CANEXCEL_STATUS_SUCCESS;
1446 break;
1447 }
1448 case CANEXCEL_IP_INT_ERR_INT:
1449 {
1450 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_INT_ERR, enable);
1451 returnResult = CANEXCEL_STATUS_SUCCESS;
1452 break;
1453 }
1454 case CANEXCEL_IP_INT_BUSOFF:
1455 {
1456 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_BUSOFF, enable);
1457 returnResult = CANEXCEL_STATUS_SUCCESS;
1458 break;
1459 }
1460 case CANEXCEL_IP_INT_BUSOFF_DONE:
1461 {
1462 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_BUSOFF_DONE, enable);
1463 returnResult = CANEXCEL_STATUS_SUCCESS;
1464 break;
1465 }
1466 case CANEXCEL_IP_INT_FREEZE:
1467 {
1468 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_FREEZE, enable);
1469 returnResult = CANEXCEL_STATUS_SUCCESS;
1470 break;
1471 }
1472 case CANEXCEL_IP_INT_PASS_ERR:
1473 {
1474 CanXL_SetErrIntCmd(CANEXCEL.EXL_SIC[u8Instance], CANXL_INT_PASIVE_ERR, enable);
1475 returnResult = CANEXCEL_STATUS_SUCCESS;
1476 break;
1477 }
1478 default :
1479 {
1480 /* Do Nothing will report CANEXCEL_STATUS_ERROR */
1481 break;
1482 }
1483 }
1484 }
1485 return returnResult;
1486 }
1487
1488 /*FUNCTION**********************************************************************
1489 *
1490 * Function Name : Canexcel_Ip_MainFunctionRead
1491 * Description : Process received Rx MessageBuffer or RxFifo.
1492 * This function read the messages received as pulling or if the Interrupts are disabled.
1493 *
1494 *END**************************************************************************/
1495 /* implements Canexcel_Ip_MainFunctionRead_Activity */
Canexcel_Ip_MainFunctionRead(uint8 instance,uint8 mb_idx)1496 void Canexcel_Ip_MainFunctionRead(uint8 instance, uint8 mb_idx)
1497 {
1498 Canexcel_Ip_MainFunction(instance, mb_idx);
1499 }
1500
1501 /*FUNCTION**********************************************************************
1502 *
1503 * Function Name : Canexcel_Ip_MainFunctionWrite
1504 * Description : Process sent Tx MessageBuffer or TxFifo.
1505 * This function read the messages received as pulling or if the Interrupts are disabled.
1506 *
1507 *END**************************************************************************/
1508 /* implements Canexcel_Ip_MainFunctionWrite_Activity */
Canexcel_Ip_MainFunctionWrite(uint8 instance,uint8 mb_idx)1509 void Canexcel_Ip_MainFunctionWrite(uint8 instance, uint8 mb_idx)
1510 {
1511 Canexcel_Ip_MainFunction(instance, mb_idx);
1512 }
1513
1514 /*FUNCTION**********************************************************************
1515 *
1516 * Function Name : Canexcel_Ip_GetStopMode
1517 * Description : Check if the CANEXCEL instance is STOPPED.
1518 *
1519 *END**************************************************************************/
1520 /* implements Canexcel_Ip_GetStopMode_Activity */
Canexcel_Ip_GetStopMode(uint8 instance)1521 boolean Canexcel_Ip_GetStopMode(uint8 instance)
1522 {
1523 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1524 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
1525 #endif
1526 const CANXL_SIC_Type * base = CANEXCEL.EXL_SIC[instance];
1527 return ((CANXL_SIC_SYSS_NTRDY_MASK == (base->SYSS & CANXL_SIC_SYSS_NTRDY_MASK)) ? TRUE : FALSE);
1528 }
1529
1530 /*FUNCTION**********************************************************************
1531 *
1532 * Function Name : Canexcel_Ip_ConfigRxFifo
1533 * Description : Confgure RX FIFO filter table elements.
1534 * This function will confgure RX FIFO filter table elements
1535 *END**************************************************************************/
1536 /* implements Canexcel_Ip_ConfigRxFifo_Activity */
Canexcel_Ip_ConfigRxFifo(uint8 instance,const Canexcel_Ip_RxFifoFilter * filterConfig)1537 Canexcel_Ip_StatusType Canexcel_Ip_ConfigRxFifo(uint8 instance,const Canexcel_Ip_RxFifoFilter * filterConfig)
1538 {
1539 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1540 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
1541 DevAssert(filterConfig->noActAddrFilters < CANXL_RXFIFO_ADDRACPTFLTAR_COUNT);
1542 DevAssert(filterConfig->noIdFilters < CANXL_RXFIFO_IDACPTFLTAR_COUNT);
1543 DevAssert(filterConfig->noSduFilters < CANXL_RXFIFO_SDUACPTFLTAR_COUNT);
1544 DevAssert(filterConfig->noVcanFilters < CANXL_RXFIFO_VCANACPTFLTAR_COUNT);
1545 #endif
1546 Canexcel_Ip_StatusType status = CANEXCEL_STATUS_SUCCESS;
1547 CANXL_RXFIFO_Type * base = CANEXCEL.EXL_RXFIFO[instance];
1548 CANXL_RXFIFO_CONTROL_Type * rxFifoCont_base = CANEXCEL.EXL_RXF_CNT[instance];
1549 uint8 idx;
1550 if (0U == CANEXCEL.EXL_RXF_CNT[instance]->RXFSYSACT)
1551 {
1552 status = CANEXCEL_STATUS_ERROR;
1553 }
1554 else
1555 {
1556 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[instance]))
1557 {
1558 /* Lock the RxFIFO by System by reading register */
1559 (void)rxFifoCont_base->RXFSYSLOCK;
1560 base->AFCFG = CANXL_RXFIFO_AFCFG_ACPTID((uint32)filterConfig->noIdFilters-1U);
1561 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_07();
1562 for (idx = 0U; idx < filterConfig->noIdFilters; idx++)
1563 {
1564 CanXL_ConfigIDFilter(base, &filterConfig->IdFilterPtr[idx], idx);
1565 }
1566 if (filterConfig->noActAddrFilters != 0U)
1567 {
1568 base->AFCFG |= CANXL_RXFIFO_AFCFG_AADDREN_MASK | CANXL_RXFIFO_AFCFG_ACPTADDR((uint32)filterConfig->noActAddrFilters-1U);
1569 for (idx = 0U; idx < filterConfig->noActAddrFilters; idx++)
1570 {
1571 CanXL_ConfigAccAddr(base, &filterConfig->AddrFilterPtr[idx], idx);
1572 }
1573 }
1574 if (filterConfig->noSduFilters != 0U)
1575 {
1576 base->AFCFG |= CANXL_RXFIFO_AFCFG_ASDUEN_MASK | CANXL_RXFIFO_AFCFG_ACPTSDU((uint32)filterConfig->noSduFilters-1U);
1577 for (idx = 0U; idx < filterConfig->noSduFilters; idx++)
1578 {
1579 CanXL_ConfigSDUFilter(base, &filterConfig->SduFilterPtr[idx], idx);
1580 }
1581 }
1582 if (filterConfig->noVcanFilters != 0U)
1583 {
1584 base->AFCFG |= CANXL_RXFIFO_AFCFG_AVCANEN_MASK | CANXL_RXFIFO_AFCFG_ACPTVCAN((uint32)filterConfig->noVcanFilters-1U);
1585 for (idx = 0U; idx < filterConfig->noVcanFilters; idx++)
1586 {
1587 CanXL_ConfigVCANFilter(base, &filterConfig->VcanFilterPtr[idx], idx);
1588 }
1589 }
1590 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_07();
1591 base->SECAM = filterConfig->SecMask;
1592 base->SECAV = filterConfig->SecFilter;
1593
1594 if (CANXL_RXFIFO_CONTROL_RXFCSTA_SYSLOCK_MASK == (rxFifoCont_base->RXFCSTA & CANXL_RXFIFO_CONTROL_RXFCSTA_SYSLOCK_MASK))
1595 {
1596 /* Clear the sys lock to enable transfers */
1597 rxFifoCont_base->RXFSYSLOCK = CANXL_RXFIFO_CONTROL_RXFSYSLOCK_SYSLOCK_MASK;
1598 }
1599 status = CANEXCEL_STATUS_SUCCESS;
1600 }
1601 else
1602 {
1603 status = CANEXCEL_STATUS_ERROR;
1604 }
1605 }
1606 return status;
1607 }
1608
1609 /*FUNCTION**********************************************************************
1610 *
1611 * Function Name : Canexcel_Ip_IsXLFrameType
1612 * Description : Check if a MessageDescritptor is set for receive XL frame type
1613 *END**************************************************************************/
1614 /* implements Canexcel_Ip_IsXLFrameType_Activity */
Canexcel_Ip_IsXLFrameType(uint8 instance,uint8 descNo)1615 boolean Canexcel_Ip_IsXLFrameType(uint8 instance, uint8 descNo)
1616 {
1617 const Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
1618 boolean retVal = FALSE;
1619 if (descNo == CANEXCEL_IP_MB_RXFIFO)
1620 {
1621 retVal = state->rxFifo.isXLFrame;
1622 }
1623 else
1624 {
1625 if (descNo < CANXL_MSG_DESCRIPTORS_MSGDSC_COUNT)
1626 {
1627 retVal = state->msgDesc[descNo].isXLFrame;
1628 }
1629 }
1630 return retVal;
1631 }
1632 /*FUNCTION**********************************************************************
1633 *
1634 * Function Name : Canexcel_Ip_GetControllerTxErrorCounter
1635 * Description : Return the TxErrorCounter
1636 *END**************************************************************************/
1637 /* implements Canexcel_Ip_GetControllerTxErrorCounter_Activity */
Canexcel_Ip_GetControllerTxErrorCounter(uint8 instance,uint8 * pValue)1638 Canexcel_Ip_StatusType Canexcel_Ip_GetControllerTxErrorCounter(uint8 instance, uint8 * pValue)
1639 {
1640 uint32 errorCount = 0;
1641 Canexcel_Ip_StatusType status = Canexcel_GetControllerMRU(instance, &errorCount, CANXL_MRU_CMD_READ_EC);
1642 * pValue = (uint8)((errorCount & BCANXL_EC_TEC_MASK) >> BCANXL_EC_TEC_SHIFT);
1643 return status;
1644 }
1645 /*FUNCTION**********************************************************************
1646 *
1647 * Function Name : Canexcel_Ip_GetControllerRxErrorCounter
1648 * Description : Return the RxErrorCounter
1649 *END**************************************************************************/
1650 /* implements Canexcel_Ip_GetControllerRxErrorCounter_Activity */
Canexcel_Ip_GetControllerRxErrorCounter(uint8 instance,uint8 * pValue)1651 Canexcel_Ip_StatusType Canexcel_Ip_GetControllerRxErrorCounter(uint8 instance, uint8 * pValue)
1652 {
1653 uint32 errorCount = 0;
1654 Canexcel_Ip_StatusType status = Canexcel_GetControllerMRU(instance, &errorCount, CANXL_MRU_CMD_READ_EC);
1655 * pValue = (uint8)((errorCount & BCANXL_EC_REC_MASK) >> BCANXL_EC_REC_SHIFT);
1656 return status;
1657 }
1658 /*FUNCTION**********************************************************************
1659 *
1660 * Function Name : Canexcel_Ip_GetControllerStatus
1661 * Description : Return the Bus Status
1662 *END**************************************************************************/
1663 /* implements Canexcel_Ip_GetControllerStatus_Activity */
Canexcel_Ip_GetControllerStatus(uint8 instance,uint8 * pValue)1664 Canexcel_Ip_StatusType Canexcel_Ip_GetControllerStatus(uint8 instance, uint8 * pValue)
1665 {
1666 uint32 errorCount = 0;
1667 Canexcel_Ip_StatusType status =Canexcel_GetControllerMRU(instance, &errorCount, CANXL_MRU_CMD_READ_ST);
1668 * pValue = (uint8)((errorCount & BCANXL_ST_FLTCONF_MASK) >> BCANXL_ST_FLTCONF_SHIFT);
1669 return status;
1670 }
1671 /*FUNCTION**********************************************************************
1672 *
1673 * Function Name : Canexcel_Ip_MainFunctionBusOff
1674 * Description : Check if BusOff occurred
1675 * This function check the bus off event.
1676 *
1677 *END**************************************************************************/
1678 /* implements Canexcel_Ip_MainFunctionBusOff_Activity */
Canexcel_Ip_MainFunctionBusOff(uint8 instance)1679 Canexcel_Ip_StatusType Canexcel_Ip_MainFunctionBusOff(uint8 instance)
1680 {
1681 Canexcel_Ip_StatusType eRetVal = CANEXCEL_STATUS_ERROR;
1682 CANXL_SIC_Type * base = CANEXCEL.EXL_SIC[instance];;
1683 const Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
1684 uint32 u32StatusError =0U;
1685 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1686 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
1687 #endif
1688 if (0U != (base->SYSS & CANXL_SIC_SYSS_CBOFF_MASK))
1689 {
1690 eRetVal = CANEXCEL_STATUS_SUCCESS;
1691 /* Clear BusOff Status Flag */
1692 base->SYSS = CANXL_SIC_SYSS_CBOFF_MASK;
1693 /* Invoke callback */
1694 if (state->error_callback != NULL_PTR)
1695 {
1696 /* Get error status */
1697 eRetVal = Canexcel_GetControllerMRU(instance, &u32StatusError, CANXL_MRU_CMD_LAST_ST);
1698 if (CANEXCEL_STATUS_SUCCESS == eRetVal)
1699 {
1700 state->error_callback(instance, CANEXCEL_EVENT_BUSOFF, u32StatusError, state);
1701 }
1702 }
1703 }
1704 return eRetVal;
1705 }
1706 /*FUNCTION**********************************************************************
1707 *
1708 * Function Name : Canexcel_Ip_ClearErrorStatus
1709 * Description : Clear error status register.
1710 *
1711 *END**************************************************************************/
1712 /* implements Canexcel_Ip_ClearErrorStatus_Activity */
Canexcel_Ip_ClearErrorStatus(uint8 instance,uint32 error)1713 void Canexcel_Ip_ClearErrorStatus(uint8 instance, uint32 error)
1714 {
1715 CANXL_SIC_Type * base = CANEXCEL.EXL_SIC[instance];
1716 base->SYSS = error;
1717 }
1718
1719 /*FUNCTION**********************************************************************
1720 *
1721 * Function Name : Canexcel_Ip_ManualBusOffRecovery
1722 * Description : Recover manually from bus-off if possible.
1723 *
1724 *END**************************************************************************/
1725 /* implements Canexcel_Ip_ManualBusOffRecovery_Activity */
Canexcel_Ip_ManualBusOffRecovery(uint8 instance)1726 Canexcel_Ip_StatusType Canexcel_Ip_ManualBusOffRecovery(uint8 instance)
1727 {
1728 Canexcel_Ip_StatusType eRetVal = CANEXCEL_STATUS_ERROR;
1729 const CANXL_SIC_Type * base = CANEXCEL.EXL_SIC[instance];
1730 uint32 u32AckVal = 255U;
1731
1732 if (CANXL_SIC_BCFG1_ABRDIS_MASK == (base->BCFG1 & CANXL_SIC_BCFG1_ABRDIS_MASK))
1733 {
1734 eRetVal = Canexcel_GetControllerMRU(instance, &u32AckVal, CANXL_MRU_CMD_BUSOFF);
1735 if ((CANEXCEL_STATUS_SUCCESS == eRetVal) && (u32AckVal != CANXL_MRU_CMD_BUSOFF))
1736 {
1737 eRetVal = CANEXCEL_STATUS_ERROR;
1738 }
1739 }
1740 return eRetVal;
1741 }
1742
1743 /*FUNCTION**********************************************************************
1744 *
1745 * Function Name : Canexcel_Ip_SetFDBaudRate
1746 * Description : Set bit rate segments in FD phase.
1747 *
1748 *END**************************************************************************/
1749 /* implements Canexcel_Ip_SetFDBaudRate_Activity */
Canexcel_Ip_SetFDBaudRate(uint8 Instance,const Canexcel_Ip_TimeSegmentType * TimeSeg,boolean BitRateSwitch)1750 Canexcel_Ip_StatusType Canexcel_Ip_SetFDBaudRate(uint8 Instance, const Canexcel_Ip_TimeSegmentType * TimeSeg, boolean BitRateSwitch)
1751 {
1752 Canexcel_Ip_StatusType RetVal = CANEXCEL_STATUS_ERROR;
1753 CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1754
1755 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1756 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1757 DevAssert(TimeSeg != NULL_PTR);
1758 #endif
1759
1760 if (TRUE == CanXL_IsFreezeMode(Base))
1761 {
1762 if (TRUE == CanXL_IsFDModeEnabled(Base))
1763 {
1764 CanXL_SetFDEnabled(Base, TRUE, BitRateSwitch);
1765 CanXL_SetFDBaudRate(Base, TimeSeg);
1766 RetVal = CANEXCEL_STATUS_SUCCESS;
1767 }
1768 }
1769
1770 return RetVal;
1771 }
1772
1773 /*FUNCTION**********************************************************************
1774 *
1775 * Function Name : Canexcel_Ip_SetXLBaudRate
1776 * Description : Set bit rate segments in XL phase.
1777 *
1778 *END**************************************************************************/
1779 /* implements Canexcel_Ip_SetXLBaudRate_Activity */
Canexcel_Ip_SetXLBaudRate(uint8 Instance,const Canexcel_Ip_TimeSegmentType * TimeSeg)1780 Canexcel_Ip_StatusType Canexcel_Ip_SetXLBaudRate(uint8 Instance, const Canexcel_Ip_TimeSegmentType * TimeSeg)
1781 {
1782 Canexcel_Ip_StatusType RetVal = CANEXCEL_STATUS_ERROR;
1783 CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1784
1785 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1786 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1787 DevAssert(TimeSeg != NULL_PTR);
1788 #endif
1789
1790 if (TRUE == CanXL_IsFreezeMode(Base))
1791 {
1792 if (TRUE == CanXL_IsXLModeEnabled(Base))
1793 {
1794 CanXL_SetXLBaudRate(Base, TimeSeg);
1795 RetVal = CANEXCEL_STATUS_SUCCESS;
1796 }
1797 }
1798
1799 return RetVal;
1800 }
1801
1802 /*FUNCTION**********************************************************************
1803 *
1804 * Function Name : Canexcel_Ip_SetBaudRate
1805 * Description : Set bit rate segments in nomimal phase.
1806 *
1807 *END**************************************************************************/
1808 /* implements Canexcel_Ip_SetBaudRate_Activity */
Canexcel_Ip_SetBaudRate(uint8 Instance,const Canexcel_Ip_TimeSegmentType * TimeSeg)1809 Canexcel_Ip_StatusType Canexcel_Ip_SetBaudRate(uint8 Instance, const Canexcel_Ip_TimeSegmentType * TimeSeg)
1810 {
1811 Canexcel_Ip_StatusType RetVal = CANEXCEL_STATUS_ERROR;
1812 CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1813 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1814 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1815 DevAssert(TimeSeg != NULL_PTR);
1816 #endif
1817 if (TRUE == CanXL_IsFreezeMode(Base))
1818 {
1819 CanXL_SetBaudRate(Base, TimeSeg);
1820 RetVal = CANEXCEL_STATUS_SUCCESS;
1821 }
1822 return RetVal;
1823 }
1824 /*FUNCTION**********************************************************************
1825 *
1826 * Function Name : Canexcel_Ip_GetFDBaudRate
1827 * Description : Get bit rate segments in FD phase.
1828 *
1829 *END**************************************************************************/
1830 /* implements Canexcel_Ip_GetFDBaudRate_Activity */
Canexcel_Ip_GetFDBaudRate(uint8 Instance,Canexcel_Ip_TimeSegmentType * TimeSeg)1831 void Canexcel_Ip_GetFDBaudRate(uint8 Instance, Canexcel_Ip_TimeSegmentType * TimeSeg)
1832 {
1833 const CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1834
1835 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1836 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1837 DevAssert(TimeSeg != NULL_PTR);
1838 #endif
1839 CanXL_GetFDBaudRate(Base, TimeSeg);
1840 }
1841
1842 /*FUNCTION**********************************************************************
1843 *
1844 * Function Name : Canexcel_Ip_GetXLBaudRate
1845 * Description : Get bit rate segments in XL phase.
1846 *
1847 *END**************************************************************************/
1848 /* implements Canexcel_Ip_GetXLBaudRate_Activity */
Canexcel_Ip_GetXLBaudRate(uint8 Instance,Canexcel_Ip_TimeSegmentType * TimeSeg)1849 void Canexcel_Ip_GetXLBaudRate(uint8 Instance, Canexcel_Ip_TimeSegmentType * TimeSeg)
1850 {
1851 const CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1852 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1853 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1854 DevAssert(TimeSeg != NULL_PTR);
1855 #endif
1856 CanXL_GetXLBaudRate(Base, TimeSeg);
1857 }
1858
1859 /*FUNCTION**********************************************************************
1860 *
1861 * Function Name : Canexcel_Ip_GetBaudRate
1862 * Description : Get bit rate segments in nomimal phase.
1863 *
1864 *END**************************************************************************/
1865 /* implements Canexcel_Ip_GetBaudRate_Activity */
Canexcel_Ip_GetBaudRate(uint8 Instance,Canexcel_Ip_TimeSegmentType * TimeSeg)1866 void Canexcel_Ip_GetBaudRate(uint8 Instance, Canexcel_Ip_TimeSegmentType * TimeSeg)
1867 {
1868 const CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1869 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1870 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1871 DevAssert(TimeSeg != NULL_PTR);
1872 #endif
1873 CanXL_GetBaudRate(Base, TimeSeg);
1874 }
1875 /*FUNCTION**********************************************************************
1876 *
1877 * Function Name : Canexcel_Ip_SetListenOnlyMode
1878 * Description : Enable/disable Listen Only Mode.
1879 *
1880 *END**************************************************************************/
1881 /* implements Canexcel_Ip_SetListenOnlyMode_Activity */
Canexcel_Ip_SetListenOnlyMode(uint8 Instance,boolean Enable)1882 Canexcel_Ip_StatusType Canexcel_Ip_SetListenOnlyMode(uint8 Instance, boolean Enable)
1883 {
1884 Canexcel_Ip_StatusType RetVal = CANEXCEL_STATUS_ERROR;
1885 CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1886
1887 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1888 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1889 #endif
1890 if (TRUE == CanXL_IsFreezeMode((const CANXL_SIC_Type *)Base))
1891 {
1892 CanXL_SetListenOnlyMode(Base, Enable);
1893 RetVal = CANEXCEL_STATUS_SUCCESS;
1894 }
1895 return RetVal;
1896 }
1897 /*FUNCTION**********************************************************************
1898 *
1899 * Function Name : Canexcel_Ip_GetListenOnlyMode
1900 * Description : Get Listen Only Mode.
1901 *
1902 *END**************************************************************************/
1903 /* implements Canexcel_Ip_GetListenOnlyMode_Activity */
Canexcel_Ip_GetListenOnlyMode(uint8 Instance)1904 boolean Canexcel_Ip_GetListenOnlyMode(uint8 Instance)
1905 {
1906 const CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1907
1908 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1909 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1910 #endif
1911
1912 return CanXL_IsListenOnlyModeEnabled(Base);
1913 }
1914 /*FUNCTION**********************************************************************
1915 *
1916 * Function Name : Canexcel_Ip_SetTDCOffsetFD
1917 * Description : Enables/Disables the FD Transceiver Delay Compensation feature
1918 * and sets the FD Transceiver Delay Compensation Offset.
1919 *
1920 *END**************************************************************************/
1921 /* implements Canexcel_Ip_SetTDCOffsetFD_Activity */
Canexcel_Ip_SetTDCOffsetFD(uint8 Instance,boolean TDCEnable,boolean TDCMEnable,uint8 Offset)1922 Canexcel_Ip_StatusType Canexcel_Ip_SetTDCOffsetFD(uint8 Instance, boolean TDCEnable, boolean TDCMEnable, uint8 Offset)
1923 {
1924 CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1925 Canexcel_Ip_StatusType RetVal = CANEXCEL_STATUS_ERROR;
1926
1927 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1928 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1929 /* When TDC disabled, TDC Measurement has no meaning! */
1930 DevAssert(!((FALSE == TDCEnable) && (TRUE == TDCMEnable)));
1931 #endif
1932 if (TRUE == CanXL_IsFreezeMode(Base))
1933 {
1934 CanXL_SetTDCOffsetFD(Base, TDCEnable, TDCMEnable, Offset);
1935 RetVal = CANEXCEL_STATUS_SUCCESS;
1936 }
1937 return RetVal;
1938 }
1939
1940 /*FUNCTION**********************************************************************
1941 *
1942 * Function Name : Canexcel_Ip_SetTDCOffsetXL
1943 * Description : Enables/Disables the XL Transceiver Delay Compensation feature
1944 * and sets the XL Transceiver Delay Compensation Offset.
1945 *
1946 *END**************************************************************************/
1947 /* implements Canexcel_Ip_SetTDCOffsetXL_Activity */
Canexcel_Ip_SetTDCOffsetXL(uint8 Instance,boolean TDCEnable,boolean TDCMEnable,uint8 Offset)1948 Canexcel_Ip_StatusType Canexcel_Ip_SetTDCOffsetXL(uint8 Instance, boolean TDCEnable, boolean TDCMEnable, uint8 Offset)
1949 {
1950 CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1951 Canexcel_Ip_StatusType RetVal = CANEXCEL_STATUS_ERROR;
1952
1953 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1954 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1955 /* When TDC disabled, TDC Measurement has no meaning! */
1956 DevAssert(!((FALSE == TDCEnable) && (TRUE == TDCMEnable)));
1957 #endif
1958
1959 if (TRUE == CanXL_IsFreezeMode(Base))
1960 {
1961 CanXL_SetTDCOffsetXL(Base, TDCEnable, TDCMEnable, Offset);
1962 RetVal = CANEXCEL_STATUS_SUCCESS;
1963 }
1964 return RetVal;
1965 }
1966
1967 /*FUNCTION**********************************************************************
1968 *
1969 * Function Name : Canexcel_Ip_ConfigTransceiverMode
1970 * Description : Configure PWM Short Phase, PWM Long Phase, PWM Offset, protocol exception
1971 *
1972 *END**************************************************************************/
1973 /* implements Canexcel_Ip_ConfigTransceiverMode_Activity */
Canexcel_Ip_ConfigTransceiverMode(uint8 Instance,const Canexcel_Ip_TransceiverModeType * Config)1974 Canexcel_Ip_StatusType Canexcel_Ip_ConfigTransceiverMode(uint8 Instance, const Canexcel_Ip_TransceiverModeType * Config)
1975 {
1976 CANXL_SIC_Type * Base = CANEXCEL.EXL_SIC[Instance];
1977 Canexcel_Ip_StatusType RetVal = CANEXCEL_STATUS_ERROR;
1978
1979 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
1980 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
1981 DevAssert(NULL_PTR != Config);
1982 /* when PWM mode enabled, protocol exception must be enabled */
1983 DevAssert(!((TRUE == Config->PwmModeEnable) && (FALSE == Config->ProtocolExceptionEnable)));
1984 /* when PWM mode enabled, PWMS must be in range [1:63] */
1985 DevAssert(!((TRUE == Config->PwmModeEnable) && ((0U == Config->PwmShortPhase) || (Config->PwmShortPhase > 63U))));
1986 /* when PWM mode enabled, PWML must be in range [1:63] */
1987 DevAssert(!((TRUE == Config->PwmModeEnable) && ((0U == Config->PwmLongPhase) || (Config->PwmLongPhase > 63U))));
1988 /* when PWM mode enabled, PWMO must be in range [0:63] */
1989 DevAssert(!((TRUE == Config->PwmModeEnable) && (Config->PwmOffset > 63U)));
1990 #endif
1991 if (TRUE == CanXL_IsFreezeMode(Base))
1992 {
1993 SchM_Enter_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_12();
1994 CanXL_SetPwmModeEnable(Base, Config->PwmModeEnable);
1995 CanXL_SetPWMPhases(Base, Config->PwmShortPhase, Config->PwmLongPhase, Config->PwmOffset);
1996 CanXL_SetXLErrorResponse(Base, Config->ProtocolExceptionEnable);
1997 SchM_Exit_Can_43_CANEXCEL_CAN_EXCLUSIVE_AREA_12();
1998 RetVal = CANEXCEL_STATUS_SUCCESS;
1999 }
2000 return RetVal;
2001 }
2002 /*FUNCTION**********************************************************************
2003 *
2004 * Function Name : Canexcel_Ip_ConfigAccFltBank0
2005 * Description : Configures the 32 AF, VCAN, SDU Acceptance Filters from Filter Bank 0
2006 * note: This Filters Affect only the MessageDescriptors config for XL Frame reception
2007 *END**************************************************************************/
2008 /* implements Canexcel_Ip_ConfigAccFltBank0_Activity */
Canexcel_Ip_ConfigAccFltBank0(uint8 Instance,const Canexcel_Ip_BankFilter * Config)2009 Canexcel_Ip_StatusType Canexcel_Ip_ConfigAccFltBank0(uint8 Instance, const Canexcel_Ip_BankFilter * Config)
2010 {
2011 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2012 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
2013 DevAssert(Config->noActAddrFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2014 DevAssert(Config->noSduFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2015 DevAssert(Config->noVcanFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2016 #endif
2017 Canexcel_Ip_StatusType status = CANEXCEL_STATUS_SUCCESS;
2018 uint8 idx;
2019 CANXL_FILTER_BANK_Type * base = CANEXCEL.EXL_FILTER[Instance];
2020 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[Instance]))
2021 {
2022 if (Config->noActAddrFilters != 0U)
2023 {
2024 base->AFCFG0 = CANXL_FILTER_BANK_AFCFG0_AADDREN_MASK | CANXL_FILTER_BANK_AFCFG0_ACPTADDR((uint32)Config->noActAddrFilters-1U);
2025 for (idx = 0U; idx < Config->noActAddrFilters; idx++)
2026 {
2027 CanXL_ConfigAccAddrFilterBank(base, 0U, &Config->AddrFilterPtr[idx], idx);
2028 }
2029 }
2030 if (Config->noSduFilters != 0U)
2031 {
2032 base->AFCFG0 |= CANXL_FILTER_BANK_AFCFG0_ASDUEN_MASK | CANXL_FILTER_BANK_AFCFG0_ACPTSDU((uint32)Config->noSduFilters-1U);
2033 for (idx = 0U; idx < Config->noSduFilters; idx++)
2034 {
2035 CanXL_ConfigSDUFilterBank(base, 0U, &Config->SduFilterPtr[idx], idx);
2036 }
2037 }
2038 if (Config->noVcanFilters != 0U)
2039 {
2040 base->AFCFG0 |= CANXL_FILTER_BANK_AFCFG0_AVCANEN_MASK | CANXL_FILTER_BANK_AFCFG0_ACPTVCAN((uint32)Config->noVcanFilters-1U);
2041 for (idx = 0U; idx < Config->noVcanFilters; idx++)
2042 {
2043 CanXL_ConfigVCANFilterBank(base, 0U, &Config->VcanFilterPtr[idx], idx);
2044 }
2045 }
2046
2047 }
2048 else
2049 {
2050 status = CANEXCEL_STATUS_ERROR;
2051 }
2052 return status;
2053 }
2054 /*FUNCTION**********************************************************************
2055 *
2056 * Function Name : Canexcel_Ip_ConfigAccFltBank1
2057 * Description : Configures the 32 AF, VCAN, SDU Acceptance Filters from Filter Bank 1
2058 * note: This Filters Affect only the MessageDescriptors config for XL Frame reception
2059 *END**************************************************************************/
2060 /* implements Canexcel_Ip_ConfigAccFltBank1_Activity */
Canexcel_Ip_ConfigAccFltBank1(uint8 Instance,const Canexcel_Ip_BankFilter * Config)2061 Canexcel_Ip_StatusType Canexcel_Ip_ConfigAccFltBank1(uint8 Instance, const Canexcel_Ip_BankFilter * Config)
2062 {
2063 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2064 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
2065 DevAssert(Config->noActAddrFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2066 DevAssert(Config->noSduFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2067 DevAssert(Config->noVcanFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2068 #endif
2069 Canexcel_Ip_StatusType status = CANEXCEL_STATUS_SUCCESS;
2070 uint8 idx;
2071 CANXL_FILTER_BANK_Type * base = CANEXCEL.EXL_FILTER[Instance];
2072 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[Instance]))
2073 {
2074 if (Config->noActAddrFilters != 0U)
2075 {
2076 base->AFCFG1 = CANXL_FILTER_BANK_AFCFG1_AADDREN_MASK | CANXL_FILTER_BANK_AFCFG1_ACPTADDR((uint32)Config->noActAddrFilters-1U);
2077 for (idx = 0U; idx < Config->noActAddrFilters; idx++)
2078 {
2079 CanXL_ConfigAccAddrFilterBank(base, 1U, &Config->AddrFilterPtr[idx], idx);
2080 }
2081 }
2082 if (Config->noSduFilters != 0U)
2083 {
2084 base->AFCFG1 |= CANXL_FILTER_BANK_AFCFG1_ASDUEN_MASK | CANXL_FILTER_BANK_AFCFG1_ACPTSDU((uint32)Config->noSduFilters-1U);
2085 for (idx = 0U; idx <= Config->noSduFilters; idx++)
2086 {
2087 CanXL_ConfigSDUFilterBank(base, 1U, &Config->SduFilterPtr[idx], idx);
2088 }
2089 }
2090 if (Config->noVcanFilters != 0U)
2091 {
2092 base->AFCFG1 |= CANXL_FILTER_BANK_AFCFG1_AVCANEN_MASK | CANXL_FILTER_BANK_AFCFG1_ACPTVCAN((uint32)Config->noVcanFilters-1U);
2093 for (idx = 0U; idx < Config->noSduFilters; idx++)
2094 {
2095 CanXL_ConfigVCANFilterBank(base, 1U, &Config->VcanFilterPtr[idx], idx);
2096 }
2097 }
2098
2099 }
2100 else
2101 {
2102 status = CANEXCEL_STATUS_ERROR;
2103 }
2104 return status;
2105 }
2106 /*FUNCTION**********************************************************************
2107 *
2108 * Function Name : Canexcel_Ip_ConfigRejFltBank0
2109 * Description : Configures the 32 AF, VCAN, SDU Rejection Filters from Filter Bank 0
2110 * note: This Filters Affect only the MessageDescriptors config for XL Frame reception
2111 *END**************************************************************************/
2112 /* implements Canexcel_Ip_ConfigRejFltBank0_Activity */
Canexcel_Ip_ConfigRejFltBank0(uint8 Instance,const Canexcel_Ip_BankFilter * Config)2113 Canexcel_Ip_StatusType Canexcel_Ip_ConfigRejFltBank0(uint8 Instance, const Canexcel_Ip_BankFilter * Config)
2114 {
2115 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2116 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
2117 DevAssert(Config->noActAddrFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2118 DevAssert(Config->noSduFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2119 DevAssert(Config->noVcanFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2120 #endif
2121 Canexcel_Ip_StatusType status = CANEXCEL_STATUS_SUCCESS;
2122 uint8 idx;
2123 CANXL_FILTER_BANK_Type * base = CANEXCEL.EXL_FILTER[Instance];
2124 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[Instance]))
2125 {
2126 if (Config->noActAddrFilters != 0U)
2127 {
2128 base->RFCFG0 = CANXL_FILTER_BANK_RFCFG0_RADDREN_MASK | CANXL_FILTER_BANK_RFCFG0_REJADDR((uint32)Config->noActAddrFilters-1U);
2129 for (idx = 0U; idx < Config->noActAddrFilters; idx++)
2130 {
2131 CanXL_ConfigAccAddrRejectBank(base, 0U, &Config->AddrFilterPtr[idx], idx);
2132 }
2133 }
2134 if (Config->noSduFilters != 0U)
2135 {
2136 base->RFCFG0 |= CANXL_FILTER_BANK_RFCFG0_RSDUEN_MASK | CANXL_FILTER_BANK_RFCFG0_REJSDU((uint32)Config->noSduFilters-1U);
2137 for (idx = 0U; idx < Config->noSduFilters; idx++)
2138 {
2139 CanXL_ConfigSDURejectBank(base, 0U, &Config->SduFilterPtr[idx], idx);
2140 }
2141 }
2142 if (Config->noVcanFilters != 0U)
2143 {
2144 base->RFCFG0 |= CANXL_FILTER_BANK_RFCFG0_RVCANEN_MASK | CANXL_FILTER_BANK_RFCFG0_REJVCAN((uint32)Config->noVcanFilters-1U);
2145 for (idx = 0U; idx < Config->noVcanFilters; idx++)
2146 {
2147 CanXL_ConfigVCANRejectBank(base, 0U, &Config->VcanFilterPtr[idx], idx);
2148 }
2149 }
2150
2151 }
2152 else
2153 {
2154 status = CANEXCEL_STATUS_ERROR;
2155 }
2156 return status;
2157 }
2158 /*FUNCTION**********************************************************************
2159 *
2160 * Function Name : Canexcel_Ip_ConfigRejFltBank1
2161 * Description : Configures the 32 AF, VCAN, SDU Rejection Filters from Filter Bank 1
2162 * note: This Filters Affect only the MessageDescriptors config for XL Frame reception
2163 *END**************************************************************************/
2164 /* implements Canexcel_Ip_ConfigRejFltBank1_Activity */
Canexcel_Ip_ConfigRejFltBank1(uint8 Instance,const Canexcel_Ip_BankFilter * Config)2165 Canexcel_Ip_StatusType Canexcel_Ip_ConfigRejFltBank1(uint8 Instance, const Canexcel_Ip_BankFilter * Config)
2166 {
2167 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2168 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
2169 DevAssert(Config->noActAddrFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2170 DevAssert(Config->noSduFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2171 DevAssert(Config->noVcanFilters <= CANEXCEL_IP_MAX_FILTER_BANK);
2172 #endif
2173 Canexcel_Ip_StatusType status = CANEXCEL_STATUS_SUCCESS;
2174 uint8 idx;
2175 CANXL_FILTER_BANK_Type * base = CANEXCEL.EXL_FILTER[Instance];
2176 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[Instance]))
2177 {
2178 if (Config->noActAddrFilters != 0U)
2179 {
2180 base->RFCFG1 = CANXL_FILTER_BANK_RFCFG1_RADDREN_MASK | CANXL_FILTER_BANK_RFCFG1_REJADDR((uint32)Config->noActAddrFilters-1U);
2181 for (idx = 0U; idx < Config->noActAddrFilters; idx++)
2182 {
2183 CanXL_ConfigAccAddrRejectBank(base, 1U, &Config->AddrFilterPtr[idx], idx);
2184 }
2185 }
2186 if (Config->noSduFilters != 0U)
2187 {
2188 base->RFCFG1 |= CANXL_FILTER_BANK_RFCFG1_RSDUEN_MASK | CANXL_FILTER_BANK_RFCFG1_REJSDU((uint32)Config->noSduFilters-1U);
2189 for (idx = 0U; idx < Config->noSduFilters; idx++)
2190 {
2191 CanXL_ConfigSDURejectBank(base, 1U, &Config->SduFilterPtr[idx], idx);
2192 }
2193 }
2194 if (Config->noVcanFilters != 0U)
2195 {
2196 base->RFCFG1 |= CANXL_FILTER_BANK_RFCFG1_RVCANEN_MASK | CANXL_FILTER_BANK_RFCFG1_REJVCAN((uint32)Config->noVcanFilters-1U);
2197 for (idx = 0U; idx < Config->noVcanFilters; idx++)
2198 {
2199 CanXL_ConfigVCANRejectBank(base, 1U, &Config->VcanFilterPtr[idx], idx);
2200 }
2201 }
2202
2203 }
2204 else
2205 {
2206 status = CANEXCEL_STATUS_ERROR;
2207 }
2208 return status;
2209 }
2210 /*FUNCTION**********************************************************************
2211 *
2212 * Function Name : Canexcel_Ip_ConfigAccAddrFilter
2213 * Description : Configures the ACC Filter No from Bank0 or Bank1
2214 * note: This Filters Affect only the MessageDescriptors config for XL Frame reception
2215 *END**************************************************************************/
2216 /* implements Canexcel_Ip_ConfigAccAddrFilter_Activity */
Canexcel_Ip_ConfigAccAddrFilter(uint8 Instance,const Canexcel_Ip_RxFifoFilterID_ADDR * filterValue,uint8 * filterNo)2217 Canexcel_Ip_StatusType Canexcel_Ip_ConfigAccAddrFilter(uint8 Instance,const Canexcel_Ip_RxFifoFilterID_ADDR * filterValue, uint8 * filterNo)
2218 {
2219 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2220 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
2221 DevAssert(filterValue != NULL_PTR);
2222 DevAssert(filterNo != NULL_PTR);
2223 #endif
2224 Canexcel_Ip_StatusType status = CANEXCEL_STATUS_SUCCESS;
2225 uint8 noFilter = 0U;
2226 if (TRUE == CanXL_IsFreezeMode(CANEXCEL.EXL_SIC[Instance]))
2227 {
2228 noFilter = (uint8)((CANEXCEL.EXL_FILTER[Instance]->AFCFG0 & CANXL_FILTER_BANK_AFCFG0_ACPTADDR_MASK) >> CANXL_FILTER_BANK_AFCFG0_ACPTADDR_SHIFT);
2229 if (0U == (CANEXCEL.EXL_FILTER[Instance]->AFCFG0 & CANXL_FILTER_BANK_AFCFG0_AADDREN_MASK))
2230 {
2231 CANEXCEL.EXL_FILTER[Instance]->AFCFG0 |= CANXL_FILTER_BANK_AFCFG0_AADDREN_MASK;
2232 }
2233 else
2234 {
2235 noFilter++;
2236
2237 }
2238 if (noFilter < CANEXCEL_IP_MAX_FILTER_BANK)
2239 {
2240 * filterNo = noFilter;
2241 CanXL_ConfigAccAddrFilterBank(CANEXCEL.EXL_FILTER[Instance], 0U, filterValue, noFilter);
2242 CANEXCEL.EXL_FILTER[Instance]->AFCFG0 |= CANXL_FILTER_BANK_AFCFG0_ACPTADDR(noFilter);
2243 }
2244 else
2245 {
2246 if (CANXL_SIC_SYSMCFG_FB1EN_MASK == (CANEXCEL.EXL_SIC[Instance]->SYSMCFG & CANXL_SIC_SYSMCFG_FB1EN_MASK))
2247 {
2248 noFilter = (uint8)((CANEXCEL.EXL_FILTER[Instance]->AFCFG1 & CANXL_FILTER_BANK_AFCFG1_ACPTADDR_MASK) >> CANXL_FILTER_BANK_AFCFG1_ACPTADDR_SHIFT);
2249 if (0U == (CANEXCEL.EXL_FILTER[Instance]->AFCFG1 & CANXL_FILTER_BANK_AFCFG0_AADDREN_MASK))
2250 {
2251 CANEXCEL.EXL_FILTER[Instance]->AFCFG1 |= CANXL_FILTER_BANK_AFCFG1_AADDREN_MASK;
2252 }
2253 else
2254 {
2255 noFilter++;
2256 }
2257 if ((CANEXCEL_IP_MAX_FILTER_BANK + noFilter) < (2U*CANEXCEL_IP_MAX_FILTER_BANK))
2258 {
2259 * filterNo = (CANEXCEL_IP_MAX_FILTER_BANK + noFilter);
2260 CanXL_ConfigAccAddrFilterBank(CANEXCEL.EXL_FILTER[Instance], 1U, filterValue, noFilter);
2261 }
2262 else
2263 {
2264 status = CANEXCEL_STATUS_BUFF_OUT_OF_RANGE;
2265 }
2266 }
2267 else
2268 {
2269 status = CANEXCEL_STATUS_BUFF_OUT_OF_RANGE;
2270 }
2271 }
2272 }
2273 else
2274 {
2275 status = CANEXCEL_STATUS_ERROR;
2276 }
2277 return status;
2278 }
2279 /*FUNCTION**********************************************************************
2280 *
2281 * Function Name : Canexcel_Ip_GetDescriptorStatus
2282 * Description : Return the Message Descriptor State, and HW and SYStem pointers indexes
2283 *END**************************************************************************/
2284 /* implements Canexcel_Ip_GetDescriptorStatus_Activity */
Canexcel_Ip_GetDescriptorStatus(uint8 Instance,uint8 descNo,uint8 * sysPoint,uint8 * hwPoint)2285 Canexcel_Ip_DescState Canexcel_Ip_GetDescriptorStatus(uint8 Instance, uint8 descNo, uint8 * sysPoint, uint8 * hwPoint)
2286 {
2287 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2288 DevAssert(Instance < CANXL_SIC_INSTANCE_COUNT);
2289 DevAssert(sysPoint != NULL_PTR);
2290 DevAssert(hwPoint != NULL_PTR);
2291 #endif
2292 * hwPoint = CanXL_GetDesciptorHWIndex(CANEXCEL.EXL_DESC_CTR[Instance], descNo);
2293 * sysPoint = CanXL_GetDesciptorSysIndex(CANEXCEL.EXL_DESC_CTR[Instance], descNo);
2294 return CanXL_GetDesciptorState(CANEXCEL.EXL_DESC_CTR[Instance], descNo);
2295 }
2296 /*FUNCTION**********************************************************************
2297 *
2298 * Function Name : Canexcel_Ip_SetMsgBuffInterrupt
2299 * Description : Enable\Disable the Message Descriptor Interrupt
2300 *END**************************************************************************/
2301 /* implements Canexcel_Ip_SetMsgBuffInterrupt_Activity */
Canexcel_Ip_SetMsgBuffInterrupt(uint8 instance,uint8 descNo,boolean enable)2302 void Canexcel_Ip_SetMsgBuffInterrupt(uint8 instance, uint8 descNo, boolean enable)
2303 {
2304 if (TRUE == enable)
2305 {
2306 CanXL_SetMsgBuffIntCmd(CANEXCEL.EXL_GRP[instance], descNo);
2307 }
2308 else
2309 {
2310 CanXL_ClearMsgBuffIntCmd(CANEXCEL.EXL_GRP[instance], descNo);
2311 }
2312 }
2313 /*FUNCTION**********************************************************************
2314 *
2315 * Function Name : Canexcel_Ip_GetMsgDescIntStatusFlag
2316 * Description : Retur the Message Descriptor Interrupt Status Flag
2317 *END**************************************************************************/
2318 /* implements Canexcel_Ip_GetMsgDescIntStatusFlag_Activity */
Canexcel_Ip_GetMsgDescIntStatusFlag(uint8 instance,uint8 descNo)2319 uint8 Canexcel_Ip_GetMsgDescIntStatusFlag(uint8 instance, uint8 descNo)
2320 {
2321 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2322 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
2323 #endif
2324 const CANXL_GRP_CONTROL_Type * Base = CANEXCEL.EXL_GRP[instance];
2325 return CanXL_GetMsgDescIntStatusFlag(Base, descNo);
2326 }
2327
2328 #if (CANXL_IP_HAS_ABORT == STD_ON)
Canexcel_Ip_AbortMD(uint8 instance,uint8 descNo)2329 Canexcel_Ip_StatusType Canexcel_Ip_AbortMD(uint8 instance, uint8 descNo)
2330 {
2331 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2332 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
2333 #endif
2334 uint32 timeStart = 0U;
2335 uint32 timeElapsed = 0U;
2336 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
2337 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_SUCCESS;
2338 uint32 uS2Ticks = OsIf_MicrosToTicks(CANEXCEL_IP_TIMEOUT_DURATION, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
2339 uint8 u8MbCnt = 0U;
2340 boolean isPending = FALSE;
2341
2342 for (u8MbCnt = 0U; u8MbCnt < 16U; u8MbCnt++)
2343 {
2344 if (TRUE == state->msgDesc[descNo].isPending[u8MbCnt])
2345 {
2346 isPending = TRUE;
2347 break;
2348 }
2349 }
2350
2351 if (TRUE == isPending)
2352 {
2353 /* Request to abort the MD */
2354 CANEXCEL.EXL_SIC[instance]->SYSS = CANXL_SIC_SYSS_ABTACK_MASK;
2355 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCABT = 1U;
2356 timeStart = OsIf_GetCounter(CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
2357 /* wait until the abort is completed */
2358 while (1U == CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCABT)
2359 {
2360 timeElapsed += OsIf_GetElapsed(&timeStart, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
2361 if (timeElapsed >= uS2Ticks)
2362 {
2363 returnResult = CANEXCEL_STATUS_TIMEOUT;
2364 break;
2365 }
2366 }
2367 if (CANEXCEL_STATUS_SUCCESS == returnResult)
2368 {
2369 /* Clear IFLAG */
2370 CanXL_ClearMsgDescIntStatusFlag(CANEXCEL.EXL_GRP[instance], descNo);
2371 /* Reset noPointers */
2372 state->msgDesc[descNo].noPointers = 0U;
2373 state->msgDesc[descNo].lastHwIdex = 0U;
2374 for (u8MbCnt = 0U; u8MbCnt < 16U; u8MbCnt++)
2375 {
2376 state->msgDesc[descNo].isPending[u8MbCnt] = FALSE;
2377 }
2378 }
2379 }
2380 else
2381 {
2382 returnResult = CANEXCEL_STATUS_NO_TRANSFER_IN_PROGRESS;
2383 }
2384
2385 return returnResult;
2386 }
2387 #endif /* (CANXL_IP_HAS_ABORT == STD_ON) */
2388
2389 /* implements Canexcel_Ip_DeactivateMD_Activity */
Canexcel_Ip_DeactivateMD(uint8 instance,uint8 descNo)2390 Canexcel_Ip_StatusType Canexcel_Ip_DeactivateMD(uint8 instance, uint8 descNo)
2391 {
2392 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2393 DevAssert(instance < CANXL_SIC_INSTANCE_COUNT);
2394 #endif
2395 uint32 timeStart = 0U;
2396 uint32 timeElapsed = 0U;
2397 Canexcel_Ip_StateType * state = Canexcel_Ip_apxState[instance];
2398 Canexcel_Ip_StatusType returnResult = CANEXCEL_STATUS_SUCCESS;
2399 uint32 uS2Ticks = OsIf_MicrosToTicks(CANEXCEL_IP_TIMEOUT_DURATION, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
2400 uint8 u8MbCnt = 0U;
2401 #if (CANXL_IP_HAS_ABORT == STD_ON)
2402 Canexcel_Ip_DescState DescState = CanXL_GetDesciptorState(CANEXCEL.EXL_DESC_CTR[instance], descNo);
2403
2404 /* For the IP has Abort feature, it requires MD to be in EMPTY before deactivation */
2405 if (DescState > CANEXCEL_DESC_STATE_EMPTY)
2406 {
2407 returnResult = CANEXCEL_STATUS_ERROR;
2408 }
2409 else
2410 #endif
2411 {
2412 /* It requires syslock before deactivation the MD */
2413 #if (CANEXCEL_IP_HAS_SYSLOCK01 == STD_ON)
2414 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 1U;
2415 #else
2416 (void)CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK;
2417 #endif
2418
2419 /* Wait until syslock is retrieved */
2420 timeStart = OsIf_GetCounter(CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
2421 while (CANEXCEL_DESCNTSTATUS_LOCKED_SYS != CanXL_GetDescControlStatus(CANEXCEL.EXL_DESC_CTR[instance], descNo))
2422 {
2423 timeElapsed += OsIf_GetElapsed(&timeStart, CANEXCEL_IP_SERVICE_TIMEOUT_TYPE);
2424 if (timeElapsed >= uS2Ticks)
2425 {
2426 returnResult = CANEXCEL_STATUS_TIMEOUT;
2427 break;
2428 }
2429 /* It requires syslock before deactivation the MD */
2430 #if (CANEXCEL_IP_HAS_SYSLOCK01 == STD_ON)
2431 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 1U;
2432 #else
2433 (void)CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK;
2434 #endif
2435 }
2436 /* If syslock retrieved, deactivate the MD */
2437 if (CANEXCEL_STATUS_SUCCESS == returnResult)
2438 {
2439 /* as result, the MD is deactivated(syspointer and hwpointer are reset).
2440 * And it can't participate in the message Tx or Rx process.
2441 */
2442 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCACT = 0U;
2443 /* Release syslock */
2444 #if (CANEXCEL_IP_HAS_SYSLOCK01 == STD_ON)
2445 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 0U;
2446 #else
2447 CANEXCEL.EXL_DESC_CTR[instance]->DSCMBCTRLAR[descNo].DCSYSLOCK = 1U;
2448 #endif
2449 /* Clear IFLAG */
2450 CanXL_ClearMsgDescIntStatusFlag(CANEXCEL.EXL_GRP[instance], descNo);
2451 /* Reset noPointers */
2452 state->msgDesc[descNo].noPointers = 0U;
2453 state->msgDesc[descNo].lastHwIdex = 0U;
2454 for (u8MbCnt = 0U; u8MbCnt < 16U; u8MbCnt++)
2455 {
2456 state->msgDesc[descNo].isPending[u8MbCnt] = FALSE;
2457 }
2458 }
2459 }
2460
2461 return returnResult;
2462 }
2463 /*FUNCTION**********************************************************************
2464 * Function Name : Canexcel_Ip_Deinit
2465 * Description : DeInitilize the Canexecel Module and restore the reset Values
2466 *END**************************************************************************/
2467 /* implements Canexcel_Ip_Deinit_Activity */
Canexcel_Ip_Deinit(uint8 u8Instance)2468 Canexcel_Ip_StatusType Canexcel_Ip_Deinit(uint8 u8Instance)
2469 {
2470 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
2471 DevAssert(u8Instance < CANXL_SIC_INSTANCE_COUNT);
2472 #endif
2473 Canexcel_Ip_StatusType retVal;
2474 retVal = CanXL_EnterFreezeMode(CANEXCEL.EXL_SIC[u8Instance]);
2475 if (CANEXCEL_STATUS_SUCCESS == retVal)
2476 {
2477 retVal = CanXL_SoftReset(CANEXCEL.EXL_SIC[u8Instance]);
2478 }
2479 if (CANEXCEL_STATUS_SUCCESS == retVal)
2480 {
2481 /* Clear status to default values */
2482 CANEXCEL.EXL_SIC[u8Instance]->SYSS = CANEXCEL_IP_SYSS_CLEAR_DEFAULT_VALUE_U32;
2483 /* Clear Memory ram and initialize it */
2484 CanXL_ClearRAM(&CANEXCEL, u8Instance);
2485 /* Restore Default Values */
2486 CANEXCEL.EXL_SIC[u8Instance]->BBPRS = 0U;
2487 CANEXCEL.EXL_SIC[u8Instance]->BCFG1 = 0U;
2488 CANEXCEL.EXL_SIC[u8Instance]->BCFG2 = CANEXCEL_IP_BCFG2_DEFAULT_VALUE_U32;
2489 CANEXCEL.EXL_SIC[u8Instance]->BNCBT = CANEXCEL_IP_BNCBT_DEFAULT_VALUE_U32;
2490 CANEXCEL.EXL_SIC[u8Instance]->BFDCBT = CANEXCEL_IP_BFDCBT_DEFAULT_VALUE_U32;
2491 CANEXCEL.EXL_SIC[u8Instance]->BXDCBT = CANEXCEL_IP_BXDCBT_DEFAULT_VALUE_U32;
2492 CANEXCEL.EXL_SIC[u8Instance]->BTDCC = 0U;
2493 CANEXCEL.EXL_SIC[u8Instance]->BMICI = 0U;
2494 CANEXCEL.EXL_MRU[u8Instance]->CHXCONFIG[0u].CH_CFG0 = 0U;
2495 }
2496 return retVal;
2497 }
2498
2499 #define CAN_43_CANEXCEL_STOP_SEC_CODE
2500 #include "Can_43_CANEXCEL_MemMap.h"
2501
2502 /** @} */
2503
2504