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