1 /*
2 * Copyright 2022 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #ifndef CANEXCEL_IP_HWACCESS_H_
8 #define CANEXCEL_IP_HWACCESS_H_
9
10 /**
11 * @file CanEXCEL_Ip_HwAccess.h
12 *
13 * @addtogroup CanEXCEL
14 * @{
15 */
16
17 #ifdef __cplusplus
18 extern "C"{
19 #endif
20 /*==================================================================================================
21 * INCLUDE FILES
22 * 1) system and project includes
23 * 2) needed interfaces from external units
24 * 3) internal and external interfaces from this unit
25 ==================================================================================================*/
26 #include "CanEXCEL_Ip.h"
27 #include "Mcal.h"
28 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
29 #include "Devassert.h"
30 #endif
31
32 /*==================================================================================================
33 * DEFINES AND MACROS
34 ==================================================================================================*/
35
36 #define CANXL_IP_ID_EXT_MASK (0x1FFFFFFFU)
37 #define CANXL_IP_ID_EXT_SHIFT 0
38 #define CANXL_IP_ID_EXT_WIDTH 18
39 #define CANXL_IP_ID_STD_MASK 0x1FFC0000u
40 #define CANXL_IP_ID_STD_SHIFT 18
41 #define CANXL_IP_ID_STD_WIDTH 11
42
43
44 #define CANXL_TX_HEADER_MODE_MASK 0x80000000u
45 #define CANXL_TX_HEADER_MODE_SHIFT 31
46 #define CANXL_TX_HEADER_PRIO_MASK 0x0F000000u
47 #define CANXL_TX_HEADER_PRIO_SHIFT 24
48 #define CANXL_TX_HEADER_RETR_MASK 0x38000u
49 #define CANXL_TX_HEADER_RETR_SHIFT 15
50 #define CANXL_TX_HEADER_RTR_MASK 0x80000000u
51 #define CANXL_TX_HEADER_RTR_SHIFT 31
52 #define CANXL_TX_HEADER_IDE_MASK 0x40000000u
53 #define CANXL_TX_HEADER_IDE_SHIFT 30
54 #define CANXL_TX_HEADER_IDE_WIDTH 1
55 #define CANXL_TX_HEADER_XLF_MASK 0x20000000u
56 #define CANXL_TX_HEADER_XLF_SHIFT 29
57 #define CANXL_TX_HEADER_XLF_WIDTH 1
58 #define CANXL_TX_HEADER_FDF_MASK 0x80000000u
59 #define CANXL_TX_HEADER_FDF_SHIFT 31
60 #define CANXL_TX_HEADER_FDF_WIDTH 1
61 #define CANXL_TX_HEADER_BRS_MASK 0x20000000u
62 #define CANXL_TX_HEADER_BRS_SHIFT 29
63 #define CANXL_TX_HEADER_BRS_WIDTH 1
64 #define CANXL_TX_HEADER_XLF_MASK 0x20000000u
65 #define CANXL_TX_HEADER_XLF_SHIFT 29
66 #define CANXL_TX_HEADER_XLF_WIDTH 1
67 #define CANXL_TX_HEADER_DLC_MASK 0x3FF00u
68 #define CANXL_TX_HEADER_DLC_SHIFT 8
69 #define CANXL_TX_HEADER_DLC_WIDTH 10
70
71 /*==================================================================================================
72 * ENUMS
73 ==================================================================================================*/
74
75 /*! @brief CANXL error interrupt types
76 */
77 typedef enum
78 {
79 CANXL_INT_FREEZE = CANXL_SIC_SYSIE_FRZACKIE_MASK, /*!< Un\Freeze Ack Interrupt */
80 CANXL_INT_RX_WARNING = CANXL_SIC_SYSIE_CRXWRNIE_MASK, /*!< RX warning interrupt*/
81 CANXL_INT_TX_WARNING = CANXL_SIC_SYSIE_CTXWRNIE_MASK, /*!< TX warning interrupt*/
82 CANXL_INT_INT_ERR = CANXL_SIC_SYSIE_IERRIE_MASK, /*!< Internal Error Interrupt */
83 CANXL_INT_PASIVE_ERR = CANXL_SIC_SYSIE_CPERRIE_MASK, /*!< Passive Error Interrupt */
84 CANXL_INT_ERR = CANXL_SIC_SYSIE_CERRIE_MASK, /*!< Bus Error interrupt*/
85 CANXL_INT_ERR_FAST = CANXL_SIC_SYSIE_CFDPERRIE_MASK, /*!< Error Fast interrupt*/
86 CANXL_INT_ERR_XL = CANXL_SIC_SYSIE_CDPERRIE_MASK, /*!< Error XL Interrupt */
87 CANXL_INT_BUSOFF_DONE = CANXL_SIC_SYSIE_CBDONEIE_MASK, /*!< Error BusOff Done Interrupt */
88 CANXL_INT_BUSOFF = CANXL_SIC_SYSIE_CBOFFIE_MASK, /*!< Bus off interrupt*/
89 CANXL_INT_RXSMB_OVER = CANXL_SIC_SYSIE_CRXSOERRIE_MASK, /*!< RX SMB Overrun Error Interrupt*/
90 CANXL_INT_MD_UNDER = CANXL_SIC_SYSIE_CMDUERRIE_MASK, /*!< MD Underrun Error Interrupt */
91 CANXL_INT_MD_OVER = CANXL_SIC_SYSIE_CMDOERRIE_MASK, /*!< MD Overrun Error Interrupt */
92 CANXL_INT_LOM = CANXL_SIC_SYSIE_CLSERRIE_MASK, /*!< LOM State Error Interrupt */
93 CANXL_INT_RXFIFO_OVER = CANXL_SIC_SYSIE_CRFOERRIR_MASK, /*!< RX FIFO Overflow Interrupt */
94 CANXL_INT_TXFIFO_UNDER= CANXL_SIC_SYSIE_CTFOERRIR_MASK /*!< TX FIFO Underflow Interrupt */
95 } canxl_int_type_t;
96
97 /*==================================================================================================
98 * FUNCTION PROTOTYPES
99 ==================================================================================================*/
100
101 void CanXL_SetErrIntCmd(CANXL_SIC_Type * base, canxl_int_type_t errType, boolean enable);
102 void CanXL_SetTxMsgBuffData(const Canexcel_Ip_DataInfoType * info, const uint8 * data, uint8 * MB);
103 void CanXL_ResetImaskBuff(CANXL_GRP_CONTROL_Type * base, uint8 Instance);
104 Canexcel_Ip_StatusType CanXL_SoftReset(CANXL_SIC_Type * base);
105 uint8 CAN_ComputeDLCValue(uint8 payloadSize);
106 void CanXL_ClearRAM(CANEXCEL_StructType * CANXL, uint8 instance);
107 void CanXL_SetOperationMode(CANXL_SIC_Type * base, Canexcel_Ip_ModesType mode);
108 Canexcel_Ip_DesCntStatus CanXL_GetDescControlStatus(CANXL_DSC_CONTROL_Type * base, uint8 descNo);
109 Canexcel_Ip_StatusType CanXL_EnterFreezeMode(CANXL_SIC_Type * base);
110 Canexcel_Ip_StatusType CanXL_ExitFreezeMode(CANXL_SIC_Type * base);
111 Canexcel_Ip_StatusType CanXL_ConfigCtrlOptions(CANXL_SIC_Type * base, uint32 u32Options);
112 void CanXL_DisableInterrupts(CANXL_SIC_Type * base, uint8 Instance);
113 void CanXL_EnableInterrupts(CANXL_SIC_Type * base, uint8 Instance);
114 void CanXL_ConfigInterrupts(uint8 Instance);
115
116 #if (CANEXCEL_IP_HAS_TS_ENABLE == STD_ON)
CanXL_SetTimeBaseSource(CAN_TBS_Type * base,Canexcel_Ip_TimeBaseSelType type)117 static inline void CanXL_SetTimeBaseSource(CAN_TBS_Type * base, Canexcel_Ip_TimeBaseSelType type)
118 {
119 base->CAN_TS_SEL |= CAN_TBS_CAN_TS_SEL_TS_SEL(type);
120 }
121
CanXL_SetTimeStampCaputre(CANXL_SIC_Type * base,Canexcel_Ip_TimeStampCaptureType type)122 static inline void CanXL_SetTimeStampCaputre(CANXL_SIC_Type * base, Canexcel_Ip_TimeStampCaptureType type)
123 {
124 base->BCFG2 |= CANXL_SIC_BCFG2_TSCAP(type);
125 }
126 #endif /* (CANEXCEL_IP_HAS_TS_ENABLE == STD_ON) */
127 /*FUNCTION**********************************************************************
128 *
129 * Function Name : CanXL_SetMsgBuffIntCmd
130 * Description : Set the corresponding Message Descriptor interrupt
131 *
132 *END**************************************************************************/
CanXL_SetMsgBuffIntCmd(CANXL_GRP_CONTROL_Type * base,uint32 msgBuffIdx)133 static inline void CanXL_SetMsgBuffIntCmd(CANXL_GRP_CONTROL_Type * base, uint32 msgBuffIdx)
134 {
135 uint8 ImaskCnt = msgBuffIdx/32U ;
136 /* Enable the corresponding message buffer Interrupt */
137 uint32 temp = 1UL << (msgBuffIdx % 32U);
138 base->MSGIMASK[ImaskCnt] |= temp;
139 }
140
141 /*FUNCTION**********************************************************************
142 *
143 * Function Name : CanXL_ClearMsgBuffIntCmd
144 * Description : Disable the corresponding Message Descriptor interrupt
145 *
146 *END**************************************************************************/
CanXL_ClearMsgBuffIntCmd(CANXL_GRP_CONTROL_Type * base,uint32 mb_idx)147 static inline void CanXL_ClearMsgBuffIntCmd(CANXL_GRP_CONTROL_Type * base, uint32 mb_idx )
148 {
149 uint8 ImaskCnt = mb_idx/32U ;
150 /* Enable the corresponding message buffer Interrupt */
151 uint32 temp = 1UL << (mb_idx % 32U);
152 base->MSGIMASK[ImaskCnt] &= (~temp);
153 }
154
155 /*!
156 * @brief Clears the interrupt flag of the message descriptor.
157 *
158 * @param base The CanXL MSG Grup Control base address
159 * @param msgBuffIdx Index of the message descriptor
160 */
CanXL_ClearMsgDescIntStatusFlag(CANXL_GRP_CONTROL_Type * base,uint32 msgBuffIdx)161 static inline void CanXL_ClearMsgDescIntStatusFlag(CANXL_GRP_CONTROL_Type * base, uint32 msgBuffIdx)
162 {
163 uint32 flag = ((uint32)1U << (msgBuffIdx % 32U));
164 uint8 ImaskCnt = msgBuffIdx/32U;
165 base->MSGIFLAG[ImaskCnt] = flag;
166 }
167
CanXL_GetMsgDescIntStatusFlag(const CANXL_GRP_CONTROL_Type * base,uint32 msgBuffIdx)168 static inline uint8 CanXL_GetMsgDescIntStatusFlag(const CANXL_GRP_CONTROL_Type * base, uint32 msgBuffIdx)
169 {
170 /* TODO: This need to be protected multithread access*/
171 uint8 flag = 0;
172 MCAL_DATA_SYNC_BARRIER();
173 uint8 ImaskCnt = msgBuffIdx/32U;
174 flag = (uint8)(((base->MSGIFLAG[ImaskCnt] & (1U << (msgBuffIdx % 32))) >> (msgBuffIdx % 32U)) & 1U);
175 return flag;
176 }
177 /*!
178 * @brief Gets the individual CanXL MB interrupt flag.
179 *
180 * @param base The FlexCAN base address
181 * @param msgBuffIdx Index of the message buffer
182 * @return the individual Message Buffer interrupt flag (0 and 1 are the flag value)
183 */
CanXL_GetMsgBuffIntStatusFlag(const CANXL_GRP_CONTROL_Type * base,uint32 msgBuffIdx)184 static inline uint8 CanXL_GetMsgBuffIntStatusFlag(const CANXL_GRP_CONTROL_Type * base, uint32 msgBuffIdx)
185 {
186 /* TODO: This need to be protected multithread access*/
187 uint8 flag = 0;
188 uint32 mask;
189 uint8 ImaskCnt = msgBuffIdx/32U;
190
191 if (msgBuffIdx < 32U)
192 {
193 mask = base->MSGIMASK[ImaskCnt];
194 flag = (uint8)(((base->MSGIFLAG[ImaskCnt] & mask) >> (msgBuffIdx % 32U)) & 1U);
195 }
196 return flag;
197 }
198
199 /*!
200 * @brief Check if controller is in freeze mode or not.
201 *
202 * @param base The FlexCAN base address
203 * @return TRUE if controller is in freeze mode
204 * FALSE if controller is not in freeze mode
205 */
CanXL_IsFreezeMode(const CANXL_SIC_Type * base)206 static inline boolean CanXL_IsFreezeMode(const CANXL_SIC_Type * base)
207 {
208 return ( ( ( (base->SYSMC & CANXL_SIC_SYSMC_FRZREQ_MASK) & (base->SYSS & CANXL_SIC_SYSS_FRZACKF_MASK) ) != 0U )? TRUE : FALSE);
209 }
210
CanXL_GetDesciptorState(CANXL_DSC_CONTROL_Type * base,uint8 descNo)211 static inline Canexcel_Ip_DescState CanXL_GetDesciptorState(CANXL_DSC_CONTROL_Type * base, uint8 descNo)
212 {
213 return (Canexcel_Ip_DescState)(base->DSCMBCTRLAR[descNo].STA.DCSTA & CANXL_DSC_CONTROL_DCSTA_STATE_MASK);
214 }
215
216 /*!
217 * @brief Enables/Disables the Self Reception feature.
218 *
219 * If enabled, CanExcel is allowed to receive frames transmitted by itself.
220 *
221 * @param base The CanExcel SIC base address
222 * @param enable Enable/Disable Self Reception
223 */
CanXL_SetSelfReception(CANXL_SIC_Type * base,boolean enable)224 static inline void CanXL_SetSelfReception(CANXL_SIC_Type * base,
225 boolean enable)
226 {
227 base->BCFG2 = (base->BCFG2 & ~CANXL_SIC_BCFG2_SRXEN_MASK) | CANXL_SIC_BCFG2_SRXEN(enable ? 1UL : 0UL);
228 }
229
230 /*!
231 * @brief Checks if the listen only mode is enabled.
232 *
233 * @param base The FlexCAN base address
234 * @return TRUE if enabled; FALSE if disabled
235 */
CanXL_IsListenOnlyModeEnabled(const CANXL_SIC_Type * base)236 static inline boolean CanXL_IsListenOnlyModeEnabled(const CANXL_SIC_Type * base)
237 {
238 return (((base->BCFG2 & (CANXL_SIC_BCFG2_LOM_MASK)) != 0U) ? TRUE : FALSE);
239 }
240
241 /*!
242 * @brief Enables/Disables Flexible Data rate (if supported).
243 *
244 * @param base The CanXL SIC base address
245 * @param enable TRUE to enable; FALSE to disable
246 */
CanXL_SetFDEnabled(CANXL_SIC_Type * base,boolean enableFD,boolean enableBRS)247 static inline void CanXL_SetFDEnabled(CANXL_SIC_Type * base,
248 boolean enableFD,
249 boolean enableBRS
250 )
251 {
252 base->BCFG2 = (base->BCFG2 & ~CANXL_SIC_BCFG2_FDEN_MASK) | CANXL_SIC_BCFG2_FDEN(enableFD ? 1UL : 0UL);
253 /* Enable BitRate Switch support */
254 base->BCFG1 = (base->BCFG1 & ~CANXL_SIC_BCFG1_FDRSDIS_MASK) | CANXL_SIC_BCFG1_FDRSDIS(enableBRS ? 0UL : 1UL);
255 /* Disable Transmission Delay Compensation by default */
256 base->BTDCC &= ~(CANXL_SIC_BTDCC_FTDCEN_MASK | CANXL_SIC_BTDCC_FTDCOFF_MASK);
257 }
258
259 /*!
260 * @brief Enables/Disables XL Frame Support
261 *
262 * @param base The CanXL SIC base address
263 * @param enable TRUE to enable; FALSE to disable
264 */
CanXL_SetXLEnable(CANXL_SIC_Type * base,boolean enableXL)265 static inline void CanXL_SetXLEnable(CANXL_SIC_Type * base,
266 boolean enableXL
267 )
268 {
269 base->BCFG2 = (base->BCFG2 & ~CANXL_SIC_BCFG2_XLEN_MASK) | CANXL_SIC_BCFG2_XLEN(enableXL ? 1UL : 0UL);
270 /* Disable Transmission Delay Compensation by default */
271 base->BTDCC &= ~(CANXL_SIC_BTDCC_XTDCEN_MASK | CANXL_SIC_BTDCC_XTDCOFF_MASK);
272 }
273
274 /*!
275 * @brief Sets the CanEXCEL FD time segments for setting up data bit rate.
276 *
277 * @param base The CanEXCEL base address
278 * @param timeSeg CanEXCEL time segments, which need to be set for the bit rate.
279 */
CanXL_SetFDBaudRate(CANXL_SIC_Type * base,const Canexcel_Ip_TimeSegmentType * timeSeg)280 static inline void CanXL_SetFDBaudRate(CANXL_SIC_Type * base, const Canexcel_Ip_TimeSegmentType * timeSeg)
281 {
282 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
283 DevAssert(timeSeg != NULL_PTR);
284 #endif
285 (base->BFDCBT) = 0U;
286
287 (base->BFDCBT) = ((base->BFDCBT) | (CANXL_SIC_BFDCBT_FTSEG1(timeSeg->phaseSeg1 + timeSeg->propSeg) |
288 CANXL_SIC_BFDCBT_FTSEG2(timeSeg->phaseSeg2) |
289 CANXL_SIC_BFDCBT_FRJW(timeSeg->rJumpwidth)
290 )
291 );
292 }
293
294 /*!
295 * @brief Sets the CanEXCEL XL time segments for setting up data bit rate.
296 *
297 * @param base The CanEXCEL base address
298 * @param timeSeg CanEXCEL time segments, which need to be set for the bit rate.
299 */
CanXL_SetXLBaudRate(CANXL_SIC_Type * base,const Canexcel_Ip_TimeSegmentType * timeSeg)300 static inline void CanXL_SetXLBaudRate(CANXL_SIC_Type * base, const Canexcel_Ip_TimeSegmentType * timeSeg)
301 {
302 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
303 DevAssert(timeSeg != NULL_PTR);
304 #endif
305 (base->BXDCBT) = 0U;
306
307 (base->BXDCBT) = ((base->BXDCBT) | (CANXL_SIC_BXDCBT_XTSEG1(timeSeg->phaseSeg1 + timeSeg->propSeg) |
308 CANXL_SIC_BXDCBT_XTSEG2(timeSeg->phaseSeg2) |
309 CANXL_SIC_BXDCBT_XRJW(timeSeg->rJumpwidth)
310 )
311 );
312 }
313
314 /*!
315 * @brief Sets the CanEXCEL nominal time segments for setting up data bit rate.
316 *
317 * @param base The CanEXCEL base address
318 * @param timeSeg CanEXCEL time segments, which need to be set for the bit rate.
319 */
CanXL_SetBaudRate(CANXL_SIC_Type * base,const Canexcel_Ip_TimeSegmentType * timeSeg)320 static inline void CanXL_SetBaudRate(CANXL_SIC_Type * base, const Canexcel_Ip_TimeSegmentType * timeSeg)
321 {
322 #if (CANEXCEL_IP_DEV_ERROR_DETECT == STD_ON)
323 DevAssert(timeSeg != NULL_PTR);
324 #endif
325 (base->BNCBT) = 0U;
326 (base->BBPRS) = 0U;
327
328 (base->BBPRS) = CANXL_SIC_BBPRS_PRESDIV(timeSeg->preDivider);
329 (base->BNCBT) = ((base->BNCBT) | (CANXL_SIC_BNCBT_NTSEG1(timeSeg->phaseSeg1 + timeSeg->propSeg) |
330 CANXL_SIC_BNCBT_NTSEG2(timeSeg->phaseSeg2) |
331 CANXL_SIC_BNCBT_NRJW(timeSeg->rJumpwidth)
332 )
333 );
334 }
335
336 void CanXL_ConfigAccAddr(CANXL_RXFIFO_Type * base, Canexcel_Ip_RxFifoFilterID_ADDR * filter, uint8 filtIdx);
337 void CanXL_ConfigIDFilter(CANXL_RXFIFO_Type * base, Canexcel_Ip_RxFifoFilterID_ADDR * filter, uint8 filtIdx);
338 void CanXL_ConfigSDUFilter(CANXL_RXFIFO_Type * base, Canexcel_Ip_RxFifoFilterSDU_CAN * filter, uint8 filtIdx);
339 void CanXL_ConfigVCANFilter(CANXL_RXFIFO_Type * base, Canexcel_Ip_RxFifoFilterSDU_CAN * filter, uint8 filtIdx);
340
341 #ifdef __cplusplus
342 }
343 #endif /* __cplusplus */
344
345 /** @} */
346
347 #endif /* CANEXCEL_IP_HWACCESS_H_ */
348