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