1 /*******************************************************************************
2 * \file cy_canfd.c
3 * \version 1.40
4 *
5 * \brief
6 *  Provides an API implementation of the CAN FD driver.
7 *
8 ********************************************************************************
9 * \copyright
10 * Copyright 2019-2020 Cypress Semiconductor Corporation
11 * SPDX-License-Identifier: Apache-2.0
12 *
13 * Licensed under the Apache License, Version 2.0 (the "License");
14 * you may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at
16 *
17 *     http://www.apache.org/licenses/LICENSE-2.0
18 *
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
24 *******************************************************************************/
25 
26 #include "cy_device.h"
27 
28 #if defined (CY_IP_MXTTCANFD)
29 
30 #include "cy_canfd.h"
31 
32 #if defined(__cplusplus)
33 extern "C" {
34 #endif
35 
36 /* Define for size of extended filter in word */
37 #define CY_CANFD_SIZE_OF_EXTID_FILTER_IN_WORD   (2U)
38 
39 /* Define for size of transmit event FIFO in word */
40 #define CY_CANFD_SIZE_OF_TXEVENT_FIFO_IN_WORD   (2U)
41 
42 /* Define for half maximum Rx buffers */
43 #define CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS     (32UL)
44 
45 #define CY_CANFD_INTERRUPT_ENABLE_DEFAULT       (CANFD_CH_M_TTCAN_IE_DRXE_Msk |  /* Message stored to Rx Buffer */\
46                                                  CANFD_CH_M_TTCAN_IE_RF1NE_Msk | /* Rx FIFO 1 New Message */\
47                                                  CANFD_CH_M_TTCAN_IE_RF0NE_Msk)  /* Rx FIFO 0 New Message */
48 #define CY_CANFD_EXT_IDENTIFIER_LENGTH          (18U)
49 
50 /* The configurable start addresses are 32-bit word addresses i.e. only bits 15
51 * to 2 are evaluated, the two least significant bits are ignored */
52 #define CY_CANFD_MRAM_SIGNIFICANT_BYTES_SHIFT   (2U)
53 
54 /* Size of R0 and R1 fields of Rx Buffer or FIFO Element in 32-bit words */
55 #define CY_CANFD_R0_R1_SIZE                     (2UL)
56 
57 /* Size of T0 and T1 fields of Tx Buffer in 32-bit words */
58 #define CY_CANFD_T0_T1_SIZE                     (2UL)
59 #define CY_CANFD_TX_EVENT_FIFO_ELEMENTS_NUM     (10UL)
60 #define CY_CANFD_CHANNEL_ADDR_MASK              (0xFFFF0000UL)
61 
62 /* Standard Filter ID 2 */
63 #define CY_CANFD_SID_FILTER_S0_SFID2_Pos        (0UL)
64 #define CY_CANFD_SID_FILTER_S0_SFID2_Msk        (0x000007FFUL)
65 
66 /* Standard Filter ID 1 */
67 #define CY_CANFD_SID_FILTER_S0_SFID1_Pos        (16UL)
68 #define CY_CANFD_SID_FILTER_S0_SFID1_Msk        (0x07FF0000UL)
69 
70 /* Standard Filter Element Configuration */
71 #define CY_CANFD_SID_FILTER_S0_SFEC_Pos         (27UL)
72 #define CY_CANFD_SID_FILTER_S0_SFEC_Msk         (0x38000000UL)
73 
74 /* Standard Filter Type */
75 #define CY_CANFD_SID_FILTER_S0_SFT_Pos          (30UL)
76 #define CY_CANFD_SID_FILTER_S0_SFT_Msk          (0xC0000000UL)
77 
78 /* Extended Filter ID 2 */
79 #define CY_CANFD_XID_FILTER_F1_EFID2_Pos        (0UL)
80 #define CY_CANFD_XID_FILTER_F1_EFID2_Msk        (0x1FFFFFFFUL)
81 
82 /* Extended Filter ID 1 */
83 #define CY_CANFD_XID_FILTER_F0_EFID1_Pos        (0UL)
84 #define CY_CANFD_XID_FILTER_F0_EFID1_Msk        (0x1FFFFFFFUL)
85 
86 /* Extended Filter Element Configuration */
87 #define CY_CANFD_XID_FILTER_F0_EFEC_Pos         (29UL)
88 #define CY_CANFD_XID_FILTER_F0_EFEC_Msk         (0xE0000000UL)
89 
90 /* Extended Filter Type */
91 #define CY_CANFD_XID_FILTER_F1_ETF_Pos          (30UL)
92 #define CY_CANFD_XID_FILTER_F1_ETF_Msk          (0xC0000000UL)
93 
94 /* Tx Buffer Element Error State Indicator (ESI) */
95 #define CY_CANFD_TX_BUFFER_T0_ESI_Pos           (31UL)
96 #define CY_CANFD_TX_BUFFER_T0_ESI_Msk           (0x80000000UL)
97 
98 /* Tx Buffer Element Extended Identifier (XTD) */
99 #define CY_CANFD_TX_BUFFER_T0_XTD_Pos           (30UL)
100 #define CY_CANFD_TX_BUFFER_T0_XTD_Msk           (0x40000000UL)
101 
102 /* Tx Buffer Element Remote Transmission Request (RTR) */
103 #define CY_CANFD_TX_BUFFER_T0_RTR_Pos           (29UL)
104 #define CY_CANFD_TX_BUFFER_T0_RTR_Msk           (0x20000000UL)
105 
106 /* Tx Buffer Element Identifier (ID) */
107 #define CY_CANFD_TX_BUFFER_T0_ID_Pos            (0UL)
108 #define CY_CANFD_TX_BUFFER_T0_ID_Msk            (0x1FFFFFFFUL)
109 
110 /* Tx Buffer Element Message Marker (MM) */
111 #define CY_CANFD_TX_BUFFER_T1_MM_Pos            (24UL)
112 #define CY_CANFD_TX_BUFFER_T1_MM_Msk            (0xFF000000UL)
113 
114 /* Tx Buffer Element Event FIFO Control (EFC) */
115 #define CY_CANFD_TX_BUFFER_T1_EFC_Pos           (23UL)
116 #define CY_CANFD_TX_BUFFER_T1_EFC_Msk           (0x00800000UL)
117 
118 /* Tx Buffer Element FD Format (FDF) */
119 #define CY_CANFD_TX_BUFFER_T1_FDF_Pos           (21UL)
120 #define CY_CANFD_TX_BUFFER_T1_FDF_Msk           (0x00200000UL)
121 
122 /* Tx Buffer Element Bit Rate Switching (BRS) */
123 #define CY_CANFD_TX_BUFFER_T1_BRS_Pos           (20UL)
124 #define CY_CANFD_TX_BUFFER_T1_BRS_Msk           (0x00100000UL)
125 
126 /* Tx Buffer Element Data Length Code (DLC) */
127 #define CY_CANFD_TX_BUFFER_T1_DLC_Pos           (16UL)
128 #define CY_CANFD_TX_BUFFER_T1_DLC_Msk           (0x000F0000UL)
129 
130 /* Rx Buffer and FIFO Element Identifier (ID) */
131 #define CY_CANFD_RX_BUFFER_R0_ID_Pos            (0UL)
132 #define CY_CANFD_RX_BUFFER_R0_ID_Msk            (0x1FFFFFFFUL)
133 
134 /* Rx Buffer and FIFO Element Remote Transmission Request (RTR) */
135 #define CY_CANFD_RX_BUFFER_R0_RTR_Pos           (29UL)
136 #define CY_CANFD_RX_BUFFER_R0_RTR_Msk           (0x20000000UL)
137 
138 /* Rx Buffer and FIFO Element Extended Identifier (XTD) */
139 #define CY_CANFD_RX_BUFFER_R0_XTD_Pos           (30UL)
140 #define CY_CANFD_RX_BUFFER_R0_XTD_Msk           (0x40000000UL)
141 
142 /* Rx Buffer and FIFO Element Error State Indicator (ESI) */
143 #define CY_CANFD_RX_BUFFER_R0_ESI_Pos           (31UL)
144 #define CY_CANFD_RX_BUFFER_R0_ESI_Msk           (0x80000000UL)
145 
146 /* Rx Buffer and FIFO Element Rx Timestamp (RXTS) */
147 #define CY_CANFD_RX_BUFFER_R1_RXTS_Pos          (0UL)
148 #define CY_CANFD_RX_BUFFER_R1_RXTS_Msk          (0x0000FFFFUL)
149 
150 /* Rx Buffer and FIFO Element Data Length Code (DLC) */
151 #define CY_CANFD_RX_BUFFER_R1_DLC_Pos           (16UL)
152 #define CY_CANFD_RX_BUFFER_R1_DLC_Msk           (0x000F0000UL)
153 
154 /* Rx Buffer and FIFO Element Bit Rate Switch (BRS) */
155 #define CY_CANFD_RX_BUFFER_R1_BRS_Pos           (20UL)
156 #define CY_CANFD_RX_BUFFER_R1_BRS_Msk           (0x00100000UL)
157 
158 /* Rx Buffer and FIFO Element FD Format (FDF) */
159 #define CY_CANFD_RX_BUFFER_R1_FDF_Pos           (21UL)
160 #define CY_CANFD_RX_BUFFER_R1_FDF_Msk           (0x00200000UL)
161 
162 /* Rx Buffer and FIFO Element Filter Index (FIDX) */
163 #define CY_CANFD_RX_BUFFER_R1_FIDX_Pos          (24UL)
164 #define CY_CANFD_RX_BUFFER_R1_FIDX_Msk          (0x7F000000UL)
165 
166 /* Rx Buffer and FIFO Element Accepted Non-matching Frame (ANMF) */
167 #define CY_CANFD_RX_BUFFER_R1_ANMF_Pos          (31UL)
168 #define CY_CANFD_RX_BUFFER_R1_ANMF_Msk          (0x80000000UL)
169 
170 #define CY_CANFD_ERRORS_MASK     (CANFD_CH_M_TTCAN_IR_RF0W_Msk  | /* Rx FIFO 0 Watermark Reached */\
171                                   CANFD_CH_M_TTCAN_IR_RF0F_Msk  | /* Rx FIFO 0 Full */\
172                                   CANFD_CH_M_TTCAN_IR_RF0L__Msk | /* Rx FIFO 0 Message Lost */\
173                                   CANFD_CH_M_TTCAN_IR_RF1W_Msk  | /* Rx FIFO 1 Watermark Reached */\
174                                   CANFD_CH_M_TTCAN_IR_RF1F_Msk  | /* Rx FIFO 1 Full */\
175                                   CANFD_CH_M_TTCAN_IR_RF1L__Msk | /* Rx FIFO 1 Message Lost */\
176                                   CANFD_CH_M_TTCAN_IR_TEFW_Msk  | /* Tx Event FIFO Watermark Reached */\
177                                   CANFD_CH_M_TTCAN_IR_TEFF_Msk  | /* Tx Event FIFO Full */\
178                                   CANFD_CH_M_TTCAN_IR_TEFL__Msk | /* Tx Event FIFO Element Lost */\
179                                   CANFD_CH_M_TTCAN_IR_TSW_Msk  | /* Timestamp Wraparound */\
180                                   CANFD_CH_M_TTCAN_IR_MRAF_Msk | /* Message RAM Access Failure */\
181                                   CANFD_CH_M_TTCAN_IR_TOO_Msk  | /* Timeout Occurred */\
182                                   CANFD_CH_M_TTCAN_IR_BEC_Msk  | /* Bit Error Corrected */\
183                                   CANFD_CH_M_TTCAN_IR_BEU_Msk  | /* Bit Error Uncorrected */\
184                                   CANFD_CH_M_TTCAN_IR_ELO_Msk  | /* Error Logging Overflow */\
185                                   CANFD_CH_M_TTCAN_IR_EP__Msk  | /* Error Passive */\
186                                   CANFD_CH_M_TTCAN_IR_EW__Msk  | /* Warning Status */\
187                                   CANFD_CH_M_TTCAN_IR_BO__Msk  | /* Bus_Off Status */\
188                                   CANFD_CH_M_TTCAN_IR_WDI_Msk  | /* Watchdog Interrupt */\
189                                   CANFD_CH_M_TTCAN_IR_PEA_Msk  | /* Protocol Error in Arb. Phase */\
190                                   CANFD_CH_M_TTCAN_IR_PED_Msk  | /* Protocol Error in Data Phase */\
191                                   CANFD_CH_M_TTCAN_IR_ARA_Msk)   /* Access to Reserved Address */
192 
193 /* Defines for default values */
194 #define CANFD_NBTP_DEF_VAL        (0x06000A03UL)
195 #define CANFD_DBTP_DEF_VAL        (0x00000A33UL)
196 
197 /* CANFD MRAM Offset */
198 #define CY_CANFD_MRAM_START_OFFSET      (0X00010000UL)
199 
200 /*****************************************************************************
201  *  DLC-Word conversion
202  *****************************************************************************/
203 static const uint8_t dataBufferSizeInWord[] =
204 {
205     2u,            /**<  8 bytes */
206     3u,            /**< 12 bytes */
207     4u,            /**< 16 bytes */
208     5u,            /**< 20 bytes */
209     6u,            /**< 24 bytes */
210     8u,            /**< 32 bytes */
211     12u,           /**< 48 bytes */
212     16u            /**< 64 bytes */
213 };
214 
215 
216 /*****************************************************************************
217 * Local function prototypes ('static')
218 *****************************************************************************/
219 
220 static uint32_t Cy_CANFD_CalcTxBufAdrs(CANFD_Type const *base, uint32_t chan,
221                                         uint32_t index,
222                                         cy_stc_canfd_context_t const *context);
223 
224 
225 /*******************************************************************************
226 * Function Name: Cy_CANFD_Init
227 ****************************************************************************//**
228 *
229 * Initializes the CAN FD module.
230 *
231 * \note The function does not enable the Tx Event FIFO but reserves 10
232 * Tx Event FIFO elements in Message RAM.
233 * \note The function enables the "Message stored to Rx Buffer",
234 * "Rx FIFO 1 New Message" and "Rx FIFO 0 New Message" interrupt events only.
235 * Other interrupts can be configured with the Cy_CANFD_SetInterruptMask() function.
236 * \note If the channel was disabled, call Cy_CANFD_Enable before calling Cy_CANFD_Init.
237 * \note Call this function only after all debug messages reception is completed.
238 *
239 * \param *base
240 * The pointer to a CAN FD instance.
241 *
242 * \param chan
243 * The CAN FD channel number.
244 *
245 * \param *config
246 * The pointer to the CAN FD configuration structure.
247 *
248 * \param *context
249 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
250 * by the user. The structure is used during the CAN FD operation for internal
251 * configuration and data retention. User must not modify anything in this
252 * structure.
253 *
254 * \return
255 * \ref cy_en_canfd_status_t
256 *
257 * \funcusage
258 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_Init
259 *
260 *******************************************************************************/
Cy_CANFD_Init(CANFD_Type * base,uint32_t chan,const cy_stc_canfd_config_t * config,cy_stc_canfd_context_t * context)261 cy_en_canfd_status_t Cy_CANFD_Init(CANFD_Type *base, uint32_t chan,
262                                    const cy_stc_canfd_config_t *config,
263                                    cy_stc_canfd_context_t *context)
264 {
265     cy_en_canfd_status_t ret = CY_CANFD_BAD_PARAM;
266     volatile uint32_t* address;
267     uint32_t  count;
268     uint32_t  sizeInWord;
269 
270     /* Check for NULL pointers */
271     if ((NULL != base) &&
272         (NULL != context) &&
273         (NULL != config) &&
274         (NULL != config->bitrate) &&
275         (NULL != config->globalFilterConfig) &&
276         (NULL != config->rxFIFO0Config) &&
277         (NULL != config->rxFIFO1Config)
278        )
279     {
280         CY_ASSERT_L2(CY_CANFD_IS_CHANNEL_VALID(chan));
281         CY_ASSERT_L2(CY_CANFD_IS_NOM_PRESCALER_VALID(config->bitrate->prescaler));
282         CY_ASSERT_L2(CY_CANFD_IS_NOM_TIME_SEG_1_VALID(config->bitrate->timeSegment1));
283         CY_ASSERT_L2(CY_CANFD_IS_NOM_TIME_SEG_2_VALID(config->bitrate->timeSegment2));
284         CY_ASSERT_L2(CY_CANFD_IS_NOM_SYNC_JUMP_WIDTH_VALID(config->bitrate->syncJumpWidth));
285 
286         CY_ASSERT_L2(CY_CANFD_IS_SID_FILTERS_VALID(config->sidFilterConfig->numberOfSIDFilters));
287         CY_ASSERT_L2(CY_CANFD_IS_XID_FILTERS_VALID(config->extidFilterConfig->numberOfEXTIDFilters));
288 
289         CY_ASSERT_L3(CY_CANFD_IS_ACCEPT_MATCHING_VALID(config->globalFilterConfig->nonMatchingFramesStandard));
290         CY_ASSERT_L3(CY_CANFD_IS_ACCEPT_MATCHING_VALID(config->globalFilterConfig->nonMatchingFramesExtended));
291 
292         CY_ASSERT_L3(CY_CANFD_IS_BUF_DATA_SIZE_VALID(config->rxBufferDataSize, config->canFDMode));
293         CY_ASSERT_L3(CY_CANFD_IS_BUF_DATA_SIZE_VALID(config->rxFIFO1DataSize, config->canFDMode));
294         CY_ASSERT_L3(CY_CANFD_IS_BUF_DATA_SIZE_VALID(config->rxFIFO0DataSize, config->canFDMode));
295         CY_ASSERT_L3(CY_CANFD_IS_BUF_DATA_SIZE_VALID(config->txBufferDataSize, config->canFDMode));
296 
297         CY_ASSERT_L3(CY_CANFD_IS_FIFO_MODE_VALID(config->rxFIFO0Config->mode));
298         CY_ASSERT_L3(CY_CANFD_IS_FIFO_MODE_VALID(config->rxFIFO1Config->mode));
299 
300         CY_ASSERT_L2(CY_CANFD_IS_FIFO_NUM_VALID(config->rxFIFO0Config->numberOfFIFOElements));
301         CY_ASSERT_L2(CY_CANFD_IS_FIFO_NUM_VALID(config->rxFIFO1Config->numberOfFIFOElements));
302 
303         CY_ASSERT_L2(CY_CANFD_IS_WATERMARK_VALID(config->rxFIFO1Config->watermark));
304         CY_ASSERT_L2(CY_CANFD_IS_WATERMARK_VALID(config->rxFIFO1Config->watermark));
305 
306         CY_ASSERT_L2(CY_CANFD_IS_RX_BUF_NUM_VALID(config->noOfRxBuffers));
307         CY_ASSERT_L2(CY_CANFD_IS_TX_BUF_NUM_VALID(config->noOfTxBuffers));
308 
309         /* Set the notification callback functions */
310         context->canFDInterruptHandling.canFDTxInterruptFunction = config->txCallback;
311         context->canFDInterruptHandling.canFDRxInterruptFunction = config->rxCallback;
312         context->canFDInterruptHandling.canFDErrorInterruptFunction = config->errorCallback;
313 
314         /* Set CCCR_INIT and CCCR_CCE bits  */
315         ret = Cy_CANFD_ConfigChangesEnable(base, chan);
316 
317         if (CY_CANFD_SUCCESS == ret)
318         {
319             /* Save the message RAM offset and size for the current CAN FD channel */
320             context->messageRAMaddress = config->messageRAMaddress;
321             context->messageRAMsize = config->messageRAMsize;
322 
323             if ((0U   != config->sidFilterConfig->numberOfSIDFilters) &&
324                 (NULL != config->sidFilterConfig->sidFilter))
325             {
326                 /* Configure a standard ID filter:
327                 * The number of SID filters and Start address (word) of the SID filter
328                 * configuration in Message RAM
329                 */
330                 CANFD_SIDFC(base, chan) =
331                 _VAL2FLD(CANFD_CH_M_TTCAN_SIDFC_LSS, config->sidFilterConfig->numberOfSIDFilters) |
332                 _VAL2FLD(CANFD_CH_M_TTCAN_SIDFC_FLSSA, config->messageRAMaddress >> CY_CANFD_MRAM_SIGNIFICANT_BYTES_SHIFT);
333             }
334             else
335             {
336                 CANFD_SIDFC(base, chan) = _VAL2FLD(CANFD_CH_M_TTCAN_SIDFC_FLSSA, config->messageRAMaddress >> CY_CANFD_MRAM_SIGNIFICANT_BYTES_SHIFT);
337             }
338 
339             if((0U   != config->extidFilterConfig->numberOfEXTIDFilters) &&
340                (NULL != config->extidFilterConfig->extidFilter))
341             {
342                 /* Configure an extended ID filter:
343                 * The number of XID filters and start address (word) of the ext id
344                 * filter configuration in Message RAM
345                 */
346                 CANFD_XIDFC(base, chan) =
347                 _VAL2FLD(CANFD_CH_M_TTCAN_XIDFC_LSE, config->extidFilterConfig->numberOfEXTIDFilters) |
348                 _VAL2FLD(CANFD_CH_M_TTCAN_XIDFC_FLESA, _FLD2VAL(CANFD_CH_M_TTCAN_SIDFC_FLSSA, CANFD_SIDFC(base, chan)) +
349                                                            (config->sidFilterConfig->numberOfSIDFilters));
350 
351                 /* Update the extended ID AND Mask */
352                 CANFD_XIDAM(base, chan) = _VAL2FLD(CANFD_CH_M_TTCAN_XIDAM_EIDM, config->extidFilterConfig->extIDANDMask);
353             }
354             else
355             {
356                 CANFD_XIDFC(base, chan) = _VAL2FLD(CANFD_CH_M_TTCAN_XIDFC_FLESA, _FLD2VAL(CANFD_CH_M_TTCAN_SIDFC_FLSSA, CANFD_SIDFC(base, chan)) +
357                                                            (config->sidFilterConfig->numberOfSIDFilters));
358                 CANFD_XIDAM(base, chan) = 0U;
359             }
360 
361             /* Configuration of Rx Buffer and Rx FIFO */
362             CANFD_RXESC(base, chan) =
363             _VAL2FLD(CANFD_CH_M_TTCAN_RXESC_RBDS, config->rxBufferDataSize) | /* Rx Buffer Data Size */
364             _VAL2FLD(CANFD_CH_M_TTCAN_RXESC_F1DS, config->rxFIFO1DataSize) | /* Rx FIFO 1 Data Size */
365             _VAL2FLD(CANFD_CH_M_TTCAN_RXESC_F0DS, config->rxFIFO0DataSize);  /* Rx FIFO 0 Data Size */
366 
367             /* Set the Rx FIFO 0 configuration:
368              *  CAN FD RX FIFO 0 operating mode
369              *  RX FIFO 0 Watermark
370              *  The number of RX FIFO 0 Elements
371              *  The start address of Rx FIFO 0 in Message RAM
372              */
373             CANFD_RXF0C(base, chan) =
374             _VAL2FLD(CANFD_CH_M_TTCAN_RXF0C_F0OM, config->rxFIFO0Config->mode) |
375             _VAL2FLD(CANFD_CH_M_TTCAN_RXF0C_F0WM, config->rxFIFO0Config->watermark) |
376             _VAL2FLD(CANFD_CH_M_TTCAN_RXF0C_F0S, config->rxFIFO0Config->numberOfFIFOElements) |
377             _VAL2FLD(CANFD_CH_M_TTCAN_RXF0C_F0SA, _FLD2VAL(CANFD_CH_M_TTCAN_XIDFC_FLESA, CANFD_XIDFC(base, chan)) +
378                                                           (config->extidFilterConfig->numberOfEXTIDFilters *
379                                                            CY_CANFD_SIZE_OF_EXTID_FILTER_IN_WORD));
380 
381             /* Set the Rx FIFO 1 configuration:
382              *  CAN FD RX FIFO  1 operating mode
383              *  RX FIFO 1 Watermark
384              *  The number of RX FIFO 1 Elements
385              *  The start address of Rx FIFO 1 in Message RAM
386             */
387             CANFD_RXF1C(base, chan) =
388             _VAL2FLD(CANFD_CH_M_TTCAN_RXF1C_F1OM, config->rxFIFO1Config->mode) |
389             _VAL2FLD(CANFD_CH_M_TTCAN_RXF1C_F1WM, config->rxFIFO1Config->watermark) |
390             _VAL2FLD(CANFD_CH_M_TTCAN_RXF1C_F1S, config->rxFIFO1Config->numberOfFIFOElements) |
391             _VAL2FLD(CANFD_CH_M_TTCAN_RXF1C_F1SA,
392                     _FLD2VAL(CANFD_CH_M_TTCAN_RXF0C_F0SA, CANFD_RXF0C(base, chan)) +
393                             (config->rxFIFO0Config->numberOfFIFOElements *
394                              (CY_CANFD_R0_R1_SIZE + dataBufferSizeInWord[config->rxFIFO0DataSize])));
395 
396             /* Configure the Rx FIFO 0,1 Top pointer logic configuration */
397             CANFD_RXFTOP_CTL(base, chan) =
398             _VAL2FLD(CANFD_CH_RXFTOP_CTL_F0TPE, (config->rxFIFO0Config->topPointerLogicEnabled) ? 1UL : 0UL) |
399             _VAL2FLD(CANFD_CH_RXFTOP_CTL_F1TPE, (config->rxFIFO1Config->topPointerLogicEnabled) ? 1UL : 0UL);
400 
401             /* Set the start address of the Rx buffer in Message RAM */
402             CANFD_RXBC(base, chan) =
403             _VAL2FLD(CANFD_CH_M_TTCAN_RXBC_RBSA, _FLD2VAL(CANFD_CH_M_TTCAN_RXF1C_F1SA, CANFD_RXF1C(base, chan)) +
404                                      (config->rxFIFO1Config->numberOfFIFOElements *
405                                      (CY_CANFD_R0_R1_SIZE + dataBufferSizeInWord[config->rxFIFO1DataSize])));
406 
407             /* Configure Tx Buffer and Tx FIFO/Queue */
408             CANFD_TXESC(base, chan) = _VAL2FLD(CANFD_CH_M_TTCAN_TXESC_TBDS, config->txBufferDataSize);
409 
410             /* Set Tx FIFO/QUEUE (not used):
411              *  The Watermark interrupt disabled
412              *  Tx Event FIFO disabled
413              *  The start address of Tx Event FIFO in Message RAM
414             */
415             CANFD_TXEFC(base, chan) =
416             _VAL2FLD(CANFD_CH_M_TTCAN_TXEFC_EFWM, 0UL) |
417             _VAL2FLD(CANFD_CH_M_TTCAN_TXEFC_EFS, 0UL)  |
418             _VAL2FLD(CANFD_CH_M_TTCAN_TXEFC_EFSA, _FLD2VAL(CANFD_CH_M_TTCAN_RXBC_RBSA, CANFD_RXBC(base, chan)) +
419                                                           (config->noOfRxBuffers * (CY_CANFD_R0_R1_SIZE +
420                                                            dataBufferSizeInWord[config->rxBufferDataSize])));
421 
422             /* Update Tx buffer configuration:
423              *  The Tx FIFO operation
424              *  No Tx FIFO/Queue
425              *  The number of Dedicated Tx Buffers
426              *  Reserve memory for 10 Tx Event FIFO elements for easy use in future
427              */
428             CANFD_TXBC(base, chan) =
429             _VAL2FLD(CANFD_CH_M_TTCAN_TXBC_TFQM, 0UL) |
430             _VAL2FLD(CANFD_CH_M_TTCAN_TXBC_TFQS, 0UL) |
431             _VAL2FLD(CANFD_CH_M_TTCAN_TXBC_NDTB, config->noOfTxBuffers) |
432             _VAL2FLD(CANFD_CH_M_TTCAN_TXBC_TBSA, _FLD2VAL(CANFD_CH_M_TTCAN_TXEFC_EFSA, CANFD_TXEFC(base, chan)) +
433                                                                      (CY_CANFD_TX_EVENT_FIFO_ELEMENTS_NUM *
434                                                                       CY_CANFD_SIZE_OF_TXEVENT_FIFO_IN_WORD));
435 
436             /* Initialize the Message RAM area (Entire region zeroing) for channel */
437             address = (volatile uint32_t *)(config->messageRAMaddress);
438             sizeInWord = config->messageRAMsize >> CY_CANFD_MRAM_SIGNIFICANT_BYTES_SHIFT;
439             for(count = 0UL; count < sizeInWord; count++)
440             {
441                 address[count] = 0UL;
442             }
443 
444             /* The configuration of the CAN bus */
445 
446             /* CCCR register */
447             CANFD_CCCR(base, chan) = _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_INIT, 1UL) | /* Keep in initialization state */
448                                _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_CCE, 1UL)  | /* Keep CCE to enabled */
449                                _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_TXP, 0UL)  | /* Transmit pause disabled */
450                                _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_BRSE, ((config->canFDMode) ? 1UL : 0UL)) | /* Bit rate */
451                                _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_FDOE, ((config->canFDMode) ? 1UL : 0UL)) | /* FD mode */
452                                _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_TEST, 0UL) | /* Normal operation */
453                                _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_DAR, 0UL)  | /* Automatic retransmission enabled */
454                                _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_MON_, 0UL) | /* Bus Monitoring Mode is disabled */
455                                _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_CSR, 0UL)  | /* No clock stop is requested */
456                                _VAL2FLD(CANFD_CH_M_TTCAN_CCCR_ASM, 0UL);   /* Normal CAN operation */
457 
458             /* The nominal bit timing & prescaler register */
459             Cy_CANFD_SetBitrate(base, chan, config->bitrate);
460 
461             if (config->canFDMode)
462             {
463                 if (NULL != config->fastBitrate)
464                 {
465                     CY_ASSERT_L2(CY_CANFD_IS_DAT_PRESCALER_VALID(config->fastBitrate->prescaler));
466                     CY_ASSERT_L2(CY_CANFD_IS_DAT_TIME_SEG_1_VALID(config->fastBitrate->timeSegment1));
467                     CY_ASSERT_L2(CY_CANFD_IS_DAT_TIME_SEG_2_VALID(config->fastBitrate->timeSegment2));
468                     CY_ASSERT_L2(CY_CANFD_IS_DAT_SYNC_JUMP_WIDTH_VALID(config->fastBitrate->syncJumpWidth));
469 
470                     /* Set data bit timing & prescaler */
471                     Cy_CANFD_SetFastBitrate(base, chan, config->fastBitrate);
472                 }
473                 else
474                 {
475                    ret = CY_CANFD_BAD_PARAM;
476                 }
477 
478                 if ((NULL != config->tdcConfig) && (ret != CY_CANFD_BAD_PARAM))
479                 {
480                     CY_ASSERT_L2(CY_CANFD_IS_TDCO_VALID(config->tdcConfig->tdcOffset));
481                     CY_ASSERT_L2(CY_CANFD_IS_TDCF_VALID(config->tdcConfig->tdcFilterWindow));
482 
483                     /* Transmitter delay compensation */
484                     Cy_CANFD_SetTDC(base, chan, config->tdcConfig);
485                 }
486                 else
487                 {
488                    ret = CY_CANFD_BAD_PARAM;
489                 }
490             }
491 
492             if (ret != CY_CANFD_BAD_PARAM)
493             {
494                 /* The configuration of a global filter */
495                 CANFD_GFC(base, chan) =
496                 _VAL2FLD(CANFD_CH_M_TTCAN_GFC_ANFS, config->globalFilterConfig->nonMatchingFramesStandard) |
497                 _VAL2FLD(CANFD_CH_M_TTCAN_GFC_ANFE, config->globalFilterConfig->nonMatchingFramesExtended) |
498                 _VAL2FLD(CANFD_CH_M_TTCAN_GFC_RRFS, ((config->globalFilterConfig->rejectRemoteFramesStandard) ? 1UL : 0UL))|
499                 _VAL2FLD(CANFD_CH_M_TTCAN_GFC_RRFE, ((config->globalFilterConfig->rejectRemoteFramesExtended) ? 1UL : 0UL));
500 
501                 if (0U != config->sidFilterConfig->numberOfSIDFilters)
502                 {
503                     /* Standard Message ID filters */
504                     Cy_CANFD_SidFiltersSetup(base, chan, config->sidFilterConfig, context);
505                 }
506 
507                 if(0U   != config->extidFilterConfig->numberOfEXTIDFilters)
508                 {
509                     /* Extended Message ID filters */
510                     Cy_CANFD_XidFiltersSetup(base, chan,  config->extidFilterConfig, context);
511                 }
512 
513                 /* Configure the interrupt */
514                 Cy_CANFD_SetInterruptMask(base, chan, CY_CANFD_INTERRUPT_ENABLE_DEFAULT);
515 
516                 /* Enable TX complete interrupts for used TX buffers */
517                 CANFD_TXBTIE(base, chan) = (uint32_t)(~(0xFFFFFFFFUL << config->noOfTxBuffers));
518 
519                 /* Set interrupt line 0 */
520                 Cy_CANFD_SetInterruptLine(base, chan, 0UL);
521 
522                 /* Enable interrupt line 0 */
523                 Cy_CANFD_EnableInterruptLine(base, chan, CANFD_CH_M_TTCAN_ILE_EINT0_Msk);
524 
525                 /* Clear CCCR_INIT bit and wait until it is updated to finalize CAN FD initialization */
526                 ret = Cy_CANFD_ConfigChangesDisable(base, chan);
527             }
528         }
529         else
530         {
531            ret = CY_CANFD_ERROR_TIMEOUT;
532         }
533     }
534 
535     return ret;
536 }
537 
538 
539 /*******************************************************************************
540 * Function Name: Cy_CANFD_DeInit
541 ****************************************************************************//**
542 *
543 *  De-initializes the CAN FD block, returns registers values to default.
544 *
545 * \note Do not call Cy_CANFD_Disable before Cy_CANFD_DeInit.
546 * \note Call this function only after all debug messages reception is completed.
547 *
548 * \param *base
549 * The pointer to a CAN FD instance.
550 *
551 * \param chan
552 *  The CAN FD channel number.
553 *
554 * \param *context
555 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
556 * by the user. The structure is used during the CAN FD operation for internal
557 * configuration and data retention. The user must not modify anything
558 * in this structure.
559 *
560 * \return
561 * \ref cy_en_canfd_status_t
562 *
563 * \funcusage
564 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_DeInit
565 *
566 *******************************************************************************/
Cy_CANFD_DeInit(CANFD_Type * base,uint32_t chan,cy_stc_canfd_context_t * context)567 cy_en_canfd_status_t Cy_CANFD_DeInit(CANFD_Type *base, uint32_t chan, cy_stc_canfd_context_t *context)
568 {
569     volatile uint32_t* address;
570     uint32_t  retry = CY_CANFD_RETRY_COUNT;
571     uint32_t  count;
572     uint32_t  sizeInWord;
573     cy_en_canfd_status_t ret = CY_CANFD_ERROR_TIMEOUT;
574 
575     /* Reset the notification callback functions */
576     context->canFDInterruptHandling.canFDTxInterruptFunction = NULL;
577     context->canFDInterruptHandling.canFDRxInterruptFunction = NULL;
578     context->canFDInterruptHandling.canFDErrorInterruptFunction = NULL;
579 
580     /* Set the CCCR_INIT bit and wait until it is updated */
581     CANFD_CCCR(base, chan) = CANFD_CH_M_TTCAN_CCCR_INIT_Msk;
582 
583     while ((retry > 0UL) && !_FLD2BOOL(CANFD_CH_M_TTCAN_CCCR_INIT, CANFD_CCCR(base, chan)))
584     {
585         Cy_SysLib_DelayUs(CY_CANFD_INIT_TIMEOUT_US);
586         retry--;
587     }
588 
589     if (retry > 0UL)
590     {
591         /* Enable configuration changes */
592         CANFD_CCCR(base, chan) |= CANFD_CH_M_TTCAN_CCCR_CCE_Msk;
593 
594         /* Standard ID filter */
595         CANFD_SIDFC(base, chan) = 0UL;
596 
597         /* Extended ID filter */
598         CANFD_XIDFC(base, chan) = 0UL;
599 
600         /* Extended ID AND Mask */
601         CANFD_XIDAM(base, chan) = CANFD_CH_M_TTCAN_XIDAM_EIDM_Msk;
602 
603         /* Configuration of Rx Buffer and Rx FIFO */
604         CANFD_RXESC(base, chan) = 0UL;
605 
606         /* Rx FIFO 0 */
607         CANFD_RXF0C(base, chan) = 0UL;
608 
609         /* Rx FIFO 1 */
610         CANFD_RXF1C(base, chan) = 0UL;
611 
612         /* Rx FIFO Top pointer logic*/
613         CANFD_RXFTOP_CTL(base, chan) = 0UL;
614 
615         /* Rx buffer */
616         CANFD_RXBC(base, chan) = 0UL;
617 
618         /* Configuration of Tx Buffer and Tx FIFO/Queue */
619         CANFD_TXESC(base, chan) = 0UL;
620 
621         /* Tx FIFO/QUEUE (not used) */
622         CANFD_TXEFC(base, chan) = 0UL;
623 
624         /* Tx buffer */
625         CANFD_TXBC(base, chan) = 0UL;
626 
627         /* Initialize the Message RAM area (Entire region zeroing) for the channel */
628         address = (volatile uint32_t *)(context->messageRAMaddress);
629         sizeInWord = context->messageRAMsize >> CY_CANFD_MRAM_SIGNIFICANT_BYTES_SHIFT;
630         for(count = 0UL; count < sizeInWord; count++)
631         {
632             address[count] = 0UL;
633         }
634 
635         /* The configuration of the CAN bus */
636 
637         /* Keep the initialization and configuration change enabled */
638         CANFD_CCCR(base, chan) = CANFD_CH_M_TTCAN_CCCR_INIT_Msk | CANFD_CH_M_TTCAN_CCCR_CCE_Msk;
639 
640         /* Set the nominal bit timing & prescaler register to the default value */
641         CANFD_NBTP(base, chan) = CANFD_NBTP_DEF_VAL;
642 
643         /* Set the data bit timing & prescaler register to the default value */
644         CANFD_DBTP(base, chan) = CANFD_DBTP_DEF_VAL;
645 
646         /* Transmitter delay compensation */
647         CANFD_TDCR(base, chan) = 0UL;
648 
649         /* The configuration of a global filter */
650         CANFD_GFC(base, chan) = 0UL;
651 
652         /* Enable interrupt configuration */
653         CANFD_IE(base, chan) = 0UL;
654 
655         /* Select interrupt line configuration */
656         CANFD_ILS(base, chan) = 0UL;
657 
658         /* Enable the interrupt line configuration */
659         CANFD_ILE(base, chan) = 0UL;
660 
661         ret = CY_CANFD_SUCCESS;
662     }
663 
664     return ret;
665 }
666 
667 
668 /*******************************************************************************
669 * Function Name: Cy_CANFD_GetLastError
670 ****************************************************************************//**
671 *
672 *  Returns the value of Protocol Status Register (PSR). \n
673 *  Use the \ref group_canfd_last_state_masks to extract necessary fields from
674 *  the register. \n
675 *  Use the \ref cy_en_canfd_LEC_t enumeration to interpret LEC and DLEC fields. \n
676 *  Use the \ref cy_en_canfd_PSR_ACT_t enumeration to interpret the  ACT field.
677 *
678 * \note Protocol Status Register has reset on read fields. Reading the register
679 *  will clear the bits PXE, RFDF, RBRS and RESI, and set DLEC[2:0] and LEC[2:0].
680 *
681 *
682 * \param *base
683 * The pointer to a CAN FD instance.
684 *
685 * \param chan
686 *  The CAN FD channel number.
687 *
688 * \return
689 *  Content of the Protocol Status Register (PSR).
690 *
691 *******************************************************************************/
Cy_CANFD_GetLastError(CANFD_Type const * base,uint32_t chan)692 uint32_t Cy_CANFD_GetLastError(CANFD_Type const *base, uint32_t chan)
693 {
694     return CANFD_PSR(base, chan);
695 }
696 
697 
698 /*******************************************************************************
699 * Function Name: Cy_CANFD_CalcRxBufAdrs
700 ****************************************************************************//**
701 *
702 *  Calculates the address of the RX buffer element.
703 *
704 * \param *base
705 * The pointer to a CAN FD instance.
706 *
707 * \param chan
708 * The CAN FD channel number.
709 *
710 * \param index
711 * The message buffer index for reception (0-63).
712 *
713 * \param context
714 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
715 * by the user. The structure is used during the CAN FD operation for internal
716 * configuration and data retention. The user must not modify anything
717 * in this structure.
718 *
719 * \return
720 * The message buffer address corresponding to the index. Can be 0 if the index
721 * is invalid.
722 *
723 * \funcusage
724 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_GetRxBuffer
725 *
726 *******************************************************************************/
Cy_CANFD_CalcRxBufAdrs(CANFD_Type const * base,uint32_t chan,uint32_t index,cy_stc_canfd_context_t const * context)727 uint32_t  Cy_CANFD_CalcRxBufAdrs(CANFD_Type const *base, uint32_t chan,
728                                 uint32_t index,
729                                 cy_stc_canfd_context_t const *context)
730 {
731     uint32_t address;
732 
733     (void)context;
734 
735     if (index > (CY_CANFD_MESSAGE_RX_BUFFERS_MAX_CNT - 1UL))
736     {
737         /* Sets 0 to the return value if the index is invalid */
738         address = 0UL;
739     }
740     else
741     {
742         /* Sets the message buffer address to the return value if the index is available  */
743         address = (uint32_t)base + CY_CANFD_MRAM_START_OFFSET;
744         address += (_FLD2VAL(CANFD_CH_M_TTCAN_RXBC_RBSA, CANFD_RXBC(base, chan))
745                      * sizeof(uint32_t));  /* Convert the word to the byte offset */
746         address += index * (CY_CANFD_R0_R1_SIZE +
747                             dataBufferSizeInWord[_FLD2VAL(CANFD_CH_M_TTCAN_RXESC_RBDS, CANFD_RXESC(base, chan))])*
748                             sizeof(uint32_t);   /* Convert the word to the byte offset */
749     }
750     return address;
751 }
752 
753 
754 /*******************************************************************************
755 * Function Name: Cy_CANFD_CalcTxBufAdrs
756 ****************************************************************************//**
757 *
758 *  Calculates the address of the TX buffer element.
759 *
760 * \param *base
761 * The pointer to a CAN FD instance.
762 *
763 * \param chan
764 * The CAN FD channel number.
765 *
766 * \param index
767 * The Message buffer index for the transmission (0-31).
768 *
769 * \param context
770 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
771 * by the user. The structure is used during the CAN FD operation for internal
772 * configuration and data retention. The user must not modify anything
773 * in this structure.
774 *
775 * \return
776 * The Message buffer address corresponding to the index.
777 * Can be 0 if the index is invalid.
778 *
779 *******************************************************************************/
Cy_CANFD_CalcTxBufAdrs(CANFD_Type const * base,uint32_t chan,uint32_t index,cy_stc_canfd_context_t const * context)780 static uint32_t Cy_CANFD_CalcTxBufAdrs(CANFD_Type const *base, uint32_t chan, uint32_t index, cy_stc_canfd_context_t const *context)
781 {
782     uint32_t address = 0UL;
783 
784     (void)context;
785 
786     /* Set the message buffer address to the return value if the index is available */
787     address = (uint32_t)base + CY_CANFD_MRAM_START_OFFSET;
788     address += (_FLD2VAL(CANFD_CH_M_TTCAN_TXBC_TBSA, CANFD_TXBC(base, chan))  /* Tx 32-bit Start Address */
789                 * sizeof(uint32_t));  /* Convert the word to the byte offset */
790 
791     if (index < (CY_CANFD_MESSAGE_TX_BUFFERS_MAX_CNT))
792     {
793         address += index * (CY_CANFD_T0_T1_SIZE +
794                             dataBufferSizeInWord[_FLD2VAL(CANFD_CH_M_TTCAN_TXESC_TBDS, CANFD_TXESC(base, chan))]) *
795                             sizeof(uint32_t);   /* Converts the word to the byte offset */
796     }
797     else
798     {
799         address = 0UL;
800     }
801 
802     return address;
803 }
804 
805 
806 /*******************************************************************************
807 * Function Name: Cy_CANFD_CalcRxFifoAdrs
808 ****************************************************************************//**
809 *
810 *  Calculates the address of the RX FIFO element.
811 *
812 * \param *base
813 * The pointer to a CAN FD instance.
814 *
815 * \param chan
816 * The CAN FD channel number.
817 *
818 * \param fifoNumber
819 * The FIFO number (0 or 1).
820 *
821 * \param index
822 * The Message buffer index for the reception (0-63).
823 *
824 * \param context
825 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
826 * by the user. The structure is used during the CAN FD operation for internal
827 * configuration and data retention. The user must not modify anything
828 * in this structure.
829 *
830 * \return
831 * The Message buffer address corresponding to the index.
832 * Can be 0 if the index is invalid.
833 *
834 * \funcusage
835 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_GetRxBuffer
836 *
837 *******************************************************************************/
Cy_CANFD_CalcRxFifoAdrs(CANFD_Type const * base,uint32_t chan,uint32_t fifoNumber,uint32_t index,cy_stc_canfd_context_t const * context)838 uint32_t Cy_CANFD_CalcRxFifoAdrs(CANFD_Type const *base, uint32_t chan,
839                                  uint32_t fifoNumber,
840                                  uint32_t index,
841                                  cy_stc_canfd_context_t const *context)
842 {
843     uint32_t address = 0UL;
844 
845     (void)context;
846 
847     CY_ASSERT_L2(CY_CANFD_IS_FIFO_NUM_VALID(index));
848     if(fifoNumber <= CY_CANFD_RX_FIFO1)
849     {
850         /* Sets the message buffer address to the return value if the index is available */
851         address = (uint32_t)base + CY_CANFD_MRAM_START_OFFSET;
852         address += (((CY_CANFD_RX_FIFO0 == fifoNumber) ?
853                      _FLD2VAL(CANFD_CH_M_TTCAN_RXF0C_F0SA, CANFD_RXF0C(base, chan)) :  /* Rx FIFO 0 32-bit Start Address */
854                      _FLD2VAL(CANFD_CH_M_TTCAN_RXF1C_F1SA, CANFD_RXF1C(base, chan)))   /* Rx FIFO 1 32-bit Start Address */
855                      * sizeof(uint32_t));  /* Convert the word to the byte offset */
856         address += index * (CY_CANFD_R0_R1_SIZE +
857                             dataBufferSizeInWord[(CY_CANFD_RX_FIFO0 == fifoNumber) ?
858                                                  _FLD2VAL(CANFD_CH_M_TTCAN_RXESC_F0DS, CANFD_RXESC(base, chan)) :
859                                                  _FLD2VAL(CANFD_CH_M_TTCAN_RXESC_F1DS, CANFD_RXESC(base, chan))]) *
860                            sizeof(uint32_t);   /* Converts the word to the byte offset */
861     }
862 
863     return address;
864 }
865 
866 
867 /*******************************************************************************
868 * Function Name: Cy_CANFD_SidFilterSetup
869 ****************************************************************************//**
870 *
871 * Updates the Standard Message ID Filter Element configuration in Message RAM.
872 *
873 * \param *base
874 * The pointer to a CAN FD instance.
875 *
876 * \param chan
877 * The CAN FD channel number.
878 *
879 * \param *filter
880 *  The SID Filter register element structure.
881 *
882 * \param index
883 *  The SID filter index.
884 *
885 * \param *context
886 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
887 * by the user. The structure is used during the CAN FD operation for internal
888 * configuration and data retention. The user must not modify anything
889 * in this structure.
890 *
891 * \funcusage
892 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_SidFilterSetup
893 *
894 *******************************************************************************/
Cy_CANFD_SidFilterSetup(CANFD_Type const * base,uint32_t chan,const cy_stc_id_filter_t * filter,uint32_t index,cy_stc_canfd_context_t const * context)895 void Cy_CANFD_SidFilterSetup(CANFD_Type const *base, uint32_t chan,
896                              const cy_stc_id_filter_t *filter,
897                              uint32_t index,
898                              cy_stc_canfd_context_t const *context)
899 {
900     uint32_t *filterAddr;
901 
902     (void)context;
903 
904     if ((NULL != filter) && (NULL != context))
905     {
906         CY_ASSERT_L2(CY_CANFD_IS_SFID_VALID(filter->sfid2));
907         CY_ASSERT_L2(CY_CANFD_IS_SFID_VALID(filter->sfid1));
908         CY_ASSERT_L3(CY_CANFD_IS_SFEC_VALID(filter->sfec));
909         CY_ASSERT_L3(CY_CANFD_IS_SFT_VALID(filter->sft));
910         CY_ASSERT_L2(CY_CANFD_IS_SID_FILTERS_VALID(index + 1U));
911 
912         /* The Standard Message ID Filter address */
913         filterAddr = (uint32_t *)((uint32_t)base + CY_CANFD_MRAM_START_OFFSET +
914                                    (_FLD2VAL(CANFD_CH_M_TTCAN_SIDFC_FLSSA, CANFD_SIDFC(base, chan))
915                                      << CY_CANFD_MRAM_SIGNIFICANT_BYTES_SHIFT));
916 
917         /* The Standard Message ID Filter element address */
918         filterAddr += index;
919 
920         /* Configuration of Rx Buffer and Rx FIFO */
921         *filterAddr = _VAL2FLD(CY_CANFD_SID_FILTER_S0_SFID2, filter->sfid2) | /* Standard Filter ID 2 */
922                       _VAL2FLD(CY_CANFD_SID_FILTER_S0_SFID1, filter->sfid1) | /* Standard Filter ID 1 */
923                       _VAL2FLD(CY_CANFD_SID_FILTER_S0_SFEC , filter->sfec)  | /* Standard Filter Element Configuration*/
924                       _VAL2FLD(CY_CANFD_SID_FILTER_S0_SFT, filter->sft);      /* Standard Filter Type */
925     }
926 }
927 
928 
929 /*******************************************************************************
930 * Function Name: Cy_CANFD_SidFiltersSetup
931 ****************************************************************************//**
932 *
933 *  Updates the Standard Message ID Filters configuration in Message RAM.
934 *
935 * \param *base
936 * The pointer to a CAN FD instance.
937 *
938 * \param chan
939 *  The CAN FD channel number.
940 *
941 * \param filterConfig
942 *  The Standard ID filter configuration structure.
943 *
944 * \param context
945 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
946 * by the user. The structure is used during the CAN FD operation for internal
947 * configuration and data retention. The user must not modify anything
948 * in this structure.
949 *
950 *******************************************************************************/
Cy_CANFD_SidFiltersSetup(CANFD_Type const * base,uint32_t chan,const cy_stc_canfd_sid_filter_config_t * filterConfig,cy_stc_canfd_context_t const * context)951 void Cy_CANFD_SidFiltersSetup(CANFD_Type const *base, uint32_t chan,
952                               const cy_stc_canfd_sid_filter_config_t *filterConfig,
953                               cy_stc_canfd_context_t const *context)
954 {
955     uint32_t index;
956 
957     if ((NULL != filterConfig) && (NULL != context))
958     {
959         CY_ASSERT_L2(CY_CANFD_IS_SID_FILTERS_VALID(filterConfig->numberOfSIDFilters));
960 
961         for (index = 0UL; index < filterConfig->numberOfSIDFilters; index++)
962         {
963             Cy_CANFD_SidFilterSetup(base, chan, (filterConfig->sidFilter + index), index, context);
964         }
965     }
966 }
967 
968 
969 /*******************************************************************************
970 * Function Name: Cy_CANFD_XidFilterSetup
971 ****************************************************************************//**
972 *
973 *  Updates the Extended Message ID Filter Element configuration in Message RAM.
974 *
975 * \param *base
976 * The pointer to a CAN FD instance.
977 *
978 * \param chan
979 * The CAN FD channel number.
980 *
981 * \param filter
982 * The XID Filter register element structure.
983 *
984 * \param index
985 *     The XID filter index.
986 *
987 * \param context
988 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
989 * by the user. The structure is used during the CAN FD operation for internal
990 * configuration and data retention. The user must not modify anything
991 * in this structure.
992 *
993 * \funcusage
994 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_XidFilterSetup
995 *
996 *******************************************************************************/
Cy_CANFD_XidFilterSetup(CANFD_Type const * base,uint32_t chan,const cy_stc_extid_filter_t * filter,uint32_t index,cy_stc_canfd_context_t const * context)997 void Cy_CANFD_XidFilterSetup(CANFD_Type const *base, uint32_t chan,
998                              const cy_stc_extid_filter_t *filter,
999                              uint32_t index,
1000                              cy_stc_canfd_context_t const *context)
1001 {
1002     uint32_t* filterAddr;
1003 
1004     (void)context;
1005 
1006     if ((NULL != filter) && (NULL != context))
1007     {
1008         CY_ASSERT_L2(CY_CANFD_IS_EFID_VALID(filter->f1_f->efid2));
1009         CY_ASSERT_L2(CY_CANFD_IS_EFID_VALID(filter->f0_f->efid1));
1010         CY_ASSERT_L3(CY_CANFD_IS_EFEC_VALID(filter->f0_f->efec));
1011         CY_ASSERT_L3(CY_CANFD_IS_EFT_VALID(filter->f1_f->eft));
1012         CY_ASSERT_L2(CY_CANFD_IS_XID_FILTERS_VALID(index + 1U));
1013 
1014         /* The Extended Message ID Filter address */
1015         filterAddr = (uint32_t *)((uint32_t)base + CY_CANFD_MRAM_START_OFFSET +
1016                                 (_FLD2VAL(CANFD_CH_M_TTCAN_XIDFC_FLESA, CANFD_XIDFC(base, chan))
1017                                   << CY_CANFD_MRAM_SIGNIFICANT_BYTES_SHIFT));
1018 
1019         /* The Extended Message ID Filter element address */
1020         filterAddr += (index << 1U);  /* The shift to 1 defines F0 and F1 fields */
1021 
1022         /* Configuration of F0 for the Rx Buffer and Rx FIFO filter element */
1023         *filterAddr = _VAL2FLD(CY_CANFD_XID_FILTER_F0_EFID1, filter->f0_f->efid1) | /* XID Filter ID 1 */
1024                       _VAL2FLD(CY_CANFD_XID_FILTER_F0_EFEC, filter->f0_f->efec); /* XID Filter Element Configuration */
1025 
1026         /* Increment the address to get the address for F1 */
1027         filterAddr++;
1028 
1029         /* Configuration of F1 for the Rx Buffer and Rx FIFO filter element */
1030         *filterAddr = _VAL2FLD(CY_CANFD_XID_FILTER_F1_EFID2, filter->f1_f->efid2) | /* XID Filter ID 2 */
1031                       _VAL2FLD(CY_CANFD_XID_FILTER_F1_ETF, filter->f1_f->eft);     /* XID Filter Type */
1032     }
1033 }
1034 
1035 
1036 /*******************************************************************************
1037 * Function Name: Cy_CANFD_XidFiltersSetup
1038 ****************************************************************************//**
1039 *
1040 *  Updates the Extended Message ID Filters configuration in Message RAM.
1041 *
1042 * \param *base
1043 * The pointer to a CAN FD instance.
1044 *
1045 * \param chan
1046 * The CAN FD channel number.
1047 *
1048 * \param filterConfig
1049 * The Extended ID filter configuration structure.
1050 *
1051 * \param context
1052 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
1053 * by the user. The structure is used during the CAN FD operation for internal
1054 * configuration and data retention. The user must not modify anything
1055 * in this structure.
1056 *
1057 *******************************************************************************/
Cy_CANFD_XidFiltersSetup(CANFD_Type const * base,uint32_t chan,const cy_stc_canfd_extid_filter_config_t * filterConfig,cy_stc_canfd_context_t const * context)1058 void Cy_CANFD_XidFiltersSetup(CANFD_Type const *base, uint32_t chan,
1059                               const cy_stc_canfd_extid_filter_config_t *filterConfig,
1060                               cy_stc_canfd_context_t const *context)
1061 {
1062     uint32_t index;
1063 
1064     if ((NULL != filterConfig) && (NULL != context))
1065     {
1066         CY_ASSERT_L2(CY_CANFD_IS_XID_FILTERS_VALID(filterConfig->numberOfEXTIDFilters));
1067 
1068         for (index = 0UL; index < filterConfig->numberOfEXTIDFilters; index++)
1069         {
1070             Cy_CANFD_XidFilterSetup(base, chan, (filterConfig->extidFilter + index), index, context);
1071         }
1072     }
1073 }
1074 
1075 
1076 /*******************************************************************************
1077 * Function Name: Cy_CANFD_GetRxBuffer
1078 ****************************************************************************//**
1079 *
1080 * Extracts the RX Buffer from Message RAM.
1081 *
1082 * \note Remember to clear the NDAT register bits after the RX buffer is read.
1083 * \note Remember to acknowledge the FIFO buffer after reading one FIFO element.
1084 *
1085 * \param *base
1086 * The pointer to a CAN FD instance.
1087 *
1088 * \param chan
1089 * The CAN FD channel number.
1090 *
1091 * \param bufferAddress
1092 *  The Rx, FIFO 0 or FIFO 1 Buffer element address in CAN Message RAM.
1093 *
1094 * \param *rxBuffer
1095 *  The Rx Buffer structure in RAM.
1096 *
1097 * \return
1098 * \ref cy_en_canfd_status_t
1099 *
1100 * \funcusage
1101 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_GetRxBuffer
1102 *
1103 *******************************************************************************/
Cy_CANFD_GetRxBuffer(CANFD_Type const * base,uint32_t chan,const uint32_t bufferAddress,cy_stc_canfd_rx_buffer_t const * rxBuffer)1104 cy_en_canfd_status_t Cy_CANFD_GetRxBuffer(CANFD_Type const *base, uint32_t chan,
1105                                           const uint32_t bufferAddress,
1106                                           cy_stc_canfd_rx_buffer_t const *rxBuffer)
1107 {
1108     cy_en_canfd_status_t ret = CY_CANFD_BAD_PARAM;
1109     volatile const uint32_t* address = (uint32_t*)bufferAddress;
1110     uint32_t count    = 0UL;
1111     uint32_t dlcIndex = 0UL;
1112 
1113     (void)base; /* Suppress warning */
1114     (void)chan; /* Suppress warning */
1115 
1116     /* Checks for the NULL pointers */
1117     if (NULL != rxBuffer)
1118     {
1119         if ((NULL != rxBuffer->r0_f) && (NULL != rxBuffer->r1_f) &&
1120             (NULL != rxBuffer->data_area_f))
1121         {
1122             rxBuffer->r0_f->id = _FLD2VAL(CY_CANFD_RX_BUFFER_R0_ID, *address);
1123             rxBuffer->r0_f->rtr = (cy_en_canfd_rtr_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R0_RTR, *address));
1124             rxBuffer->r0_f->xtd = (cy_en_canfd_xtd_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R0_XTD, *address));
1125             rxBuffer->r0_f->esi = (cy_en_canfd_esi_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R0_ESI, *address));
1126 
1127             address++;
1128             rxBuffer->r1_f->rxts = _FLD2VAL(CY_CANFD_RX_BUFFER_R1_RXTS, *address);
1129             rxBuffer->r1_f->dlc = _FLD2VAL(CY_CANFD_RX_BUFFER_R1_DLC, *address);
1130             rxBuffer->r1_f->brs = _FLD2BOOL(CY_CANFD_RX_BUFFER_R1_BRS, *address);
1131             rxBuffer->r1_f->fdf = (cy_en_canfd_fdf_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R1_FDF, *address));
1132             rxBuffer->r1_f->fidx = _FLD2VAL(CY_CANFD_RX_BUFFER_R1_FIDX, *address);
1133             rxBuffer->r1_f->anmf = (cy_en_canfd_anmf_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R1_ANMF, *address));
1134 
1135             /* ID : Shifts a standard RxID to its position */
1136             if (rxBuffer->r0_f->xtd == CY_CANFD_XTD_STANDARD_ID)
1137             {
1138                 rxBuffer->r0_f->id >>= CY_CANFD_EXT_IDENTIFIER_LENGTH;
1139             }
1140 
1141             /* Copies the 0-64 byte of the data area */
1142             if (rxBuffer->r1_f->dlc > CY_CANFD_CLASSIC_CAN_DATA_LENGTH)
1143             {
1144                 dlcIndex = (uint32_t)(rxBuffer->r1_f->dlc - CY_CANFD_CLASSIC_CAN_DATA_LENGTH);
1145             }
1146 
1147             for (count = 0UL; count < (uint32_t)dataBufferSizeInWord[dlcIndex]; count++)
1148             {
1149                 address++;
1150                 rxBuffer->data_area_f[count] = *address;
1151             }
1152 
1153             ret = CY_CANFD_SUCCESS;
1154         }
1155     }
1156 
1157     return ret;
1158 }
1159 
1160 
1161 /*******************************************************************************
1162 * Function Name: Cy_CANFD_GetFIFOTop
1163 ****************************************************************************//**
1164 *
1165 * Extracts one RX FIFO Buffer element using the FIFO TOP register logic.
1166 *
1167 * \param *base
1168 * The pointer to a CAN FD instance.
1169 *
1170 * \param chan
1171 * The CAN FD channel number.
1172 *
1173 * \param FIFONumber
1174 *  The CY_CANFD_RX_FIFO0 or CY_CANFD_RX_FIFO1, FIFO Buffer number.
1175 *
1176 * \param *rxBuffer
1177 *  The Rx Buffer structure in RAM.
1178 *
1179 * \return
1180 * \ref cy_en_canfd_status_t
1181 *
1182 * \funcusage
1183 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_GetFIFOTop
1184 *
1185 *******************************************************************************/
Cy_CANFD_GetFIFOTop(CANFD_Type const * base,uint32_t chan,const uint8_t FIFONumber,cy_stc_canfd_rx_buffer_t const * rxBuffer)1186 cy_en_canfd_status_t Cy_CANFD_GetFIFOTop(CANFD_Type const *base, uint32_t chan,
1187                                           const uint8_t FIFONumber,
1188                                           cy_stc_canfd_rx_buffer_t const *rxBuffer)
1189 {
1190     cy_en_canfd_status_t ret = CY_CANFD_BAD_PARAM;
1191     volatile const uint32_t* address;
1192     uint32_t count    = 0UL;
1193     uint32_t dataSize = 0UL;
1194     uint32_t tmpregister = 0UL;
1195 
1196     /* Checks for the NULL pointers */
1197     if (NULL != rxBuffer)
1198     {
1199         if ((NULL != rxBuffer->r0_f) && (NULL != rxBuffer->r1_f) &&
1200             (NULL != rxBuffer->data_area_f))
1201         {
1202             /* Selects a corresponding FIFO TOP address and FIFO element size */
1203             if (CY_CANFD_RX_FIFO0 == FIFONumber)
1204             {
1205                 address = (uint32_t*)&CANFD_RXFTOP0_DATA(base, chan);
1206                 dataSize = (uint32_t)dataBufferSizeInWord[_FLD2VAL(CANFD_CH_M_TTCAN_RXESC_F0DS,
1207                                                           CANFD_RXESC(base, chan))];
1208             }
1209             else
1210             {
1211                 address = (uint32_t*)&CANFD_RXFTOP1_DATA(base, chan);
1212                 dataSize = (uint32_t)dataBufferSizeInWord[_FLD2VAL(CANFD_CH_M_TTCAN_RXESC_F1DS,
1213                                                           CANFD_RXESC(base, chan))];
1214             }
1215 
1216             tmpregister = *address; /* The FIFO Read pointer is post-incremented by the HW */
1217             rxBuffer->r0_f->id = _FLD2VAL(CY_CANFD_RX_BUFFER_R0_ID, tmpregister);
1218             rxBuffer->r0_f->rtr = (cy_en_canfd_rtr_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R0_RTR, tmpregister));
1219             rxBuffer->r0_f->xtd = (cy_en_canfd_xtd_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R0_XTD, tmpregister));
1220             rxBuffer->r0_f->esi = (cy_en_canfd_esi_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R0_ESI, tmpregister));
1221 
1222             tmpregister = *address; /* The FIFO Read pointer is post-incremented by the HW */
1223             rxBuffer->r1_f->rxts = _FLD2VAL(CY_CANFD_RX_BUFFER_R1_RXTS, tmpregister);
1224             rxBuffer->r1_f->dlc = _FLD2VAL(CY_CANFD_RX_BUFFER_R1_DLC, tmpregister);
1225             rxBuffer->r1_f->brs = _FLD2BOOL(CY_CANFD_RX_BUFFER_R1_BRS, tmpregister);
1226             rxBuffer->r1_f->fdf = (cy_en_canfd_fdf_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R1_FDF, tmpregister));
1227             rxBuffer->r1_f->fidx = _FLD2VAL(CY_CANFD_RX_BUFFER_R1_FIDX, tmpregister);
1228             rxBuffer->r1_f->anmf = (cy_en_canfd_anmf_t)((uint32_t)_FLD2VAL(CY_CANFD_RX_BUFFER_R1_ANMF, tmpregister));
1229 
1230             /* ID : Shifts a standard RxID to its position */
1231             if (rxBuffer->r0_f->xtd == CY_CANFD_XTD_STANDARD_ID)
1232             {
1233                 rxBuffer->r0_f->id >>= CY_CANFD_EXT_IDENTIFIER_LENGTH;
1234             }
1235 
1236             /* Copies the whole data area of one FIFO element */
1237             for (count = 0UL; count < dataSize; count++)
1238             {
1239                 rxBuffer->data_area_f[count] = *address; /* The FIFO read pointer is post-incremented by the HW */
1240             }
1241 
1242             ret = CY_CANFD_SUCCESS;
1243         }
1244     }
1245 
1246     return ret;
1247 }
1248 
1249 
1250 /*******************************************************************************
1251 * Function Name: Cy_CANFD_ExtractMsgFromRXBuffer
1252 ****************************************************************************//**
1253 *
1254 * Extracts one RX buffer or one FIFO buffer element.
1255 *
1256 * \param *base
1257 * The pointer to a CAN FD instance.
1258 *
1259 * \param chan
1260 * The CAN FD channel number.
1261 *
1262 * \param rxFIFOMsg
1263 *  The buffer to read: True for FIFO buffers and False for RX buffers.
1264 *
1265 * \param msgBufOrRxFIFONum
1266 *  The RX buffer element index or FIFO buffer number.
1267 *
1268 * \param *rxBuffer
1269 *  The Rx buffer structure in RAM.
1270 *
1271 * \param context
1272 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
1273 * by the user. The structure is used during the CAN FD operation for internal
1274 * configuration and data retention. The user must not modify anything
1275 * in this structure.
1276 *
1277 * \return
1278 * \ref cy_en_canfd_status_t
1279 *
1280 * \funcusage
1281 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_ExtractMsgFromRXBuffer
1282 *
1283 *******************************************************************************/
Cy_CANFD_ExtractMsgFromRXBuffer(CANFD_Type * base,uint32_t chan,bool rxFIFOMsg,uint8_t msgBufOrRxFIFONum,cy_stc_canfd_rx_buffer_t const * rxBuffer,cy_stc_canfd_context_t const * context)1284 cy_en_canfd_status_t Cy_CANFD_ExtractMsgFromRXBuffer(CANFD_Type *base, uint32_t chan,
1285                                                      bool rxFIFOMsg, uint8_t msgBufOrRxFIFONum,
1286                                                      cy_stc_canfd_rx_buffer_t const *rxBuffer,
1287                                                      cy_stc_canfd_context_t const *context)
1288 {
1289     cy_en_canfd_status_t ret = CY_CANFD_BAD_PARAM;
1290     uint32_t address = 0UL;
1291     if (rxFIFOMsg)
1292     {
1293         /* Reading from the FIFO buffer */
1294         if (0U == msgBufOrRxFIFONum)
1295         {
1296             /* FIFO0 is used */
1297             if (_FLD2BOOL(CANFD_CH_RXFTOP_CTL_F0TPE, CANFD_RXFTOP_CTL(base, chan)))   /* The RxFifo Top pointer logic is used. */
1298             {
1299                 /* Gets data from the FIFO top register. The Read address is incremented by HW */
1300                 ret = Cy_CANFD_GetFIFOTop(base, chan, CY_CANFD_RX_FIFO0, rxBuffer);
1301 
1302             }
1303             else        /* The RxFifo Top pointer logic is not used */
1304             {
1305                 address = Cy_CANFD_CalcRxFifoAdrs(base, chan,
1306                                                   CY_CANFD_RX_FIFO0,
1307                                                   _FLD2VAL(CANFD_CH_M_TTCAN_RXF0S_F0GI, CANFD_RXF0S(base, chan)),
1308                                                   context);
1309 
1310                 if (0UL != address)
1311                 {
1312                     /* Extracts the received message from the buffer */
1313                     ret = Cy_CANFD_GetRxBuffer(base, chan, address, rxBuffer);
1314 
1315                     /* Acknowledges the FIFO message */
1316                     CANFD_RXF0A(base, chan) = _CLR_SET_FLD32U(CANFD_RXF0A(base, chan),
1317                                                         CANFD_CH_M_TTCAN_RXF0A_F0AI,
1318                                                         _FLD2VAL(CANFD_CH_M_TTCAN_RXF0S_F0GI, CANFD_RXF0S(base, chan)));
1319                 }
1320             }
1321         }
1322         else
1323         {
1324             /* FIFO1 is used */
1325             if (_FLD2BOOL(CANFD_CH_RXFTOP_CTL_F1TPE, CANFD_RXFTOP_CTL(base, chan)))  /* The RxFifo Top pointer logic is used. */
1326             {
1327                 /* Gets data from the FIFO top register. The Read address is incremented by the HW */
1328                 ret = Cy_CANFD_GetFIFOTop(base, chan, CY_CANFD_RX_FIFO1, rxBuffer);
1329             }
1330             else        /* The RxFifo Top pointer logic is not used */
1331             {
1332                 address = Cy_CANFD_CalcRxFifoAdrs(base, chan,
1333                                                   CY_CANFD_RX_FIFO1,
1334                                                   _FLD2VAL(CANFD_CH_M_TTCAN_RXF1S_F1GI, CANFD_RXF1S(base, chan)),
1335                                                   context);
1336 
1337                 if(0UL != address)
1338                 {
1339                     ret = Cy_CANFD_GetRxBuffer(base, chan, address, rxBuffer);
1340 
1341                     /* Acknowledges the FIFO message */
1342                     CANFD_RXF1A(base, chan) = _CLR_SET_FLD32U(CANFD_RXF1A(base, chan),
1343                                                         CANFD_CH_M_TTCAN_RXF1A_F1AI,
1344                                                         _FLD2VAL(CANFD_CH_M_TTCAN_RXF1S_F1GI, CANFD_RXF1S(base, chan)));
1345                 }
1346             }
1347         }
1348     }
1349     else
1350     {
1351         /* Reads from the dedicated RX buffer */
1352         address = Cy_CANFD_CalcRxBufAdrs(base, chan, msgBufOrRxFIFONum, context);
1353 
1354         if (0UL != address)
1355         {
1356             /* Extracts the received message from the buffer */
1357             ret = Cy_CANFD_GetRxBuffer(base, chan, address, rxBuffer);
1358 
1359             if (msgBufOrRxFIFONum < CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS)
1360             {
1361                 /* Clears the NDAT1 register */
1362                 CANFD_NDAT1(base, chan) = (1UL << (msgBufOrRxFIFONum));
1363             }
1364             else
1365             {
1366                 /* Clears the NDAT2 register */
1367                 CANFD_NDAT2(base, chan) = (1UL << (msgBufOrRxFIFONum - (CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS)));
1368             }
1369         }
1370     }
1371 
1372     return ret;
1373 }
1374 
1375 
1376 /*******************************************************************************
1377 * Function Name: Cy_CANFD_AckRxBuf
1378 ****************************************************************************//**
1379 *
1380 *  Acknowledges the data reading and makes the buffer element available for
1381 *  a next message.
1382 *
1383 * \param *base
1384 * The pointer to a CAN FD instance.
1385 *
1386 * \param chan
1387 *     The CAN FD channel number.
1388 *
1389 * \param bufNum
1390 *    The RX buffer element index.
1391 *
1392 * \funcusage
1393 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_GetRxBuffer
1394 *
1395 *******************************************************************************/
Cy_CANFD_AckRxBuf(CANFD_Type * base,uint32_t chan,uint32_t bufNum)1396 void Cy_CANFD_AckRxBuf(CANFD_Type *base, uint32_t chan, uint32_t bufNum)
1397 {
1398     CY_ASSERT_L2(CY_CANFD_IS_RX_BUF_NUM_VALID(bufNum));
1399     if (bufNum < CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS)
1400     {
1401         /* Clears the NDAT1 register */
1402         CANFD_NDAT1(base, chan) = (1UL << (bufNum));
1403     }
1404     else
1405     {
1406         /* Clears the NDAT2 register */
1407         CANFD_NDAT2(base, chan) = (1UL << (bufNum - (CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS)));
1408     }
1409 }
1410 
1411 
1412 /*******************************************************************************
1413 * Function Name: Cy_CANFD_AckRxFifo
1414 ****************************************************************************//**
1415 *
1416 *  Acknowledges the data reading and makes the buffer element available for
1417 *  a next message.
1418 * \note Do not use this function with Cy_CANFD_GetFIFOTop(). FIFO top logic
1419 *  takes care on updating the FIFO read pointer buffer with hardware.
1420 *
1421 * \param *base
1422 * The pointer to a CAN FD instance.
1423 *
1424 * \param chan
1425 *  The CAN FD channel number.
1426 *
1427 * \param FIFOnumber
1428 *  The RX buffer element index.
1429 *
1430 * \funcusage
1431 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_GetRxBuffer
1432 *
1433 *******************************************************************************/
Cy_CANFD_AckRxFifo(CANFD_Type * base,uint32_t chan,uint32_t FIFOnumber)1434 void Cy_CANFD_AckRxFifo(CANFD_Type *base, uint32_t chan, uint32_t FIFOnumber)
1435 {
1436     switch (FIFOnumber)
1437     {
1438         case CY_CANFD_RX_FIFO0:
1439             /* Acknowledges the FIFO message */
1440             CANFD_RXF0A(base, chan) = _CLR_SET_FLD32U(CANFD_RXF0A(base, chan),
1441                                                 CANFD_CH_M_TTCAN_RXF0A_F0AI,
1442                                                 _FLD2VAL(CANFD_CH_M_TTCAN_RXF0S_F0GI, CANFD_RXF0S(base, chan)));
1443             break;
1444         case CY_CANFD_RX_FIFO1:
1445             /* Acknowledges the FIFO message */
1446             CANFD_RXF1A(base, chan) = _CLR_SET_FLD32U(CANFD_RXF1A(base, chan),
1447                                                 CANFD_CH_M_TTCAN_RXF1A_F1AI,
1448                                                 _FLD2VAL(CANFD_CH_M_TTCAN_RXF1S_F1GI, CANFD_RXF1S(base, chan)));
1449             break;
1450         default:
1451             /* Invalid FIFO number */
1452             break;
1453     }
1454 }
1455 
1456 
1457 /*******************************************************************************
1458 * Function Name: Cy_CANFD_IrqHandler
1459 ****************************************************************************//**
1460 *
1461 *  CAN FD (Status/Error/Rx/Tx) interrupt ISR.
1462 *
1463 * \param *base
1464 * The pointer to a CAN FD instance.
1465 *
1466 * \param chan
1467 *     The CAN FD channel number.
1468 *
1469 * \param context
1470 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
1471 * by the user. The structure is used during the CAN FD operation for internal
1472 * configuration and data retention. The user must not modify anything
1473 * in this structure.
1474 *
1475 *******************************************************************************/
Cy_CANFD_IrqHandler(CANFD_Type * base,uint32_t chan,cy_stc_canfd_context_t const * context)1476 void Cy_CANFD_IrqHandler(CANFD_Type *base, uint32_t chan, cy_stc_canfd_context_t const *context)
1477 {
1478     uint32_t           address = 0UL;
1479     uint32_t           messageBufferNumber;
1480     uint32_t           rxData[CY_CANFD_DATA_ELEMENTS_MAX];
1481     cy_stc_canfd_r0_t  r0RxBuffer;
1482     cy_stc_canfd_r1_t  r1RxBuffer;
1483 
1484     cy_stc_canfd_rx_buffer_t rxBuffer =
1485     {
1486         /* .r0_f         */ &r0RxBuffer,
1487         /* .r1_f         */ &r1RxBuffer,
1488         /* .data_area_f  */ rxData
1489     };
1490 
1491     /* Other than a Tx/Rx interrupt occurred */
1492     if (0UL != (Cy_CANFD_GetInterruptStatus(base, chan) & CY_CANFD_ERRORS_MASK))
1493     {
1494         /* Calls the callback function if it was set previously */
1495         if (NULL != context->canFDInterruptHandling.canFDErrorInterruptFunction)
1496         {
1497             context->canFDInterruptHandling.canFDErrorInterruptFunction(Cy_CANFD_GetInterruptStatus(base, chan));
1498         }
1499         else
1500         {
1501             uint32_t status = Cy_CANFD_GetInterruptStatus(base, chan) & CY_CANFD_ERRORS_MASK;
1502             Cy_CANFD_ClearInterrupt(base, chan, status);
1503         }
1504     }
1505 
1506     /* At least one received message must be stored into the Rx Buffer */
1507     if (CANFD_CH_M_TTCAN_IR_DRX_Msk == (Cy_CANFD_GetInterruptStatus(base, chan) & CANFD_CH_M_TTCAN_IR_DRX_Msk))
1508     {
1509         /* Clears the Message stored to the Dedicated Rx Buffer flag */
1510         Cy_CANFD_ClearInterrupt(base, chan, CANFD_CH_M_TTCAN_IR_DRX_Msk);
1511 
1512         if (0UL != CANFD_NDAT1(base, chan))       /* Message buffers 0-31 */
1513         {
1514             for (messageBufferNumber = 0UL;
1515                  messageBufferNumber < (CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS);
1516                  messageBufferNumber++)
1517             {
1518                 if (0UL != (CANFD_NDAT1(base, chan) & (1UL << messageBufferNumber)))
1519                 {
1520                     /* Calculates the Rx Buffer address */
1521                     address = Cy_CANFD_CalcRxBufAdrs(base, chan, messageBufferNumber, context);
1522 
1523                     /* Clears the NDAT1 register */
1524                     CANFD_NDAT1(base, chan) = (1UL << messageBufferNumber);
1525 
1526                     break;
1527                 }
1528             }
1529         }
1530         else /* Message buffers 32-63 */
1531         {
1532             for (messageBufferNumber = CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS;
1533                  messageBufferNumber < (CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS + CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS);
1534                  messageBufferNumber++)
1535             {
1536                 if (0UL != (CANFD_NDAT2(base, chan) & (1UL << (messageBufferNumber - CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS))))
1537                 {
1538                     /* Calculates the Rx Buffer address */
1539                     address = Cy_CANFD_CalcRxBufAdrs(base, chan, messageBufferNumber, context);
1540 
1541                     /* Clears the NDAT2 register */
1542                     CANFD_NDAT2(base, chan) = (1UL << (messageBufferNumber - (CY_CANFD_MESSAGE_HALF_OF_RX_BUFFERS)));
1543 
1544                     break;
1545                 }
1546             }
1547         }
1548 
1549         if (0UL != address)
1550         {
1551             /* Extracts the received message from a buffer */
1552             (void)Cy_CANFD_GetRxBuffer(base, chan, address, &rxBuffer);
1553 
1554             /* After a CAN FD message is received, checks if there is a callback function */
1555             /* Calls the callback function if it was set previously */
1556             if (NULL != context->canFDInterruptHandling.canFDRxInterruptFunction)
1557             {
1558                 context->canFDInterruptHandling.canFDRxInterruptFunction(false, messageBufferNumber, &rxBuffer);
1559             }
1560         }
1561     }
1562     else if (CANFD_CH_M_TTCAN_IR_RF0N_Msk ==
1563              (Cy_CANFD_GetInterruptStatus(base, chan) & CANFD_CH_M_TTCAN_IR_RF0N_Msk)) /* New message stored into RxFIFO 0 */
1564     {
1565         /* Clears the new message interrupt flag */
1566         Cy_CANFD_ClearInterrupt(base, chan, CANFD_CH_M_TTCAN_IR_RF0N_Msk);
1567 
1568         while (_FLD2VAL(CANFD_CH_M_TTCAN_RXF0S_F0FL, CANFD_RXF0S(base, chan)) > 0UL)    /* Checks the Rx FIFO 0 fill level */
1569         {
1570             if (_FLD2BOOL(CANFD_CH_RXFTOP_CTL_F0TPE, CANFD_RXFTOP_CTL(base, chan)))   /* The RxFifo Top pointer logic is used */
1571             {
1572                 /* Gets data from the FIFO top register. The Read address is incremented by HW */
1573                 (void)Cy_CANFD_GetFIFOTop(base, chan, CY_CANFD_RX_FIFO0, &rxBuffer);
1574 
1575                 /* After a CAN FD message is received, checks if there is a callback function */
1576                 /* Calls the callback function if it was set previously */
1577                 if (NULL != context->canFDInterruptHandling.canFDRxInterruptFunction)
1578                 {
1579                     context->canFDInterruptHandling.canFDRxInterruptFunction(true, CY_CANFD_RX_FIFO0, &rxBuffer);
1580                 }
1581             }
1582             else        /* The RxFifo Top pointer logic is not used */
1583             {
1584                 address = Cy_CANFD_CalcRxFifoAdrs(base, chan,
1585                                                   CY_CANFD_RX_FIFO0,
1586                                                   _FLD2VAL(CANFD_CH_M_TTCAN_RXF0S_F0GI, CANFD_RXF0S(base, chan)),
1587                                                   context);
1588 
1589                 if (0UL != address)
1590                 {
1591                     /* Extracts the received message from a buffer */
1592                     (void)Cy_CANFD_GetRxBuffer(base, chan, address, &rxBuffer);
1593 
1594                     /* Acknowledges the FIFO message */
1595                     CANFD_RXF0A(base, chan) = _CLR_SET_FLD32U(CANFD_RXF0A(base, chan),
1596                                                         CANFD_CH_M_TTCAN_RXF0A_F0AI,
1597                                                         _FLD2VAL(CANFD_CH_M_TTCAN_RXF0S_F0GI, CANFD_RXF0S(base, chan)));
1598 
1599                     /* After a CAN FD message received, checks if there is a callback function */
1600                     /* Calls the callback function if it was set previously */
1601                     if (NULL != context->canFDInterruptHandling.canFDRxInterruptFunction)
1602                     {
1603                         context->canFDInterruptHandling.canFDRxInterruptFunction(true, CY_CANFD_RX_FIFO0, &rxBuffer);
1604                     }
1605                 }
1606             }
1607         }
1608     }
1609     else if (CANFD_CH_M_TTCAN_IR_RF1N_Msk ==
1610              (Cy_CANFD_GetInterruptStatus(base, chan) & CANFD_CH_M_TTCAN_IR_RF1N_Msk)) /* New message stored into RxFIFO 1 */
1611     {
1612         /* Clears the new message interrupt flag */
1613         Cy_CANFD_ClearInterrupt(base, chan, CANFD_CH_M_TTCAN_IR_RF1N_Msk);
1614         while (_FLD2VAL(CANFD_CH_M_TTCAN_RXF1S_F1FL, CANFD_RXF1S(base, chan)) > 0UL) /* Checks the Rx FIFO 1 fill level */
1615         {
1616             if (_FLD2BOOL(CANFD_CH_RXFTOP_CTL_F1TPE, CANFD_RXFTOP_CTL(base, chan)))  /* The RxFifo Top pointer logic is used */
1617             {
1618                 /* Gets data from the FIFO top register. The Read address is incremented by the HW */
1619                 (void)Cy_CANFD_GetFIFOTop(base, chan, CY_CANFD_RX_FIFO1, &rxBuffer);
1620 
1621                 /* After a CAN FD message is received, checks if there is a callback function */
1622                 /* Calls the callback function if it was set previously */
1623                 if (NULL != context->canFDInterruptHandling.canFDRxInterruptFunction)
1624                 {
1625                     context->canFDInterruptHandling.canFDRxInterruptFunction(true,
1626                                                                              CY_CANFD_RX_FIFO1,
1627                                                                              &rxBuffer);
1628                 }
1629             }
1630             else        /* The RxFifo Top pointer logic is not used */
1631             {
1632                 address = Cy_CANFD_CalcRxFifoAdrs(base, chan,
1633                                                   CY_CANFD_RX_FIFO1,
1634                                                   _FLD2VAL(CANFD_CH_M_TTCAN_RXF1S_F1GI, CANFD_RXF1S(base, chan)),
1635                                                   context);
1636 
1637                 if(0UL != address)
1638                 {
1639                     (void)Cy_CANFD_GetRxBuffer(base, chan, address, &rxBuffer);
1640 
1641                     /* Acknowledges the FIFO message */
1642                     CANFD_RXF1A(base, chan) = _CLR_SET_FLD32U(CANFD_RXF1A(base, chan),
1643                                                         CANFD_CH_M_TTCAN_RXF1A_F1AI,
1644                                                         _FLD2VAL(CANFD_CH_M_TTCAN_RXF1S_F1GI, CANFD_RXF1S(base, chan)));
1645 
1646                     /* After a CAN FD message is received, checks if there is a callback function */
1647                     /* Calls the callback function if it was set previously */
1648                     if (NULL != context->canFDInterruptHandling.canFDRxInterruptFunction)
1649                     {
1650                         context->canFDInterruptHandling.canFDRxInterruptFunction(true,
1651                                                                                  CY_CANFD_RX_FIFO1,
1652                                                                                  &rxBuffer);
1653                     }
1654                 }
1655             }
1656         }
1657     }
1658     else if (CANFD_CH_M_TTCAN_IR_TC_Msk ==
1659              (Cy_CANFD_GetInterruptStatus(base, chan) & CANFD_CH_M_TTCAN_IR_TC_Msk)) /* Transmission Completed */
1660     {
1661         /* The CAN FD message is successfully transmitted */
1662         /* Clears the Transmission completed flag */
1663         Cy_CANFD_ClearInterrupt(base, chan, CANFD_CH_M_TTCAN_IR_TC_Msk);
1664 
1665         /* Calls the callback function if it was set previously */
1666         if (NULL != context->canFDInterruptHandling.canFDTxInterruptFunction)
1667         {
1668             context->canFDInterruptHandling.canFDTxInterruptFunction();
1669         }
1670     }
1671     else
1672     {
1673         /* An unused event occurs. Skip it */
1674     }
1675 }
1676 
1677 
1678 /*******************************************************************************
1679 * Function Name: Cy_CANFD_TxBufferConfig
1680 ****************************************************************************//**
1681 *
1682 * Updates the T0 and T1 Tx buffer element parameters in Message RAM and copies
1683 * data from cy_stc_canfd_tx_buffer_t structure to Message RAM.
1684 * \note Function Cy_CANFD_Init() must be called before setting up an identifier
1685 *  and enabling this message buffer.
1686 *
1687 * \param *base
1688 * The pointer to a CAN FD instance.
1689 *
1690 * \param chan
1691 * The CAN FD channel number.
1692 *
1693 * \param *txBuffer
1694 * The Tx Buffer configuration structure.
1695 *
1696 * \param index
1697 * the message buffer index (0-31).
1698 *
1699 * \param context
1700 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
1701 * by the user. The structure is used during the CAN FD operation for internal
1702 * configuration and data retention. The user must not modify anything
1703 * in this structure.
1704 *
1705 * \return
1706 * \ref cy_en_canfd_status_t
1707 *
1708 * \funcusage
1709 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_TxBufferConfig
1710 *
1711 *******************************************************************************/
Cy_CANFD_TxBufferConfig(CANFD_Type const * base,uint32_t chan,const cy_stc_canfd_tx_buffer_t * txBuffer,uint8_t index,cy_stc_canfd_context_t const * context)1712 cy_en_canfd_status_t Cy_CANFD_TxBufferConfig(CANFD_Type const *base, uint32_t chan,
1713                                              const cy_stc_canfd_tx_buffer_t *txBuffer,
1714                                              uint8_t index,
1715                                              cy_stc_canfd_context_t const *context)
1716 {
1717     cy_en_canfd_status_t ret = CY_CANFD_BAD_PARAM;
1718     uint32_t* bufferAddress;
1719     uint32_t dlcIndex;
1720     uint32_t count;
1721     uint8_t  dataLengthWord;
1722 
1723     /* Check for NULL pointers */
1724     if ((NULL != context) && (NULL != txBuffer))
1725     {
1726         if((NULL != txBuffer->t0_f) && (NULL != txBuffer->t1_f))
1727         {
1728             CY_ASSERT_L2(CY_CANFD_IS_ID_VALID(txBuffer->t0_f->id));
1729             CY_ASSERT_L3(CY_CANFD_IS_RTR_VALID(txBuffer->t0_f->rtr));
1730             CY_ASSERT_L3(CY_CANFD_IS_XTD_VALID(txBuffer->t0_f->xtd));
1731             CY_ASSERT_L3(CY_CANFD_IS_ESI_VALID(txBuffer->t0_f->esi));
1732             CY_ASSERT_L2(CY_CANFD_IS_DLC_VALID(txBuffer->t1_f->dlc));
1733             CY_ASSERT_L3(CY_CANFD_IS_FDF_VALID(txBuffer->t1_f->fdf));
1734             CY_ASSERT_L2(CY_CANFD_IS_TX_BUFFER_MM_VALID(txBuffer->t1_f->mm));
1735             CY_ASSERT_L2(CY_CANFD_IS_MESSAGE_BUFFER_IDX_VALID(index));
1736 
1737             /* Get the Tx Buffer address (T0 element) */
1738             bufferAddress = (uint32_t *)Cy_CANFD_CalcTxBufAdrs(base, chan, index, context);
1739 
1740             /* Checks whether the CAN FD controller is not in the INIT state and Tx buffer is empty or not */
1741             if((!((_FLD2BOOL(CANFD_CH_M_TTCAN_CCCR_INIT, CANFD_CCCR(base, chan))) ||
1742                 (0UL != (CANFD_TXBRP(base, chan) & (1UL << index))))) &&
1743                 (NULL != bufferAddress))
1744             {
1745                 /* T0 Configuration */
1746                 *bufferAddress =
1747                 _VAL2FLD(CY_CANFD_TX_BUFFER_T0_ESI, txBuffer->t0_f->esi) | /* The error state indicator */
1748                 _VAL2FLD(CY_CANFD_TX_BUFFER_T0_XTD, txBuffer->t0_f->xtd) | /* The extended identifier */
1749                 _VAL2FLD(CY_CANFD_TX_BUFFER_T0_RTR, txBuffer->t0_f->rtr) | /* A remote transmission request */
1750                 _VAL2FLD(CY_CANFD_TX_BUFFER_T0_ID, ((CY_CANFD_XTD_STANDARD_ID == txBuffer->t0_f->xtd) ?
1751                         (txBuffer->t0_f->id
1752                         << CY_CANFD_EXT_IDENTIFIER_LENGTH) :   /* The 11-bit standard identifier */
1753                         txBuffer->t0_f->id));                    /* The 29-bit extended identifier */
1754 
1755                 /* The T1 element address of Tx Buffer*/
1756                 bufferAddress ++;
1757 
1758                 /* Configure T1 */
1759                 *bufferAddress = _VAL2FLD(CY_CANFD_TX_BUFFER_T1_MM, txBuffer->t1_f->mm) | /* The message marker */
1760                                 _BOOL2FLD(CY_CANFD_TX_BUFFER_T1_EFC, txBuffer->t1_f->efc) | /* Event FIFO control */
1761                                 _VAL2FLD(CY_CANFD_TX_BUFFER_T1_FDF, txBuffer->t1_f->fdf) | /* FD format */
1762                                 _BOOL2FLD(CY_CANFD_TX_BUFFER_T1_BRS, txBuffer->t1_f->brs) | /* Bit rate switching */
1763                                 _VAL2FLD(CY_CANFD_TX_BUFFER_T1_DLC, txBuffer->t1_f->dlc);  /* Data length code */
1764 
1765                 /* Convert the DLC to data byte word */
1766                 if (txBuffer->t1_f->dlc < CY_CANFD_CLASSIC_CAN_DATA_LENGTH)
1767                 {
1768                     dlcIndex = 0UL;
1769                 }
1770                 else
1771                 {
1772                     dlcIndex = (uint32_t)(txBuffer->t1_f->dlc - CY_CANFD_CLASSIC_CAN_DATA_LENGTH);
1773                 }
1774                 dataLengthWord = dataBufferSizeInWord[dlcIndex];
1775 
1776                 /* Data set */
1777                 bufferAddress++; /* The data area field address of Tx Buffer*/
1778                 if ((CY_CANFD_RTR_DATA_FRAME == txBuffer->t0_f->rtr) && (NULL != txBuffer->data_area_f))
1779                 {
1780                     for (count = 0UL; count < dataLengthWord; count++)
1781                     {
1782                         *bufferAddress = txBuffer->data_area_f[count];
1783                         bufferAddress++;
1784                     }
1785                 }
1786 
1787                 ret = CY_CANFD_SUCCESS;
1788             }
1789         }
1790     }
1791 
1792     return ret;
1793 }
1794 
1795 
1796 /*******************************************************************************
1797 * Function Name: Cy_CANFD_TransmitTxBuffer
1798 ****************************************************************************//**
1799 *
1800 * Starts transmission of the message prepared with Cy_CANFD_TxBufferConfig().
1801 * Transmits the message immediately.
1802 * Function CanFD_Init() must be called before setting up the identifier and enabling
1803 * this message buffer.
1804 *
1805 * \param *base
1806 * The pointer to a CAN FD instance.
1807 *
1808 * \param chan
1809 * The CAN FD channel number.
1810 *
1811 * \param index
1812 * Message buffer index (0-31).
1813 *
1814 *
1815 * \return \ref cy_en_canfd_status_t
1816 *
1817 * \funcusage
1818 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_TransmitTxBuffer
1819 *
1820 *******************************************************************************/
Cy_CANFD_TransmitTxBuffer(CANFD_Type * base,uint32_t chan,uint8_t index)1821 cy_en_canfd_status_t Cy_CANFD_TransmitTxBuffer(CANFD_Type *base, uint32_t chan,
1822                                                          uint8_t index)
1823 {
1824     cy_en_canfd_status_t ret = CY_CANFD_BAD_PARAM;
1825 
1826     CY_ASSERT_L2(CY_CANFD_IS_MESSAGE_BUFFER_IDX_VALID(index));
1827 
1828     /* Checks whether the CAN FD controller is not in the INIT state and Tx buffer is empty or not */
1829     if(!((_FLD2BOOL(CANFD_CH_M_TTCAN_CCCR_INIT, CANFD_CCCR(base, chan))) ||
1830          (0UL != (CANFD_TXBRP(base, chan) & (1UL << index)))))
1831     {
1832         CANFD_TXBAR(base, chan) = 1UL << index; /* Transmits the buffer add request */
1833 
1834         ret = CY_CANFD_SUCCESS;
1835     }
1836     return ret;
1837 }
1838 
1839 
1840 /*******************************************************************************
1841 * Function Name: Cy_CANFD_UpdateAndTransmitMsgBuffer
1842 ****************************************************************************//**
1843 *
1844 * Updates the T0 and T1 Tx buffer element parameters in Message RAM and copies
1845 * data from cy_stc_canfd_tx_buffer_t structure to Message RAM.
1846 * Transmits the message immediately.
1847 * Function CanFD_Init() must be called before setting up the identifier and enabling
1848 * this message buffer.
1849 *
1850 * \param *base
1851 * The pointer to a CAN FD instance.
1852 *
1853 * \param chan
1854 * The CAN FD channel number.
1855 *
1856 * \param *txBuffer
1857 * The Tx Buffer configuration structure.
1858 *
1859 * \param index
1860 * the message buffer index (0-31).
1861 *
1862 * \param context
1863 * The pointer to the context structure \ref cy_stc_canfd_context_t allocated
1864 * by the user. The structure is used during the CAN FD operation for internal
1865 * configuration and data retention. The user must not modify anything
1866 * in this structure.
1867 *
1868 * \return \ref cy_en_canfd_status_t
1869 *
1870 * \funcusage
1871 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_UpdateAndTransmitMsgBuffer
1872 *
1873 *******************************************************************************/
Cy_CANFD_UpdateAndTransmitMsgBuffer(CANFD_Type * base,uint32_t chan,const cy_stc_canfd_tx_buffer_t * txBuffer,uint8_t index,cy_stc_canfd_context_t const * context)1874 cy_en_canfd_status_t Cy_CANFD_UpdateAndTransmitMsgBuffer(CANFD_Type *base, uint32_t chan,
1875                                                          const cy_stc_canfd_tx_buffer_t *txBuffer,
1876                                                          uint8_t index,
1877                                                          cy_stc_canfd_context_t const *context)
1878 {
1879     cy_en_canfd_status_t ret = CY_CANFD_BAD_PARAM;
1880 
1881     ret = Cy_CANFD_TxBufferConfig(base, chan, txBuffer, index, context);
1882 
1883     if (CY_CANFD_SUCCESS == ret)
1884     {
1885         ret = Cy_CANFD_TransmitTxBuffer(base, chan, index);
1886     }
1887     return ret;
1888 }
1889 
1890 
1891 /*******************************************************************************
1892 * Function Name: Cy_CANFD_GetTxBufferStatus
1893 ****************************************************************************//**
1894 *
1895 *  Gets the status of the CAN FD Tx buffer.
1896 *
1897 * \param *base
1898 * The pointer to a CAN FD instance.
1899 *
1900 * \param chan
1901 * The CAN FD channel number.
1902 *
1903 * \param index
1904 * Message buffer index (0-31).
1905 *
1906 * \return \ref cy_en_canfd_status_t
1907 *
1908 * \funcusage
1909 * \snippet canfd/snippet/main.c snippet_Cy_CANFD_GetTxBufferStatus
1910 *
1911 *******************************************************************************/
Cy_CANFD_GetTxBufferStatus(CANFD_Type const * base,uint32_t chan,uint8_t index)1912 cy_en_canfd_tx_buffer_status_t Cy_CANFD_GetTxBufferStatus(CANFD_Type const *base, uint32_t chan, uint8_t index)
1913 {
1914     cy_en_canfd_tx_buffer_status_t enTxBufferStatus;
1915 
1916     CY_ASSERT_L2(CY_CANFD_IS_MESSAGE_BUFFER_IDX_VALID(index));
1917 
1918     /* Initializes return value */
1919     enTxBufferStatus = CY_CANFD_TX_BUFFER_IDLE;
1920 
1921     if(0UL != (CANFD_TXBRP(base, chan) & (1UL << index)))    /* Pending transmission request */
1922     {
1923         /* Checks if the cancel request was issued */
1924         if(0UL == (CANFD_TXBCR(base, chan) & (1UL << index)))
1925         {
1926             /* No cancellation request */
1927             enTxBufferStatus = CY_CANFD_TX_BUFFER_PENDING;
1928         }
1929         else
1930         {
1931             /* Cancel request issued */
1932             enTxBufferStatus = CY_CANFD_TX_BUFFER_CANCEL_REQUESTED;
1933         }
1934     }
1935     else if(0UL != (CANFD_TXBTO(base, chan) & (1UL << index))) /* Transmission occurred */
1936     {
1937         enTxBufferStatus = CY_CANFD_TX_BUFFER_TRANSMIT_OCCURRED;
1938     }
1939     else if(0UL != (CANFD_TXBCF(base, chan) & (1UL << index))) /* Cancellation finished */
1940     {
1941         enTxBufferStatus = CY_CANFD_TX_BUFFER_CANCEL_FINISHED;
1942     }
1943     else
1944     {
1945         /* Closing if-else-if sequence */
1946     }
1947 
1948     return enTxBufferStatus;
1949 }
1950 
1951 #if defined(__cplusplus)
1952 }
1953 #endif
1954 
1955 #endif /* CY_IP_MXTTCANFD */
1956 
1957 
1958 /* [] END OF FILE */
1959