1 /***************************************************************************//**
2 * \file cy_smif.c
3 * \version 2.100
4 *
5 * \brief
6 * This file provides the source code for the SMIF driver APIs.
7 *
8 * Note:
9 *
10 ********************************************************************************
11 * \copyright
12 * Copyright 2016-2022 Cypress Semiconductor Corporation
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27
28 #include "cy_device.h"
29
30 #if defined (CY_IP_MXSMIF) && (CY_IP_MXSMIF_VERSION <= 5)
31
32 #include "cy_smif.h"
33 #include "cy_sysclk.h"
34
35 #if defined(__cplusplus)
36 extern "C" {
37 #endif
38
39 /*******************************************************************************
40 * Function Name: Cy_SMIF_Init
41 ****************************************************************************//**
42 *
43 * This function initializes the SMIF block as a communication block. The user
44 * must ensure that the SMIF interrupt is disabled while this function
45 * is called. Enabling the interrupts can lead to triggering in the middle
46 * of the initialization operation, which can lead to erroneous initialization.
47 *
48 * As parameters, this function takes the SMIF register base address and a
49 * context structure along with the configuration needed for the SMIF block,
50 * stored in a config
51 *
52 * \param base
53 * Holds the base address of the SMIF block registers.
54 *
55 * \param config
56 * Passes a configuration structure that configures the SMIF block for operation.
57 *
58 * \param timeout
59 * A timeout in microseconds for blocking APIs in use.
60 *
61 * \param context
62 * Passes a configuration structure that contains the transfer parameters of the
63 * SMIF block.
64 *
65 * \note Make sure that the interrupts are initialized and disabled.
66 *
67 * \return
68 * - \ref CY_SMIF_BAD_PARAM
69 * - \ref CY_SMIF_SUCCESS
70 *
71 *******************************************************************************/
Cy_SMIF_Init(SMIF_Type * base,cy_stc_smif_config_t const * config,uint32_t timeout,cy_stc_smif_context_t * context)72 cy_en_smif_status_t Cy_SMIF_Init(SMIF_Type *base,
73 cy_stc_smif_config_t const *config,
74 uint32_t timeout,
75 cy_stc_smif_context_t *context)
76 {
77 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
78
79 if((NULL != base) && (NULL != config) && (NULL != context))
80 {
81 #if (CY_IP_MXSMIF_VERSION == 4)
82 if(config->enable_internal_dll != true)
83 {
84 /* Must enable the DLL or the SMIF doesn't work. */
85 return CY_SMIF_BAD_PARAM;
86 }
87 #endif
88
89 uint32_t smif_ctl_value = SMIF_CTL(base);
90
91 /* Copy the base address of the SMIF and the SMIF Device block
92 * registers to the context.
93 */
94 context->timeout = timeout;
95
96 /* Default initialization */
97 context->memReadyPollDelay = 0U;
98
99 #if(CY_IP_MXSMIF_VERSION>=2)
100 /* Default initialization */
101 context->preXIPDataRate = CY_SMIF_SDR;
102 #endif /* CY_IP_MXSMIF_VERSION */
103
104 /* SMIF is running already in XIP/ARB mode. Do not modify register configuration */
105 if (!((_FLD2VAL(SMIF_CTL_ENABLED, smif_ctl_value) == 1U) && (_FLD2VAL(SMIF_CTL_XIP_MODE, smif_ctl_value) == 1U)))
106 {
107 /* Configure the initial interrupt mask */
108 /* Disable the TR_TX_REQ and TR_RX_REQ interrupts */
109 Cy_SMIF_SetInterruptMask(base, Cy_SMIF_GetInterruptMask(base)
110 & ~(SMIF_INTR_TR_TX_REQ_Msk | SMIF_INTR_TR_RX_REQ_Msk));
111
112 /* Check config structure */
113 CY_ASSERT_L3(CY_SMIF_MODE_VALID(config->mode));
114 CY_ASSERT_L3(CY_SMIF_CLOCK_SEL_VALID(config->rxClockSel));
115 CY_ASSERT_L2(CY_SMIF_DESELECT_DELAY_VALID(config->deselectDelay));
116 CY_ASSERT_L3(CY_SMIF_BLOCK_EVENT_VALID(config->blockEvent));
117
118 /* Configure the SMIF interface */
119 SMIF_CTL(base) = (uint32_t)(_VAL2FLD(SMIF_CTL_XIP_MODE, config->mode) |
120 #if (CY_IP_MXSMIF_VERSION<=3)
121 _VAL2FLD(SMIF_CTL_CLOCK_IF_RX_SEL, config->rxClockSel) |
122 #endif /*(CY_IP_MXSMIF_VERSION<=3)*/
123 _VAL2FLD(SMIF_CTL_DESELECT_DELAY, config->deselectDelay) |
124 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
125 _VAL2FLD(SMIF_CTL_DELAY_TAP_ENABLED, config->delayTapEnable) |
126 _VAL2FLD(SMIF_CTL_DELAY_LINE_SEL, config->delayLineSelect) |
127 #endif /*((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))*/
128 _VAL2FLD(SMIF_CTL_BLOCK, config->blockEvent));
129
130 #if (CY_IP_MXSMIF_VERSION >=4)
131
132 /* These values are taken from the Register TRM
133 entry for SMIF_CORE_CTL2_DLL_SPEED_MODE. */
134 #if (CY_IP_MXSMIF_VERSION == 4)
135 const uint32_t PLL_FREQ_1 = 160U;
136 const uint32_t PLL_FREQ_2 = 180U;
137 const uint32_t PLL_FREQ_3 = 266U;
138 const uint32_t PLL_FREQ_4 = 333U;
139 #elif (CY_IP_MXSMIF_VERSION == 5)
140 const uint32_t PLL_FREQ_1 = 150U;
141 const uint32_t PLL_FREQ_2 = 192U;
142 const uint32_t PLL_FREQ_3 = 245U;
143 const uint32_t PLL_FREQ_4 = 313U;
144 #endif
145
146 if (config->enable_internal_dll)
147 {
148 /* Reset DLL Registers */
149 SMIF_CTL2(base) &= ~SMIF_CORE_CTL2_DLL_SPEED_MODE_Msk;
150 #if (CY_IP_MXSMIF_VERSION >= 5)
151 SMIF_CTL2(base) &= ~SMIF_CORE_CTL2_DLL_BYPASS_MODE_Msk;
152 SMIF_CTL2(base) &= ~SMIF_CORE_CTL2_DLL_OPENLOOP_ENABLE_Msk;
153
154 if ( config->inputFrequencyMHz <= 150U)
155 {
156 /* DLL runs in open loop mode */
157 SMIF_CTL2(base) |= _VAL2FLD(SMIF_CORE_CTL2_DLL_OPENLOOP_ENABLE, 1U);
158 SMIF_IDAC(base) = 0; /* Set max delay for accuracy */
159 }
160 else
161 #endif /* CY_IP_MXSMIF_VERSION >= 5 */
162 {
163 uint32_t dll_speed_mode = 0U;
164 if ((config->inputFrequencyMHz > PLL_FREQ_1) && (config->inputFrequencyMHz <= PLL_FREQ_2))
165 {
166 dll_speed_mode = 0U;
167 }
168 else if ((config->inputFrequencyMHz > PLL_FREQ_2) && (config->inputFrequencyMHz <= PLL_FREQ_3))
169 {
170 dll_speed_mode = 1U;
171 }
172 else if ((config->inputFrequencyMHz > PLL_FREQ_3) && (config->inputFrequencyMHz <= PLL_FREQ_4))
173 {
174 dll_speed_mode = 2U;
175 }
176 else
177 {
178 dll_speed_mode = 3U;
179 }
180 SMIF_CTL2(base) |= _VAL2FLD(SMIF_CORE_CTL2_DLL_SPEED_MODE, dll_speed_mode);
181 }
182 }
183 #if (CY_IP_MXSMIF_VERSION >=5)
184 else
185 {
186 /* Use DLL bypass mode, unavailable in SMIF v4 */
187 SMIF_CTL2(base) |= SMIF_CORE_CTL2_DLL_BYPASS_MODE_Msk;
188 }
189 #endif
190
191 /* Set RX Capture Mode */
192 SMIF_CTL2(base) &= ~SMIF_CORE_CTL2_RX_CAPTURE_MODE_Msk;
193 SMIF_CTL2(base) |= _VAL2FLD(SMIF_CORE_CTL2_RX_CAPTURE_MODE, (uint32_t)config->rx_capture_mode);
194
195 /* In case user is working with higher frequencies increase initial set up and hold delay */
196 SMIF_CTL(base) &= ~SMIF_CORE_CTL_SELECT_SETUP_DELAY_Msk;
197 SMIF_CTL(base) &= ~SMIF_CORE_CTL_SELECT_HOLD_DELAY_Msk;
198
199 if (config->inputFrequencyMHz >= 300U)
200 {
201 SMIF_CTL(base) |= _VAL2FLD(SMIF_CORE_CTL_SELECT_SETUP_DELAY, 2);
202 SMIF_CTL(base) |= _VAL2FLD(SMIF_CORE_CTL_SELECT_HOLD_DELAY, 2);
203 }
204 else
205 {
206 SMIF_CTL(base) |= _VAL2FLD(SMIF_CORE_CTL_SELECT_SETUP_DELAY, 1);
207 SMIF_CTL(base) |= _VAL2FLD(SMIF_CORE_CTL_SELECT_HOLD_DELAY, 1);
208 }
209 #endif /* (CY_IP_MXSMIF_VERSION >=4) */
210 }
211 result = CY_SMIF_SUCCESS;
212 }
213
214 return result;
215 }
216
217
218 /*******************************************************************************
219 * Function Name: Cy_SMIF_DeInit
220 ****************************************************************************//**
221 *
222 * This function de-initializes the SMIF block to default values.
223 *
224 * \param base
225 * Holds the base address of the SMIF block registers.
226 *
227 * \note The SMIF must be disabled before calling the function. Call
228 * \ref Cy_SMIF_Disable
229 *
230 *******************************************************************************/
Cy_SMIF_DeInit(SMIF_Type * base)231 void Cy_SMIF_DeInit(SMIF_Type *base)
232 {
233 uint32_t idx;
234
235 /* Configure the SMIF interface to default values.
236 * The default value is 0.
237 */
238 SMIF_CTL(base) = CY_SMIF_CTL_REG_DEFAULT;
239 #if (CY_IP_MXSMIF_VERSION>=4)
240 SMIF_CTL2(base) = CY_SMIF_CTL2_REG_DEFAULT;
241 #endif
242 SMIF_TX_DATA_FIFO_CTL(base) = 0U;
243 SMIF_RX_DATA_FIFO_CTL(base) = 0U;
244 SMIF_INTR_MASK(base) = 0U;
245
246 for(idx = 0UL; idx < SMIF_DEVICE_NR; idx++)
247 {
248 SMIF_DEVICE_IDX_CTL(base, idx) = 0U;
249 }
250 }
251
252
253 /*******************************************************************************
254 * Function Name: Cy_SMIF_SetMode
255 ****************************************************************************//**
256 *
257 * Sets the mode of operation for the SMIF. The mode of operation can be the XIP
258 * mode where the slave devices are mapped as memories and are directly accessed
259 * from the PSoC register map. In the MMIO mode, the SMIF block acts as a simple
260 * SPI engine. MMIO mode and XIP modes are mutually exclusive. SMIF IP Version 3
261 * and above support MMIO mode transactions even when XIP mode is enabled. However,
262 * user has to ensure that XIP transaction is not issued during an ongoing MMIO
263 * transaction. Rather wait for MMIO transaction to complete since few MMIO operations
264 * make external flash busy and it cannot respond to XIP read transaction.
265 *
266 * \note With SMIF V1 IP, Interrupt and triggers are not working in XIP mode, see TRM for details
267 *
268 * \param base
269 * Holds the base address of the SMIF block registers.
270 *
271 * \param mode
272 * The mode of the SMIF operation.
273 *
274 *******************************************************************************/
Cy_SMIF_SetMode(SMIF_Type * base,cy_en_smif_mode_t mode)275 void Cy_SMIF_SetMode(SMIF_Type *base, cy_en_smif_mode_t mode)
276 {
277 CY_ASSERT_L3(CY_SMIF_MODE_VALID(mode));
278
279 /* Set the register SMIF.CTL.XIP_MODE = TRUE */
280 if (CY_SMIF_NORMAL == mode)
281 {
282 SMIF_CTL(base) &= ~ SMIF_CTL_XIP_MODE_Msk;
283 }
284 else
285 {
286 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
287 uint32_t read_cmd_data_ctl;
288 uint8_t idx;
289
290 /* Context variable is not available in this API. To make the API backward compatible
291 * we search if any of the device uses XIP and pick the data rate from that device.
292 * Multiple devices supporting XIP mode is not supported with the version of driver.
293 */
294
295 for(idx = 0U; idx < SMIF_DEVICE_NR; idx++)
296 {
297 read_cmd_data_ctl = SMIF_DEVICE_IDX_RD_DATA_CTL(base, idx);
298
299 if ((read_cmd_data_ctl & SMIF_DEVICE_RD_DATA_CTL_DDR_MODE_Msk) != 0UL)
300 {
301 uint32_t temp;
302 /* Select TX Clock mode SDR/DDR */
303 temp = SMIF_CTL(base);
304 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
305 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, CY_SMIF_DDR);
306 break;
307 }
308 }
309 #endif /* CY_IP_MXSMIF_VERSION */
310 SMIF_CTL(base) |= SMIF_CTL_XIP_MODE_Msk;
311 }
312 }
313
314
315 /*******************************************************************************
316 * Function Name: Cy_SMIF_GetMode
317 ****************************************************************************//**
318 *
319 * Reads the mode of operation for the SMIF. The mode of operation can be the
320 * XIP mode where the slave devices are mapped as memories and are directly
321 * accessed from the PSoC register map. In the MMIO mode, the SMIF block acts as
322 * a simple SPI engine.
323 *
324 * \param base
325 * Holds the base address of the SMIF block registers.
326 *
327 * \return The mode of SMIF operation (see \ref cy_en_smif_mode_t).
328 *
329 *******************************************************************************/
Cy_SMIF_GetMode(SMIF_Type const * base)330 cy_en_smif_mode_t Cy_SMIF_GetMode(SMIF_Type const *base)
331 {
332 cy_en_smif_mode_t result = CY_SMIF_NORMAL;
333
334 /* Read the register SMIF.CTL.XIP_MODE */
335 if (0U != (SMIF_CTL(base) & SMIF_CTL_XIP_MODE_Msk))
336 {
337 result = CY_SMIF_MEMORY;
338 }
339
340 return (result);
341 }
342
343
344 /*******************************************************************************
345 * Function Name: Cy_SMIF_SetDataSelect
346 ****************************************************************************//**
347 *
348 * This function configures the data select option for a specific slave. The
349 * selection provides pre-set combinations for connecting the SMIF data lines to
350 * the GPIOs.
351 *
352 * \param base
353 * Holds the base address of the SMIF block registers.
354 *
355 * \param slaveSelect
356 * The slave device ID. This number is either CY_SMIF_SLAVE_SELECT_0 or
357 * CY_SMIF_SLAVE_SELECT_1 or CY_SMIF_SLAVE_SELECT_2 or CY_SMIF_SLAVE_SELECT_3
358 * (\ref cy_en_smif_slave_select_t). It defines the slave select line to be used
359 * during the transmission.
360 *
361 * \param dataSelect
362 * This parameter selects the data select option. \ref cy_en_smif_data_select_t
363 *
364 *******************************************************************************/
Cy_SMIF_SetDataSelect(SMIF_Type * base,cy_en_smif_slave_select_t slaveSelect,cy_en_smif_data_select_t dataSelect)365 void Cy_SMIF_SetDataSelect(SMIF_Type *base, cy_en_smif_slave_select_t slaveSelect,
366 cy_en_smif_data_select_t dataSelect)
367 {
368 SMIF_DEVICE_Type volatile *device;
369
370 CY_ASSERT_L3(CY_SMIF_SLAVE_SEL_VALID(slaveSelect));
371 CY_ASSERT_L3(CY_SMIF_DATA_SEL_VALID(dataSelect));
372
373 /* Connect the slave to its data lines */
374 device = Cy_SMIF_GetDeviceBySlot(base, slaveSelect);
375
376 if(NULL != device)
377 {
378 SMIF_DEVICE_CTL(device) = _CLR_SET_FLD32U(SMIF_DEVICE_CTL(device),
379 SMIF_DEVICE_CTL_DATA_SEL,
380 (uint32_t)dataSelect);
381 }
382 }
383
384
385 /*******************************************************************************
386 * Function Name: Cy_SMIF_TransmitCommand()
387 ****************************************************************************//**
388 *
389 * This function transmits a command byte followed by a parameter which is
390 * typically an address field. The transfer is implemented using the TX FIFO.
391 * This function also asserts the slave select line.
392 * A command to a memory device generally starts with a command byte
393 * transmission. This function sets up the slave lines for the rest of the
394 * command structure. The \ref Cy_SMIF_TransmitCommand is called before \ref
395 * Cy_SMIF_TransmitData or \ref Cy_SMIF_ReceiveData is called. When enabled, the
396 * completeTxfr parameter in the function will de-assert the slave select line at
397 * the end of the function execution.
398 *
399 * \note This function blocks until all the command and associated parameters
400 * have been transmitted over the SMIF block or timeout expire.
401 *
402 * \param base
403 * Holds the base address of the SMIF block registers.
404 *
405 * \param cmd
406 * The command byte to be transmitted.
407 *
408 * \param cmdTxfrWidth
409 * The width of command byte transfer \ref cy_en_smif_txfr_width_t.
410 *
411 * \param cmdParam
412 * This is the pointer to an array that has bytes to be transmitted
413 * after the command byte. Typically, this field has the address bytes
414 * associated with the memory command.
415 *
416 * \param paramSize
417 * The size of the cmdParam array.
418 *
419 * \param paramTxfrWidth
420 * The width of parameter transfer \ref cy_en_smif_txfr_width_t.
421 *
422 * \param slaveSelect
423 * Denotes the number of the slave device to which the transfer is made.
424 * (0, 1, 2 or 4 - the bit defines which slave to enable) Two-bit enable is
425 * possible only for the double quad SPI mode.
426 *
427 * \param completeTxfr
428 * Specifies if the slave select line must be de-asserted after transferring
429 * the last byte in the parameter array. Typically, this field is set to 0 when
430 * this function succeed through \ref Cy_SMIF_TransmitData or \ref
431 * Cy_SMIF_ReceiveData.
432 *
433 * \param context
434 * Passes a configuration structure that contains the transfer parameters of the
435 * SMIF block.
436 *
437 * \return A status of the command transmit.
438 * - \ref CY_SMIF_SUCCESS
439 * - \ref CY_SMIF_EXCEED_TIMEOUT
440 *
441 * \note Check \ref group_smif_usage_rules for any usage restriction
442 *
443 *******************************************************************************/
Cy_SMIF_TransmitCommand(SMIF_Type * base,uint8_t cmd,cy_en_smif_txfr_width_t cmdTxfrWidth,uint8_t const cmdParam[],uint32_t paramSize,cy_en_smif_txfr_width_t paramTxfrWidth,cy_en_smif_slave_select_t slaveSelect,uint32_t completeTxfr,cy_stc_smif_context_t const * context)444 cy_en_smif_status_t Cy_SMIF_TransmitCommand(SMIF_Type *base,
445 uint8_t cmd,
446 cy_en_smif_txfr_width_t cmdTxfrWidth,
447 uint8_t const cmdParam[],
448 uint32_t paramSize,
449 cy_en_smif_txfr_width_t paramTxfrWidth,
450 cy_en_smif_slave_select_t slaveSelect,
451 uint32_t completeTxfr,
452 cy_stc_smif_context_t const *context)
453 {
454 #if (CY_IP_MXSMIF_VERSION>=2)
455 return Cy_SMIF_TransmitCommand_Ext(base,
456 (uint16_t)cmd,
457 false,
458 cmdTxfrWidth,
459 CY_SMIF_SDR,
460 cmdParam,
461 paramSize,
462 paramTxfrWidth,
463 CY_SMIF_SDR,
464 slaveSelect,
465 completeTxfr,
466 context);
467 #else
468 /* The return variable */
469 cy_en_smif_status_t result = CY_SMIF_SUCCESS;
470
471 /* Check input values */
472 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(cmdTxfrWidth));
473 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(paramTxfrWidth));
474 CY_ASSERT_L3(CY_SMIF_SLAVE_SEL_VALID(slaveSelect));
475 CY_ASSERT_L1(CY_SMIF_CMD_PARAM_VALID(cmdParam, paramSize));
476 CY_ASSERT_L1(CY_SMIF_WIDTH_NA_VALID(paramTxfrWidth, paramSize));
477
478 uint8_t bufIndex = 0U;
479 /* The common part of a command and parameter transfer */
480 uint32_t const constCmdPart = (
481 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_TX_MODE) |
482 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_SS, slaveSelect));
483 uint32_t timeoutUnits = context->timeout;
484
485 /* Send the command byte */
486 SMIF_TX_CMD_FIFO_WR(base) = constCmdPart |
487 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_WIDTH, (uint32_t) cmdTxfrWidth) |
488 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_TXDATA, (uint32_t) cmd) |
489 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_LAST_BYTE,
490 ((0UL == paramSize) ? completeTxfr : 0UL)) ;
491
492 /* Send the command parameters (usually address) in the blocking mode */
493 while ((bufIndex < paramSize) && (CY_SMIF_EXCEED_TIMEOUT != result))
494 {
495 /* Check if there is at least one free entry in TX_CMD_FIFO */
496 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
497 {
498 SMIF_TX_CMD_FIFO_WR(base) = constCmdPart|
499 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_TXDATA,
500 (uint32_t) cmdParam[bufIndex]) |
501 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_WIDTH,
502 (uint32_t) paramTxfrWidth) |
503 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_LAST_BYTE,
504 ((((uint32_t)bufIndex + 1UL) < paramSize) ?
505 0UL : completeTxfr));
506
507 bufIndex++;
508 }
509 result = Cy_SMIF_TimeoutRun(&timeoutUnits);
510 }
511
512 return (result);
513 #endif /* CY_IP_MXSMIF_VERSION */
514 }
515
516
517 /*******************************************************************************
518 * Function Name: Cy_SMIF_TransmitData
519 ****************************************************************************//**
520 *
521 * This function is used to transmit data using the SMIF interface. This
522 * function uses the TX Data FIFO to implement the transmit functionality. The
523 * function sets up an interrupt to trigger the TX Data FIFO and uses that
524 * interrupt to fill the TX Data FIFO until all the data is transmitted. At the
525 * end of the transmission, the TxCompleteCb is executed.
526 *
527 * \note This function is to be preceded by \ref Cy_SMIF_TransmitCommand where
528 * the slave select is selected. The slave is de-asserted at the end of a
529 * transmit. The function triggers the transfer and the transfer itself utilizes
530 * the interrupt for FIFO operations in the background. Thus, frequent
531 * interrupts will be executed after this function is triggered.
532 * Since this API is non-blocking and sets up the interrupt to act on the data
533 * FIFO, ensure there will be no another instance of the function called
534 * before the current instance has completed execution.
535 *
536 * \param base
537 * Holds the base address of the SMIF block registers.
538 *
539 * \param txBuffer
540 * The pointer to the data to be transferred. If this pointer is a NULL, then the
541 * function does not enable the interrupt. This use case is typically used when
542 * the FIFO is handled outside the interrupt and is managed in either a
543 * polling-based code or a DMA. The user would handle the FIFO management in a
544 * DMA or a polling-based code.
545 *
546 * \note If the user provides a NULL pointer in this function and does not handle
547 * the FIFO transaction, this could either stall or timeout the operation.
548 * The transfer statuses returned by \ref Cy_SMIF_GetTransferStatus are no longer
549 * valid.
550 *
551 * \param size
552 * The size of txBuffer. Must be > 0 and not greater than 65536.
553 *
554 * \param transferWidth
555 * The width of transfer \ref cy_en_smif_txfr_width_t.
556 *
557 * \param TxCompleteCb
558 * The callback executed at the end of a transmission. NULL interpreted as no
559 * callback.
560 *
561 * \param context
562 * Passes a configuration structure that contains the transfer parameters of the
563 * SMIF block.
564 *
565 * \return A status of a transmission.
566 * - \ref CY_SMIF_SUCCESS
567 * - \ref CY_SMIF_CMD_FIFO_FULL
568 *
569 *******************************************************************************/
Cy_SMIF_TransmitData(SMIF_Type * base,uint8_t const * txBuffer,uint32_t size,cy_en_smif_txfr_width_t transferWidth,cy_smif_event_cb_t TxCompleteCb,cy_stc_smif_context_t * context)570 cy_en_smif_status_t Cy_SMIF_TransmitData(SMIF_Type *base,
571 uint8_t const *txBuffer,
572 uint32_t size,
573 cy_en_smif_txfr_width_t transferWidth,
574 cy_smif_event_cb_t TxCompleteCb,
575 cy_stc_smif_context_t *context)
576 {
577
578 #if (CY_IP_MXSMIF_VERSION>=2)
579 return Cy_SMIF_TransmitData_Ext(base,
580 txBuffer,
581 size,
582 transferWidth,
583 CY_SMIF_SDR,
584 TxCompleteCb,
585 context);
586 #else
587 /* The return variable */
588 cy_en_smif_status_t result = CY_SMIF_CMD_FIFO_FULL;
589
590 /* Check input values */
591 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(transferWidth));
592 CY_ASSERT_L2(CY_SMIF_BUF_SIZE_VALID(size));
593
594 /* Check if there are enough free entries in TX_CMD_FIFO */
595 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
596 {
597 /* Enter the transmitting mode */
598 SMIF_TX_CMD_FIFO_WR(base) =
599 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_TX_COUNT_MODE) |
600 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_WIDTH, (uint32_t)transferWidth) |
601 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_TX_COUNT, (size - 1UL));
602
603 if (NULL != txBuffer)
604 {
605 /* Move the parameters to the global variables */
606 context->txBufferAddress = txBuffer;
607 context->txBufferSize = size;
608 context->txBufferCounter = size;
609 context->txCompleteCb = TxCompleteCb;
610 context->transferStatus = (uint32_t) CY_SMIF_SEND_BUSY;
611
612 /* Enable the TR_TX_REQ interrupt */
613 Cy_SMIF_SetInterruptMask(base,
614 Cy_SMIF_GetInterruptMask(base) |
615 SMIF_INTR_TR_TX_REQ_Msk);
616 }
617 result = CY_SMIF_SUCCESS;
618 }
619
620 return (result);
621 #endif /* CY_IP_MXSMIF_VERSION */
622 }
623
624
625 /*******************************************************************************
626 * Function Name: Cy_SMIF_TransmitDataBlocking
627 ****************************************************************************//**
628 *
629 * This function implements the transmit data phase in the memory command. The
630 * data is transmitted using the Tx Data FIFO and the TX_COUNT command. This
631 * function blocks until completion. The function does not use the interrupts and
632 * will use CPU to monitor the FIFO status and move data accordingly. The
633 * function returns only on completion.
634 *
635 * \note Since this API is blocking, ensure that other transfers finished and it
636 * will not be called during non-blocking transfer.
637 *
638 * \param base
639 * Holds the base address of the SMIF block registers.
640 *
641 * \param txBuffer
642 * The pointer to the data to be transferred. If this pointer is a NULL, then the
643 * function does not fill TX_FIFO. The user would handle the FIFO management in a
644 * DMA or a polling-based code.
645 *
646 * \note If the user provides a NULL pointer in this function and does not handle
647 * the FIFO transaction, this could either stall or timeout the operation.
648 * The transfer statuses returned by \ref Cy_SMIF_GetTransferStatus are no longer
649 * valid.
650 *
651 * \param size
652 * The size of txBuffer. Must be > 0 and not greater than 65536.
653 *
654 * \param transferWidth
655 * The width of transfer \ref cy_en_smif_txfr_width_t.
656 *
657 * \param context
658 * Passes a configuration structure that contains the transfer parameters of the
659 * SMIF block.
660 *
661 * \return A status of a transmission.
662 * - \ref CY_SMIF_SUCCESS
663 * - \ref CY_SMIF_CMD_FIFO_FULL
664 * - \ref CY_SMIF_EXCEED_TIMEOUT
665 * - \ref CY_SMIF_BAD_PARAM
666 *
667 *******************************************************************************/
Cy_SMIF_TransmitDataBlocking(SMIF_Type * base,uint8_t const * txBuffer,uint32_t size,cy_en_smif_txfr_width_t transferWidth,cy_stc_smif_context_t const * context)668 cy_en_smif_status_t Cy_SMIF_TransmitDataBlocking(SMIF_Type *base,
669 uint8_t const *txBuffer,
670 uint32_t size,
671 cy_en_smif_txfr_width_t transferWidth,
672 cy_stc_smif_context_t const *context)
673 {
674 #if (CY_IP_MXSMIF_VERSION>=2)
675 return Cy_SMIF_TransmitDataBlocking_Ext(base,
676 txBuffer,
677 size,
678 transferWidth,
679 CY_SMIF_SDR,
680 context);
681 #else
682 /* The return variable */
683 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
684
685 /* Check input values */
686 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(transferWidth));
687
688 if(size > 0U)
689 {
690 result = CY_SMIF_CMD_FIFO_FULL;
691 /* Check if there are enough free entries in TX_CMD_FIFO */
692 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
693 {
694 /* Enter the transmitting mode */
695 SMIF_TX_CMD_FIFO_WR(base) =
696 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_TX_COUNT_MODE) |
697 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_WIDTH, (uint32_t)transferWidth) |
698 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_TX_COUNT, (size - 1UL));
699
700 result = CY_SMIF_SUCCESS;
701
702 if (NULL != txBuffer)
703 {
704 uint32_t timeoutUnits = context->timeout;
705 cy_stc_smif_context_t contextLoc;
706
707 /* initialize parameters for Cy_SMIF_PushTxFifo */
708 contextLoc.txBufferAddress = txBuffer;
709 contextLoc.txBufferCounter = size;
710 contextLoc.txCompleteCb = NULL;
711 contextLoc.transferStatus = (uint32_t) CY_SMIF_SEND_BUSY;
712
713 while (((uint32_t) CY_SMIF_SEND_BUSY == contextLoc.transferStatus) &&
714 (CY_SMIF_EXCEED_TIMEOUT != result))
715 {
716 Cy_SMIF_PushTxFifo(base, &contextLoc);
717 result = Cy_SMIF_TimeoutRun(&timeoutUnits);
718 }
719 }
720 }
721 }
722
723 return (result);
724 #endif /* CY_IP_MXSMIF_VERSION */
725 }
726
727
728 /*******************************************************************************
729 * Function Name: Cy_SMIF_ReceiveData
730 ****************************************************************************//**
731 *
732 * This function implements the receive data phase in the memory command. The
733 * data is received into the RX Data FIFO using the RX_COUNT command. This
734 * function sets up the interrupt to trigger on the RX Data FIFO level, and the
735 * data is fetched from the RX Data FIFO to the rxBuffer as it gets filled. This
736 * function does not block until completion. The completion will trigger the call
737 * back function.
738 *
739 * \note This function is to be preceded by \ref Cy_SMIF_TransmitCommand. The
740 * slave select is de-asserted at the end of the receive.
741 * The function triggers the transfer and the transfer itself utilizes the
742 * interrupt for FIFO operations in the background. Thus, frequent
743 * interrupts will be executed after this function is triggered.
744 * This API is non-blocking and sets up the interrupt to act on the data
745 * FIFO, ensure there will be no another instance of the function called
746 * before the current instance has completed execution.
747 *
748 *
749 * \param base
750 * Holds the base address of the SMIF block registers.
751 *
752 * \param rxBuffer
753 * The pointer to the variable where the receive data is stored. If this pointer
754 * is a NULL, then the function does not enable the interrupt. This use case is
755 * typically used when the FIFO is handled outside the interrupt and is managed
756 * in either a polling-based code or a DMA. The user would handle the FIFO
757 * management in a DMA or a polling-based code.
758 *
759 * \note If the user provides a NULL pointer in this function and does not handle
760 * the FIFO transaction, this could either stall or timeout the operation.
761 * The transfer statuses returned by \ref Cy_SMIF_GetTransferStatus are no longer
762 * valid.
763 *
764 * \param size
765 * The size of data to be received. Must be > 0 and not greater than 65536.
766 *
767 * \param transferWidth
768 * The width of transfer \ref cy_en_smif_txfr_width_t.
769 *
770 * \param RxCompleteCb
771 * The callback executed at the end of a reception. NULL interpreted as no
772 * callback.
773 *
774 * \param context
775 * Passes a configuration structure that contains the transfer parameters of the
776 * SMIF block.
777 *
778 * \return A status of a reception.
779 * - \ref CY_SMIF_SUCCESS
780 * - \ref CY_SMIF_CMD_FIFO_FULL
781 * - \ref CY_SMIF_BAD_PARAM
782 *
783 * \note Check \ref group_smif_usage_rules for any usage restriction
784 *
785 *******************************************************************************/
Cy_SMIF_ReceiveData(SMIF_Type * base,uint8_t * rxBuffer,uint32_t size,cy_en_smif_txfr_width_t transferWidth,cy_smif_event_cb_t RxCompleteCb,cy_stc_smif_context_t * context)786 cy_en_smif_status_t Cy_SMIF_ReceiveData(SMIF_Type *base,
787 uint8_t *rxBuffer,
788 uint32_t size,
789 cy_en_smif_txfr_width_t transferWidth,
790 cy_smif_event_cb_t RxCompleteCb,
791 cy_stc_smif_context_t *context)
792 {
793 #if (CY_IP_MXSMIF_VERSION>=2)
794 return Cy_SMIF_ReceiveData_Ext(base,
795 rxBuffer,
796 size,
797 transferWidth,
798 CY_SMIF_SDR,
799 RxCompleteCb,
800 context);
801 #else
802 /* The return variable */
803 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
804
805 /* Check input values */
806 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(transferWidth));
807
808 if(size > 0U)
809 {
810 result = CY_SMIF_CMD_FIFO_FULL;
811 /* Check if there are enough free entries in TX_CMD_FIFO */
812 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
813 {
814 /* Enter the receiving mode */
815 SMIF_TX_CMD_FIFO_WR(base) =
816 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_RX_COUNT_MODE) |
817 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_WIDTH, (uint32_t)transferWidth) |
818 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_RX_COUNT, (size - 1UL));
819
820 if (NULL != rxBuffer)
821 {
822 /* Move the parameters to the global variables */
823 context->rxBufferAddress = (uint8_t*)rxBuffer;
824 context->rxBufferSize = size;
825 context->rxBufferCounter = size;
826 context->rxCompleteCb = RxCompleteCb;
827 context->transferStatus = (uint32_t) CY_SMIF_RX_BUSY;
828
829 /* Enable the TR_RX_REQ interrupt */
830 Cy_SMIF_SetInterruptMask(base,
831 Cy_SMIF_GetInterruptMask(base) | SMIF_INTR_TR_RX_REQ_Msk);
832 }
833 result = CY_SMIF_SUCCESS;
834 }
835 }
836
837 return (result);
838 #endif /* CY_IP_MXSMIF_VERSION */
839 }
840
841
842 /*******************************************************************************
843 * Function Name: Cy_SMIF_ReceiveDataBlocking
844 ****************************************************************************//**
845 *
846 * This function implements the receive data phase in the memory command. The
847 * data is received into the RX Data FIFO using the RX_COUNT command. This
848 * function blocks until completion. The function does not use the interrupts and
849 * will use CPU to monitor the FIFO status and move data accordingly. The
850 * function returns only on completion.
851 *
852 * \note This function is to be preceded by \ref Cy_SMIF_TransmitCommand. The
853 * slave select is de-asserted at the end of the receive. Ensure there is
854 * no another transfers.
855 *
856 * \param base
857 * Holds the base address of the SMIF block registers.
858 *
859 * \param rxBuffer
860 * The pointer to the variable where the receive data is stored. If this pointer
861 * is a NULL, then the function does not enable the interrupt. This use case is
862 * typically used when the FIFO is handled outside the interrupt and is managed
863 * in either a polling-based code or a DMA. The user would handle the FIFO
864 * management in a DMA or a polling-based code.
865 *
866 * \note If the user provides a NULL pointer in this function and does not handle
867 * the FIFO transaction, this could either stall or timeout the operation.
868 * The transfer statuses returned by \ref Cy_SMIF_GetTransferStatus are no longer
869 * valid.
870 *
871 * \param size
872 * The size of data to be received. Must be > 0 and not greater than 65536.
873 *
874 * \param transferWidth
875 * The width of transfer \ref cy_en_smif_txfr_width_t.
876 *
877 * \param context
878 * Passes a configuration structure that contains the transfer parameters of the
879 * SMIF block.
880 *
881 * \return A status of a reception.
882 * - \ref CY_SMIF_SUCCESS
883 * - \ref CY_SMIF_CMD_FIFO_FULL
884 * - \ref CY_SMIF_EXCEED_TIMEOUT
885 * - \ref CY_SMIF_BAD_PARAM
886 *
887 * \note Check \ref group_smif_usage_rules for any usage restriction
888 *
889 *******************************************************************************/
Cy_SMIF_ReceiveDataBlocking(SMIF_Type * base,uint8_t * rxBuffer,uint32_t size,cy_en_smif_txfr_width_t transferWidth,cy_stc_smif_context_t const * context)890 cy_en_smif_status_t Cy_SMIF_ReceiveDataBlocking(SMIF_Type *base,
891 uint8_t *rxBuffer,
892 uint32_t size,
893 cy_en_smif_txfr_width_t transferWidth,
894 cy_stc_smif_context_t const *context)
895 {
896 #if(CY_IP_MXSMIF_VERSION>=2)
897 return Cy_SMIF_ReceiveDataBlocking_Ext(base,
898 rxBuffer,
899 size,
900 transferWidth,
901 CY_SMIF_SDR,
902 context);
903 #else
904 /* The return variable */
905 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
906
907 /* Check input values */
908 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(transferWidth));
909
910 if(size > 0U)
911 {
912 result = CY_SMIF_CMD_FIFO_FULL;
913 /* Check if there are enough free entries in TX_CMD_FIFO */
914 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
915 {
916 /* Enter the receiving mode */
917 SMIF_TX_CMD_FIFO_WR(base) =
918 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_RX_COUNT_MODE) |
919 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_WIDTH, (uint32_t)transferWidth) |
920 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_RX_COUNT, (size - 1UL));
921 result = CY_SMIF_SUCCESS;
922
923 if (NULL != rxBuffer)
924 {
925 uint32_t timeoutUnits = context->timeout;
926 cy_stc_smif_context_t contextLoc;
927
928 /* initialize parameters for Cy_SMIF_PushTxFifo */
929 contextLoc.rxBufferAddress = (uint8_t*)rxBuffer;
930 contextLoc.rxBufferCounter = size;
931 contextLoc.rxCompleteCb = NULL;
932 contextLoc.transferStatus = (uint32_t) CY_SMIF_RX_BUSY;
933
934 while (((uint32_t) CY_SMIF_RX_BUSY == contextLoc.transferStatus) &&
935 (CY_SMIF_EXCEED_TIMEOUT != result))
936 {
937 Cy_SMIF_PopRxFifo(base, &contextLoc);
938 result = Cy_SMIF_TimeoutRun(&timeoutUnits);
939 }
940 }
941 }
942 }
943 return (result);
944 #endif /* CY_IP_MXSMIF_VERSION */
945 }
946
947
948 /*******************************************************************************
949 * Function Name: Cy_SMIF_SendDummyCycles()
950 ****************************************************************************//**
951 *
952 * This function sends dummy-clock cycles. The data lines are tri-stated during
953 * the dummy cycles.
954 *
955 * \note This function is to be preceded by \ref Cy_SMIF_TransmitCommand.
956 *
957 * \param base
958 * Holds the base address of the SMIF block registers.
959 *
960 * \param cycles
961 * The number of dummy cycles. Must be > 0 and not greater than 65536.
962 *
963 * \return A status of dummy cycles sending.
964 * - \ref CY_SMIF_SUCCESS
965 * - \ref CY_SMIF_CMD_FIFO_FULL
966 * - \ref CY_SMIF_BAD_PARAM
967 *
968 *******************************************************************************/
Cy_SMIF_SendDummyCycles(SMIF_Type * base,uint32_t cycles)969 cy_en_smif_status_t Cy_SMIF_SendDummyCycles(SMIF_Type *base,
970 uint32_t cycles)
971 {
972 #if(CY_IP_MXSMIF_VERSION>=2)
973 return Cy_SMIF_SendDummyCycles_Ext(base,
974 CY_SMIF_WIDTH_SINGLE,
975 CY_SMIF_SDR,
976 cycles);
977 #else
978 /* The return variable */
979 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
980
981 if (cycles > 0U)
982 {
983 result = CY_SMIF_CMD_FIFO_FULL;
984 /* Check if there are enough free entries in TX_CMD_FIFO */
985 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
986 {
987 /* Send the dummy bytes */
988 SMIF_TX_CMD_FIFO_WR(base) =
989 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_DUMMY_COUNT_MODE) |
990 _VAL2FLD(CY_SMIF_CMD_FIFO_WR_DUMMY, (cycles-1UL));
991
992 result = CY_SMIF_SUCCESS;
993 }
994 }
995
996 return (result);
997 #endif /* CY_IP_MXSMIF_VERSION */
998 }
999
1000
1001 /*******************************************************************************
1002 * Function Name: Cy_SMIF_GetTransferStatus
1003 ****************************************************************************//**
1004 *
1005 * This function provides the status of the transfer. This function is used to
1006 * poll for the status of the TransmitData or receiveData function. When this
1007 * function is called to determine the status of ongoing
1008 * \ref Cy_SMIF_ReceiveData() or \ref Cy_SMIF_TransmitData(), the returned status
1009 * is only valid if the functions passed a non-NULL buffer to transmit or
1010 * receive respectively. If the pointer passed to \ref Cy_SMIF_ReceiveData()
1011 * or \ref Cy_SMIF_TransmitData() is a NULL, then the code/DMA outside this
1012 * driver will take care of the transfer and the Cy_GetTxfrStatus() will return
1013 * an erroneous result.
1014 *
1015 * \param base
1016 * Holds the base address of the SMIF block registers.
1017 *
1018 * \param context
1019 * Passes a configuration structure that contains the transfer parameters of the
1020 * SMIF block.
1021 *
1022 * \return Returns the transfer status. \ref cy_en_smif_txfr_status_t
1023 *
1024 *******************************************************************************/
Cy_SMIF_GetTransferStatus(SMIF_Type const * base,cy_stc_smif_context_t const * context)1025 uint32_t Cy_SMIF_GetTransferStatus(SMIF_Type const *base, cy_stc_smif_context_t const *context)
1026 {
1027 (void)base; /* Suppress warning */
1028 return (context->transferStatus);
1029 }
1030
1031
1032 /*******************************************************************************
1033 * Function Name: Cy_SMIF_Enable
1034 ****************************************************************************//**
1035 *
1036 * Enables the operation of the SMIF block.
1037 *
1038 * \note This function only enables the SMIF IP. The interrupts associated with
1039 * the SMIF will need to be separately enabled using the interrupt driver.
1040 *
1041 * \param base
1042 * Holds the base address of the SMIF block registers.
1043 *
1044 * \param context
1045 * Passes a configuration structure that contains the transfer parameters of the
1046 * SMIF block.
1047 *
1048 *******************************************************************************/
Cy_SMIF_Enable(SMIF_Type * base,cy_stc_smif_context_t * context)1049 void Cy_SMIF_Enable(SMIF_Type *base, cy_stc_smif_context_t *context)
1050 {
1051 /* Global variables initialization */
1052 context->txBufferAddress = NULL;
1053 context->txBufferSize = 0U;
1054 context->txBufferCounter = 0U;
1055 context->rxBufferAddress = NULL;
1056 context->rxBufferSize = 0U;
1057 context->rxBufferCounter = 0U;
1058 context->transferStatus = (uint32_t)CY_SMIF_STARTED;
1059
1060 SMIF_CTL(base) |= SMIF_CTL_ENABLED_Msk;
1061
1062 #if (CY_IP_MXSMIF_VERSION >= 4)
1063 #if (CY_IP_MXSMIF_VERSION >= 5)
1064 if ((_FLD2VAL(SMIF_CORE_CTL2_DLL_OPENLOOP_ENABLE, (SMIF_CTL2(base))) == 0U) &&
1065 (_FLD2VAL(SMIF_CORE_CTL2_DLL_BYPASS_MODE, (SMIF_CTL2(base))) == 0U))
1066 #endif
1067 {
1068 /* Wait for DLL Lock to be attained */
1069 while ((SMIF_STATUS(base) & SMIF_CORE_STATUS_DLL_LOCKED_Msk) == 0U) { }
1070 Cy_SysLib_DelayUs(10);
1071 /* Wait for the SMIF to no longer be busy */
1072 while (Cy_SMIF_BusyCheck(base)) { }
1073 }
1074 #endif /* (CY_IP_MXSMIF_VERSION >= 4) */
1075 }
1076
1077
1078 #if (CY_IP_MXSMIF_VERSION>=2) || defined (CY_DOXYGEN)
1079 /*******************************************************************************
1080 * Function Name: Cy_SMIF_TransmitCommand_Ext()
1081 ****************************************************************************//**
1082 *
1083 * This function transmits a command byte followed by a parameter which is
1084 * typically an address field. The transfer is implemented using the TX FIFO.
1085 * This function also asserts the slave select line.
1086 * A command to a memory device generally starts with a command byte
1087 * transmission. This function sets up the slave lines for the rest of the
1088 * command structure. The \ref Cy_SMIF_TransmitCommand_Ext is called before \ref
1089 * Cy_SMIF_TransmitData_Ext or \ref Cy_SMIF_ReceiveData_Ext is called. When enabled, the
1090 * completeTxfr parameter in the function will de-assert the slave select line at
1091 * the end of the function execution.
1092 *
1093 * \note This function blocks until all the command and associated parameters
1094 * have been transmitted over the SMIF block or timeout expire.
1095 *
1096 * \param base
1097 * Holds the base address of the SMIF block registers.
1098 *
1099 * \param cmd
1100 * The command byte to be transmitted.
1101 *
1102 * \param isCommand2byte
1103 * isCommand2byte
1104 *
1105 * \param cmdTxfrWidth
1106 * The width of command byte transfer \ref cy_en_smif_txfr_width_t.
1107 *
1108 * \param cmdDataRate
1109 * cmdDataRate
1110 *
1111 * \param cmdParam
1112 * This is the pointer to an array that has bytes to be transmitted
1113 * after the command byte. Typically, this field has the address bytes
1114 * associated with the memory command.
1115 *
1116 * \param paramSize
1117 * The size of the cmdParam array.
1118 *
1119 * \param paramTxfrWidth
1120 * The width of parameter transfer \ref cy_en_smif_txfr_width_t.
1121 *
1122 * \param paramDataRate
1123 * paramDataRate
1124 *
1125 * \param slaveSelect
1126 * Denotes the number of the slave device to which the transfer is made.
1127 * (0, 1, 2 or 4 - the bit defines which slave to enable) Two-bit enable is
1128 * possible only for the Double Quad SPI mode.
1129 *
1130 * \param completeTxfr
1131 * Specifies if the slave select line must be de-asserted after transferring
1132 * the last byte in the parameter array. Typically, this field is set to 0 when
1133 * this function succeed through \ref Cy_SMIF_TransmitData_Ext or \ref
1134 * Cy_SMIF_ReceiveData_Ext.
1135 *
1136 * \param context
1137 * Passes a configuration structure that contains the transfer parameters of the
1138 * SMIF block.
1139 *
1140 * \return A status of the command transmit.
1141 * - \ref CY_SMIF_SUCCESS
1142 * - \ref CY_SMIF_EXCEED_TIMEOUT
1143 *
1144 *
1145 * \note
1146 * This API is available for CAT1B, CAT1C and CAT1D devices.
1147 *
1148 *******************************************************************************/
Cy_SMIF_TransmitCommand_Ext(SMIF_Type * base,uint16_t cmd,bool isCommand2byte,cy_en_smif_txfr_width_t cmdTxfrWidth,cy_en_smif_data_rate_t cmdDataRate,uint8_t const cmdParam[],uint32_t paramSize,cy_en_smif_txfr_width_t paramTxfrWidth,cy_en_smif_data_rate_t paramDataRate,cy_en_smif_slave_select_t slaveSelect,uint32_t completeTxfr,cy_stc_smif_context_t const * context)1149 cy_en_smif_status_t Cy_SMIF_TransmitCommand_Ext(SMIF_Type *base,
1150 uint16_t cmd,
1151 bool isCommand2byte,
1152 cy_en_smif_txfr_width_t cmdTxfrWidth,
1153 cy_en_smif_data_rate_t cmdDataRate,
1154 uint8_t const cmdParam[],
1155 uint32_t paramSize,
1156 cy_en_smif_txfr_width_t paramTxfrWidth,
1157 cy_en_smif_data_rate_t paramDataRate,
1158 cy_en_smif_slave_select_t slaveSelect,
1159 uint32_t completeTxfr,
1160 cy_stc_smif_context_t const *context)
1161 {
1162 cy_en_smif_status_t result = CY_SMIF_SUCCESS;
1163 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1164 uint32_t temp = 0;
1165 #endif
1166
1167 /* Check input values */
1168 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(cmdTxfrWidth));
1169 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(paramTxfrWidth));
1170 CY_ASSERT_L3(CY_SMIF_SLAVE_SEL_VALID(slaveSelect));
1171 CY_ASSERT_L3(CY_SMIF_CMD_DATA_RATE_VALID(cmdDataRate));
1172 CY_ASSERT_L3(CY_SMIF_CMD_PARAM_DATA_RATE_VALID(paramDataRate));
1173 CY_ASSERT_L1(CY_SMIF_CMD_PARAM_VALID(cmdParam, paramSize));
1174 CY_ASSERT_L1(CY_SMIF_WIDTH_NA_VALID(paramTxfrWidth, paramSize));
1175
1176 uint8_t bufIndex = 0U;
1177 /* The common part of a command and parameter transfer */
1178 uint32_t const constCmdPart = (
1179 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_TX_MODE) |
1180 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_SS, slaveSelect));
1181 uint32_t timeoutUnits = context->timeout;
1182
1183 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1184 /* Select TX Clock mode SDR/DDR for COMMAND */
1185 temp = SMIF_CTL(base);
1186 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1187 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, cmdDataRate);
1188 #endif
1189
1190 /* Prepare a cmd fifo data */
1191 if(isCommand2byte == true)
1192 {
1193 if((cmdTxfrWidth == CY_SMIF_WIDTH_OCTAL) && (cmdDataRate == CY_SMIF_DDR))
1194 {
1195 /* 2byte for each one command */
1196 SMIF_TX_CMD_MMIO_FIFO_WR(base) = constCmdPart |
1197 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t) cmdTxfrWidth) |
1198 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) cmdDataRate) |
1199 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_1, (uint8_t)(cmd & 0x00FFU)) |
1200 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_2, (uint8_t)((cmd >> 8U) & 0x00FFU)) |
1201 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE,
1202 ((0UL == paramSize) ? completeTxfr : 0UL)) ;
1203 }
1204 else
1205 {
1206 /* 1byte for each one command. need to send two command to send a command of 2byte.*/
1207 SMIF_TX_CMD_MMIO_FIFO_WR(base) = constCmdPart |
1208 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t) cmdTxfrWidth) |
1209 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) cmdDataRate) |
1210 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_1, (uint8_t)((cmd >> 8U) & 0x00FFU)) |
1211 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_2, 0U) |
1212 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE, 0U);
1213
1214 SMIF_TX_CMD_MMIO_FIFO_WR(base) = constCmdPart |
1215 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t) cmdTxfrWidth) |
1216 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) cmdDataRate) |
1217 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_1, (uint8_t)(cmd & 0x00FFU)) |
1218 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_2, 0U) |
1219 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE,
1220 ((0UL == paramSize) ? completeTxfr : 0UL)) ;
1221 }
1222 }
1223 else
1224 {
1225 /* Send the command byte */
1226 SMIF_TX_CMD_MMIO_FIFO_WR(base) = constCmdPart |
1227 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t) cmdTxfrWidth) |
1228 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) cmdDataRate) |
1229 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_1, (uint8_t) cmd) |
1230 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_2, (uint8_t) 0) |
1231 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE,
1232 ((0UL == paramSize) ? completeTxfr : 0UL)) ;
1233 }
1234
1235 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1236 /* Select TX Clock mode SDR/DDR for ADDRESS */
1237 temp = SMIF_CTL(base);
1238 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1239 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, paramDataRate);
1240 #endif
1241
1242 if((paramTxfrWidth == CY_SMIF_WIDTH_OCTAL) && (paramDataRate == CY_SMIF_DDR))
1243 {
1244 // 2 byte transmission for each one command.
1245 while ((bufIndex < paramSize) && (CY_SMIF_EXCEED_TIMEOUT != result))
1246 {
1247 /* Check if there is at least one free entry in TX_CMD_FIFO */
1248 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
1249 {
1250 SMIF_TX_CMD_MMIO_FIFO_WR(base) = constCmdPart|
1251 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_1, (uint32_t) cmdParam[bufIndex+1U]) |
1252 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_2, (uint32_t) cmdParam[bufIndex])|
1253 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t) paramTxfrWidth) |
1254 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) paramDataRate) |
1255 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE,
1256 ((((uint32_t)bufIndex + 2UL) < paramSize) ? 0UL : completeTxfr));
1257 bufIndex += 2U;
1258 }
1259 result = Cy_SMIF_TimeoutRun(&timeoutUnits);
1260 }
1261 }
1262 else
1263 {
1264 /* Send the command parameters (usually address) in the blocking mode */
1265 while ((bufIndex < paramSize) && (CY_SMIF_EXCEED_TIMEOUT != result))
1266 {
1267 /* Check if there is at least one free entry in TX_CMD_FIFO */
1268 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
1269 {
1270 SMIF_TX_CMD_MMIO_FIFO_WR(base) = constCmdPart|
1271 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_1, (uint32_t) cmdParam[bufIndex]) |
1272 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_2, 0)|
1273 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t) paramTxfrWidth) |
1274 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) paramDataRate) |
1275 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE,
1276 ((((uint32_t)bufIndex + 1UL) < paramSize) ? 0UL : completeTxfr));
1277
1278 bufIndex++;
1279 }
1280 result = Cy_SMIF_TimeoutRun(&timeoutUnits);
1281 }
1282 }
1283
1284 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1285 /* Switch back to preferred XIP mode data rate */
1286 temp = SMIF_CTL(base);
1287 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1288 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, context->preXIPDataRate);
1289 #endif
1290 return (result);
1291 }
1292
1293 /*******************************************************************************
1294 * Function Name: Cy_SMIF_TransmitData_Ext
1295 ****************************************************************************//**
1296 *
1297 * This function is used to transmit data using the SMIF interface. This
1298 * function uses the TX Data FIFO to implement the transmit functionality. The
1299 * function sets up an interrupt to trigger the TX Data FIFO and uses that
1300 * interrupt to fill the TX Data FIFO until all the data is transmitted. At the
1301 * end of the transmission, the TxCmpltCb is executed.
1302 *
1303 * \note This function is to be preceded by \ref Cy_SMIF_TransmitCommand_Ext where
1304 * the slave select is selected. The slave is de-asserted at the end of a
1305 * transmit. The function triggers the transfer and the transfer itself utilizes
1306 * the interrupt for FIFO operations in the background. Thus, frequent
1307 * interrupts will be executed after this function is triggered.
1308 * Since this API is non-blocking and sets up the interrupt to act on the data
1309 * FIFO, ensure there will be no another instance of the function called
1310 * before the current instance has completed execution.
1311 *
1312 * \param base
1313 * Holds the base address of the SMIF block registers.
1314 *
1315 * \param txBuffer
1316 * The pointer to the data to be transferred. If this pointer is a NULL, then the
1317 * function does not enable the interrupt. This use case is typically used when
1318 * the FIFO is handled outside the interrupt and is managed in either a
1319 * polling-based code or a DMA. The user would handle the FIFO management in a
1320 * DMA or a polling-based code.
1321 *
1322 * \note If the user provides a NULL pointer in this function and does not handle
1323 * the FIFO transaction, this could either stall or timeout the operation.
1324 * The transfer statuses returned by \ref Cy_SMIF_GetTransferStatus are no longer
1325 * valid.
1326 *
1327 * \param size
1328 * The size of txBuffer. Must be > 0 and not greater than 65536.
1329 *
1330 * \param transferWidth
1331 * The width of transfer \ref cy_en_smif_txfr_width_t.
1332 *
1333 * \param dataDataRate
1334 * dataDataRate
1335 *
1336 * \param TxCmpltCb
1337 * The callback executed at the end of a transmission. NULL interpreted as no
1338 * callback.
1339 *
1340 * \param context
1341 * Passes a configuration structure that contains the transfer parameters of the
1342 * SMIF block.
1343 *
1344 * \return A status of a transmission.
1345 * - \ref CY_SMIF_SUCCESS
1346 * - \ref CY_SMIF_CMD_FIFO_FULL
1347 *
1348 * \note
1349 * This API is available for CAT1B, CAT1C and CAT1D devices.
1350 *
1351 *******************************************************************************/
Cy_SMIF_TransmitData_Ext(SMIF_Type * base,uint8_t const * txBuffer,uint32_t size,cy_en_smif_txfr_width_t transferWidth,cy_en_smif_data_rate_t dataDataRate,cy_smif_event_cb_t TxCmpltCb,cy_stc_smif_context_t * context)1352 cy_en_smif_status_t Cy_SMIF_TransmitData_Ext(SMIF_Type *base,
1353 uint8_t const *txBuffer,
1354 uint32_t size,
1355 cy_en_smif_txfr_width_t transferWidth,
1356 cy_en_smif_data_rate_t dataDataRate,
1357 cy_smif_event_cb_t TxCmpltCb,
1358 cy_stc_smif_context_t *context)
1359 {
1360 /* The return variable */
1361 cy_en_smif_status_t result = CY_SMIF_CMD_FIFO_FULL;
1362 uint32_t trUnitNum;
1363 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1364 uint32_t temp = 0;
1365 #endif
1366
1367 /* Check input values */
1368 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(transferWidth));
1369 CY_ASSERT_L2(CY_SMIF_BUF_SIZE_VALID(size));
1370
1371 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1372 /* Select TX Clock mode SDR/DDR */
1373 temp = SMIF_CTL(base);
1374 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1375 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, dataDataRate);
1376 #endif
1377
1378 /* If the mode is octal SPI with DDR data unit is a 2-byte */
1379 if((transferWidth == CY_SMIF_WIDTH_OCTAL) && (dataDataRate == CY_SMIF_DDR))
1380 {
1381 trUnitNum = (size / 2U) + (size % 2U);
1382 }
1383 else
1384 {
1385 trUnitNum = size;
1386 }
1387
1388 /* Check if there are enough free entries in TX_CMD_FIFO */
1389 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
1390 {
1391 /* Enter the transmitting mode */
1392 SMIF_TX_CMD_MMIO_FIFO_WR(base) =
1393 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_TX_COUNT_MODE) |
1394 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t)transferWidth) |
1395 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) dataDataRate) |
1396 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TX_COUNT, (trUnitNum - 1UL))|
1397 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE, 1U);
1398
1399 if (NULL != txBuffer)
1400 {
1401 /* Move the parameters to the global variables */
1402 context->txBufferAddress = (uint8_t*)txBuffer;
1403 context->txBufferSize = size;
1404 context->txBufferCounter = size;
1405 context->txCompleteCb = TxCmpltCb;
1406 context->transferStatus = (uint32_t) CY_SMIF_SEND_BUSY;
1407 context->preCmdDataRate = dataDataRate;
1408 context->preCmdWidth = transferWidth;
1409
1410 #if (CY_IP_MXSMIF_VERSION >= 4) /* DRIVERS-12031 */
1411 Cy_SMIF_SetTxFifoTriggerLevel(base, 1U);
1412 #endif
1413
1414 /* Enable the TR_TX_REQ interrupt */
1415 Cy_SMIF_SetInterruptMask(base,
1416 Cy_SMIF_GetInterruptMask(base) |
1417 SMIF_INTR_TR_TX_REQ_Msk);
1418 }
1419 result = CY_SMIF_SUCCESS;
1420 }
1421
1422 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1423 /* Switch back to preferred XIP mode data rate */
1424 temp = SMIF_CTL(base);
1425 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1426 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, context->preXIPDataRate);
1427 #endif
1428
1429 return (result);
1430 }
1431
1432 /*******************************************************************************
1433 * Function Name: Cy_SMIF_TransmitDataBlocking_Ext
1434 ****************************************************************************//**
1435 *
1436 * This function implements the transmit data phase in the memory command. The
1437 * data is transmitted using the Tx Data FIFO and the TX_COUNT command. This
1438 * function blocks until completion. The function does not use the interrupts and
1439 * will use CPU to monitor the FIFO status and move data accordingly. The
1440 * function returns only on completion.
1441 *
1442 * \note Since this API is blocking, ensure that other transfers finished and it
1443 * will not be called during non-blocking transfer.
1444 *
1445 * \param base
1446 * Holds the base address of the SMIF block registers.
1447 *
1448 * \param txBuffer
1449 * The pointer to the data to be transferred. If this pointer is a NULL, then the
1450 * function does not fill TX_FIFO. The user would handle the FIFO management in a
1451 * DMA or a polling-based code.
1452 *
1453 * \note If the user provides a NULL pointer in this function and does not handle
1454 * the FIFO transaction, this could either stall or timeout the operation.
1455 * The transfer statuses returned by \ref Cy_SMIF_GetTransferStatus are no longer
1456 * valid.
1457 *
1458 * \param size
1459 * The size of txBuffer. Must be > 0 and not greater than 65536.
1460 *
1461 * \param transferWidth
1462 * The width of transfer \ref cy_en_smif_txfr_width_t.
1463 *
1464 * \param dataDataRate
1465 * dataDataRate
1466 *
1467 * \param context
1468 * Passes a configuration structure that contains the transfer parameters of the
1469 * SMIF block.
1470 *
1471 * \return A status of a transmission.
1472 * - \ref CY_SMIF_SUCCESS
1473 * - \ref CY_SMIF_CMD_FIFO_FULL
1474 * - \ref CY_SMIF_EXCEED_TIMEOUT
1475 * - \ref CY_SMIF_BAD_PARAM
1476 *
1477 * \note
1478 * This API is available for CAT1B, CAT1C and CAT1D devices.
1479 *
1480 *******************************************************************************/
Cy_SMIF_TransmitDataBlocking_Ext(SMIF_Type * base,uint8_t const * txBuffer,uint32_t size,cy_en_smif_txfr_width_t transferWidth,cy_en_smif_data_rate_t dataDataRate,cy_stc_smif_context_t const * context)1481 cy_en_smif_status_t Cy_SMIF_TransmitDataBlocking_Ext(SMIF_Type *base,
1482 uint8_t const *txBuffer,
1483 uint32_t size,
1484 cy_en_smif_txfr_width_t transferWidth,
1485 cy_en_smif_data_rate_t dataDataRate,
1486 cy_stc_smif_context_t const *context)
1487 {
1488 /* The return variable */
1489 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
1490 uint32_t trUnitNum;
1491 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1492 uint32_t temp = 0;
1493 #endif
1494
1495 /* Check input values */
1496 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(transferWidth));
1497
1498 if(size > 0U)
1499 {
1500 result = CY_SMIF_CMD_FIFO_FULL;
1501 /* Check if there are enough free entries in TX_CMD_FIFO */
1502 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
1503 {
1504 /* If the mode is octal SPI with DDR or Hyperbus, data unit is a 2-byte */
1505 if((transferWidth == CY_SMIF_WIDTH_OCTAL) && (dataDataRate == CY_SMIF_DDR))
1506 {
1507 trUnitNum = (size / 2U) + (size % 2U);
1508 }
1509 else
1510 {
1511 trUnitNum = size;
1512 }
1513
1514 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1515 /* Select TX Clock mode SDR/DDR */
1516 temp = SMIF_CTL(base);
1517 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1518 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, dataDataRate);
1519 #endif
1520 /* Enter the transmitting mode */
1521 SMIF_TX_CMD_MMIO_FIFO_WR(base) =
1522 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_TX_COUNT_MODE) |
1523 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) dataDataRate) |
1524 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t)transferWidth) |
1525 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_TX_COUNT, (trUnitNum - 1U)) |
1526 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE, 1U);
1527
1528 result = CY_SMIF_SUCCESS;
1529
1530 if (NULL != txBuffer)
1531 {
1532 uint32_t timeoutUnits = context->timeout;
1533 cy_stc_smif_context_t contextLoc = *context;
1534
1535 /* initialize parameters for Cy_SMIF_PushTxFifo */
1536 contextLoc.txBufferAddress = (uint8_t*)txBuffer;
1537 contextLoc.txBufferCounter = size;
1538 contextLoc.txCompleteCb = NULL;
1539 contextLoc.transferStatus = (uint32_t) CY_SMIF_SEND_BUSY;
1540 contextLoc.preCmdDataRate = dataDataRate;
1541 contextLoc.preCmdWidth = transferWidth;
1542
1543 while (((uint32_t) CY_SMIF_SEND_BUSY == contextLoc.transferStatus) &&
1544 (CY_SMIF_EXCEED_TIMEOUT != result))
1545 {
1546 Cy_SMIF_PushTxFifo(base, &contextLoc);
1547 result = Cy_SMIF_TimeoutRun(&timeoutUnits);
1548 }
1549 }
1550 }
1551 }
1552
1553 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1554 /* Switch back to preferred XIP mode data rate */
1555 temp = SMIF_CTL(base);
1556 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1557 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, context->preXIPDataRate);
1558 #endif
1559
1560 return (result);
1561 }
1562
1563 /*******************************************************************************
1564 * Function Name: Cy_SMIF_ReceiveData_Ext
1565 ****************************************************************************//**
1566 *
1567 * This function implements the receive data phase in the memory command. The
1568 * data is received into the RX Data FIFO using the RX_COUNT command. This
1569 * function sets up the interrupt to trigger on the RX Data FIFO level, and the
1570 * data is fetched from the RX Data FIFO to the rxBuffer as it gets filled. This
1571 * function does not block until completion. The completion will trigger the call
1572 * back function.
1573 *
1574 * \note This function is to be preceded by \ref Cy_SMIF_TransmitCommand. The
1575 * slave select is de-asserted at the end of the receive.
1576 * The function triggers the transfer and the transfer itself utilizes the
1577 * interrupt for FIFO operations in the background. Thus, frequent
1578 * interrupts will be executed after this function is triggered.
1579 * This API is non-blocking and sets up the interrupt to act on the data
1580 * FIFO, ensure there will be no another instance of the function called
1581 * before the current instance has completed execution.
1582 *
1583 *
1584 * \param base
1585 * Holds the base address of the SMIF block registers.
1586 *
1587 * \param rxBuffer
1588 * The pointer to the variable where the receive data is stored. If this pointer
1589 * is a NULL, then the function does not enable the interrupt. This use case is
1590 * typically used when the FIFO is handled outside the interrupt and is managed
1591 * in either a polling-based code or a DMA. The user would handle the FIFO
1592 * management in a DMA or a polling-based code.
1593 *
1594 * \note If the user provides a NULL pointer in this function and does not handle
1595 * the FIFO transaction, this could either stall or timeout the operation.
1596 * The transfer statuses returned by \ref Cy_SMIF_GetTransferStatus are no longer
1597 * valid.
1598 *
1599 * \param size
1600 * The size of data to be received. Must be > 0 and not greater than 65536.
1601 *
1602 * \param transferWidth
1603 * The width of transfer \ref cy_en_smif_txfr_width_t.
1604 *
1605 * \param dataRate
1606 * dataRate
1607 *
1608 * \param RxCmpltCb
1609 * The callback executed at the end of a reception. NULL interpreted as no
1610 * callback.
1611 *
1612 * \param context
1613 * Passes a configuration structure that contains the transfer parameters of the
1614 * SMIF block.
1615 *
1616 * \return A status of a reception.
1617 * - \ref CY_SMIF_SUCCESS
1618 * - \ref CY_SMIF_CMD_FIFO_FULL
1619 * - \ref CY_SMIF_BAD_PARAM
1620 *
1621 * \note Check \ref group_smif_usage_rules for any usage restriction
1622 *
1623 * \note
1624 * This API is available for CAT1B, CAT1C and CAT1D devices.
1625 *
1626 *******************************************************************************/
Cy_SMIF_ReceiveData_Ext(SMIF_Type * base,uint8_t * rxBuffer,uint32_t size,cy_en_smif_txfr_width_t transferWidth,cy_en_smif_data_rate_t dataRate,cy_smif_event_cb_t RxCmpltCb,cy_stc_smif_context_t * context)1627 cy_en_smif_status_t Cy_SMIF_ReceiveData_Ext(SMIF_Type *base,
1628 uint8_t *rxBuffer,
1629 uint32_t size,
1630 cy_en_smif_txfr_width_t transferWidth,
1631 cy_en_smif_data_rate_t dataRate,
1632 cy_smif_event_cb_t RxCmpltCb,
1633 cy_stc_smif_context_t *context)
1634 {
1635 /* The return variable */
1636 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
1637 uint32_t rxUnitNum;
1638 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1639 uint32_t temp = 0;
1640 #endif
1641
1642 /* Check input values */
1643 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(transferWidth));
1644
1645 if(size > 0U)
1646 {
1647 result = CY_SMIF_CMD_FIFO_FULL;
1648 /* Check if there are enough free entries in TX_CMD_FIFO */
1649 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
1650 {
1651 /* If the mode is octal SPI with DDR or Hyperbus, data unit is a 2-byte */
1652 if((transferWidth == CY_SMIF_WIDTH_OCTAL) && (dataRate == CY_SMIF_DDR))
1653 {
1654 rxUnitNum = (size / 2U) + (size % 2U);
1655 }
1656 else
1657 {
1658 rxUnitNum = size;
1659 }
1660
1661 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1662 /* Select TX Clock mode SDR/DDR */
1663 temp = SMIF_CTL(base);
1664 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1665 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, dataRate);
1666 #endif
1667 /* Enter the receiving mode */
1668 SMIF_TX_CMD_MMIO_FIFO_WR(base) =
1669 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_RX_COUNT_MODE) |
1670 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t)transferWidth) |
1671 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) dataRate) |
1672 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_RX_COUNT, (rxUnitNum - 1UL)) |
1673 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE, 1U);
1674
1675 if (NULL != rxBuffer)
1676 {
1677 /* Move the parameters to the global variables */
1678 context->rxBufferAddress = (uint8_t*)rxBuffer;
1679 context->rxBufferSize = size;
1680 context->rxBufferCounter = size;
1681 context->rxCompleteCb = RxCmpltCb;
1682 context->transferStatus = (uint32_t) CY_SMIF_REC_BUSY;
1683
1684 /* Enable the TR_RX_REQ interrupt */
1685 Cy_SMIF_SetInterruptMask(base,
1686 Cy_SMIF_GetInterruptMask(base) | SMIF_INTR_TR_RX_REQ_Msk);
1687 }
1688 result = CY_SMIF_SUCCESS;
1689 }
1690 }
1691
1692 return (result);
1693 }
1694
1695 /*******************************************************************************
1696 * Function Name: Cy_SMIF_ReceiveDataBlocking_Ext
1697 ****************************************************************************//**
1698 *
1699 * This function implements the receive data phase in the memory command. The
1700 * data is received into the RX Data FIFO using the RX_COUNT command. This
1701 * function blocks until completion. The function does not use the interrupts and
1702 * will use CPU to monitor the FIFO status and move data accordingly. The
1703 * function returns only on completion.
1704 *
1705 * \note This function is to be preceded by \ref Cy_SMIF_TransmitCommand. The
1706 * slave select is de-asserted at the end of the receive. Ensure there is
1707 * no another transfers.
1708 *
1709 * \param base
1710 * Holds the base address of the SMIF block registers.
1711 *
1712 * \param rxBuffer
1713 * The pointer to the variable where the receive data is stored. If this pointer
1714 * is a NULL, then the function does not enable the interrupt. This use case is
1715 * typically used when the FIFO is handled outside the interrupt and is managed
1716 * in either a polling-based code or a DMA. The user would handle the FIFO
1717 * management in a DMA or a polling-based code.
1718 *
1719 * \note If the user provides a NULL pointer in this function and does not handle
1720 * the FIFO transaction, this could either stall or timeout the operation.
1721 * The transfer statuses returned by \ref Cy_SMIF_GetTransferStatus are no longer
1722 * valid.
1723 *
1724 * \param size
1725 * The size of data to be received. Must be > 0 and not greater than 65536.
1726 *
1727 * \param transferWidth
1728 * The width of transfer \ref cy_en_smif_txfr_width_t.
1729 *
1730 * \param dataRate
1731 * dataRate
1732 *
1733 * \param context
1734 * Passes a configuration structure that contains the transfer parameters of the
1735 * SMIF block.
1736 *
1737 * \return A status of a reception.
1738 * - \ref CY_SMIF_SUCCESS
1739 * - \ref CY_SMIF_CMD_FIFO_FULL
1740 * - \ref CY_SMIF_EXCEED_TIMEOUT
1741 * - \ref CY_SMIF_BAD_PARAM
1742 *
1743 * \note Check \ref group_smif_usage_rules for any usage restriction
1744 *
1745 * \note
1746 * This API is available for CAT1B, CAT1C and CAT1D devices.
1747 *
1748 *******************************************************************************/
Cy_SMIF_ReceiveDataBlocking_Ext(SMIF_Type * base,uint8_t * rxBuffer,uint32_t size,cy_en_smif_txfr_width_t transferWidth,cy_en_smif_data_rate_t dataRate,cy_stc_smif_context_t const * context)1749 cy_en_smif_status_t Cy_SMIF_ReceiveDataBlocking_Ext(SMIF_Type *base,
1750 uint8_t *rxBuffer,
1751 uint32_t size,
1752 cy_en_smif_txfr_width_t transferWidth,
1753 cy_en_smif_data_rate_t dataRate,
1754 cy_stc_smif_context_t const *context)
1755 {
1756 /* The return variable */
1757 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
1758 uint32_t rxUnitNum;
1759 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1760 uint32_t temp = 0;
1761 #endif
1762
1763 /* Check input values */
1764 CY_ASSERT_L3(CY_SMIF_TXFR_WIDTH_VALID(transferWidth));
1765
1766 if(size > 0U)
1767 {
1768 result = CY_SMIF_CMD_FIFO_FULL;
1769 /* Check if there are enough free entries in TX_CMD_FIFO */
1770 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
1771 {
1772 /* If the mode is octal SPI with DDR or Hyperbus, data unit is a 2-byte */
1773 if((transferWidth == CY_SMIF_WIDTH_OCTAL) && (dataRate == CY_SMIF_DDR))
1774 {
1775 rxUnitNum = (size / 2U) + (size % 2U);
1776 }
1777 else
1778 {
1779 rxUnitNum = size;
1780 }
1781
1782 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1783 /* Select TX Clock mode SDR/DDR */
1784 temp = SMIF_CTL(base);
1785 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1786 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, dataRate);
1787 #endif
1788 /* Enter the receiving mode */
1789 SMIF_TX_CMD_MMIO_FIFO_WR(base) =
1790 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_RX_COUNT_MODE) |
1791 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t)transferWidth) |
1792 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_RX_COUNT, (rxUnitNum - 1UL)) |
1793 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) dataRate) |
1794 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE, 1U);
1795
1796 result = CY_SMIF_SUCCESS;
1797
1798 if (NULL != rxBuffer)
1799 {
1800 uint32_t timeoutUnits = context->timeout;
1801 cy_stc_smif_context_t contextLoc;
1802
1803 /* initialize parameters for Cy_SMIF_PushTxFifo */
1804 contextLoc.rxBufferAddress = (uint8_t*)rxBuffer;
1805 contextLoc.rxBufferCounter = size;
1806 contextLoc.rxCompleteCb = NULL;
1807 contextLoc.transferStatus = (uint32_t) CY_SMIF_REC_BUSY;
1808
1809 while (((uint32_t) CY_SMIF_REC_BUSY == contextLoc.transferStatus) &&
1810 (CY_SMIF_EXCEED_TIMEOUT != result))
1811 {
1812 Cy_SMIF_PopRxFifo(base, &contextLoc);
1813 result = Cy_SMIF_TimeoutRun(&timeoutUnits);
1814 }
1815 }
1816 }
1817 }
1818
1819 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1820 /* Switch back to preferred XIP mode data rate */
1821 temp = SMIF_CTL(base);
1822 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1823 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, context->preXIPDataRate);
1824 #endif
1825
1826 return (result);
1827 }
1828
1829
1830 /*******************************************************************************
1831 * Function Name: Cy_SMIF_SendDummyCycles_Ext()
1832 ****************************************************************************//**
1833 *
1834 * This function sends dummy-clock cycles. The data lines are tri-stated during
1835 * the dummy cycles.
1836 *
1837 * \note This function is to be preceded by \ref Cy_SMIF_TransmitCommand.
1838 *
1839 * \param base
1840 * Holds the base address of the SMIF block registers.
1841 *
1842 * \param transferWidth
1843 *
1844 * \param dataRate
1845 *
1846 * \param cycles
1847 * The number of dummy cycles. Must be > 0 and not greater than 65536.
1848 *
1849 * \return A status of dummy cycles sending.
1850 * - \ref CY_SMIF_SUCCESS
1851 * - \ref CY_SMIF_CMD_FIFO_FULL
1852 * - \ref CY_SMIF_BAD_PARAM
1853 *
1854 * \note
1855 * This API is available for CAT1B, CAT1C and CAT1D devices.
1856 *
1857 *******************************************************************************/
Cy_SMIF_SendDummyCycles_Ext(SMIF_Type * base,cy_en_smif_txfr_width_t transferWidth,cy_en_smif_data_rate_t dataRate,uint32_t cycles)1858 cy_en_smif_status_t Cy_SMIF_SendDummyCycles_Ext(SMIF_Type *base,
1859 cy_en_smif_txfr_width_t transferWidth,
1860 cy_en_smif_data_rate_t dataRate,
1861 uint32_t cycles)
1862 {
1863 /* The return variable */
1864 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
1865 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1866 uint32_t temp = 0;
1867 #endif
1868 if (cycles > 0U)
1869 {
1870 result = CY_SMIF_CMD_FIFO_FULL;
1871 uint32_t dummyRWDS = 0U;
1872 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
1873 /* Select TX Clock mode SDR/DDR */
1874 temp = SMIF_CTL(base);
1875 temp &= ~(SMIF_CTL_CLOCK_IF_TX_SEL_Msk);
1876 SMIF_CTL(base) = temp | _VAL2FLD(SMIF_CTL_CLOCK_IF_TX_SEL, dataRate);
1877
1878 uint32_t ifRxSel = _FLD2VAL(SMIF_CTL_CLOCK_IF_RX_SEL, SMIF_CTL(base));
1879 if(ifRxSel == (uint32_t)CY_SMIF_SEL_SPHB_RWDS_CLK || ifRxSel == (uint32_t)CY_SMIF_SEL_INVERTED_SPHB_RWDS_CLK)
1880 {
1881 dummyRWDS = 1U;
1882 }
1883 #endif
1884 #if (CY_IP_MXSMIF_VERSION >= 4)
1885 if (_FLD2VAL(SMIF_CORE_CTL2_RX_CAPTURE_MODE, (SMIF_CTL2(base))) == (uint32_t)CY_SMIF_SEL_XSPI_HYPERBUS_WITH_DQS)
1886 {
1887 dummyRWDS = 1U;
1888 }
1889 #endif
1890 /* Check if there are enough free entries in TX_CMD_FIFO */
1891 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
1892 {
1893 /* Send the dummy bytes */
1894 SMIF_TX_CMD_MMIO_FIFO_WR(base) =
1895 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_DUMMY_COUNT_MODE) |
1896 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY, (cycles-1UL)) |
1897 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t)transferWidth) |
1898 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) dataRate) |
1899 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY_READ_RWDS, dummyRWDS) |
1900 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE, 0);
1901
1902 result = CY_SMIF_SUCCESS;
1903 }
1904 }
1905
1906 return (result);
1907 }
1908 /*******************************************************************************
1909 * Function Name: Cy_SMIF_SendDummyCycles_With_RWDS()
1910 ****************************************************************************//**
1911 *
1912 * This function sends dummy-clock cycles and observes additional input data signal RWDS.
1913 * The data lines are tri-stated during
1914 * the dummy cycles.
1915 *
1916 * \note This function is to be preceded by \ref Cy_SMIF_TransmitCommand_Ext.
1917 *
1918 * \param base
1919 * Holds the base address of the SMIF block registers.
1920 *
1921 * \param read_rwds
1922 * Indicates whether it is read/write transaction. "true" in case of read. "false" in case of write.
1923 *
1924 * \param refresh_indicator
1925 * Dummy cycles are doubled when RWDS refresh indicator is high during CA cycle. (HyperRAM variable latency mode)
1926 *
1927 * \param cycles
1928 * The number of dummy cycles. Must be > 0 and not greater than 65536.
1929 *
1930 * \return A status of dummy cycles sending.
1931 * - \ref CY_SMIF_SUCCESS
1932 * - \ref CY_SMIF_CMD_FIFO_FULL
1933 * - \ref CY_SMIF_BAD_PARAM
1934 *
1935 * \note
1936 * This API is available for CAT1B, CAT1C and CAT1D devices.
1937 *
1938 *******************************************************************************/
Cy_SMIF_SendDummyCycles_With_RWDS(SMIF_Type * base,bool read_rwds,bool refresh_indicator,uint32_t cycles)1939 cy_en_smif_status_t Cy_SMIF_SendDummyCycles_With_RWDS(SMIF_Type *base,
1940 bool read_rwds,
1941 bool refresh_indicator,
1942 uint32_t cycles)
1943 {
1944 /* The return variable */
1945 cy_en_smif_status_t result = CY_SMIF_BAD_PARAM;
1946
1947 if (cycles > 0U)
1948 {
1949 result = CY_SMIF_CMD_FIFO_FULL;
1950
1951 /* Check if there are enough free entries in TX_CMD_FIFO */
1952 if (Cy_SMIF_GetCmdFifoStatus(base) < CY_SMIF_TX_CMD_FIFO_STATUS_RANGE)
1953 {
1954 /* Send the dummy bytes */
1955 SMIF_TX_CMD_MMIO_FIFO_WR(base) =
1956 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_MODE, CY_SMIF_CMD_FIFO_DUMMY_COUNT_MODE) |
1957 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY, (cycles-1UL)) |
1958 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH, (uint32_t)CY_SMIF_WIDTH_OCTAL) |
1959 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE, (uint32_t) CY_SMIF_DDR) |
1960 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY_READ_RWDS, (uint32_t)read_rwds) |
1961 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY_WRITE_RWDS,(uint32_t)!(read_rwds)) |
1962 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_RWDS_REFRESH, (uint32_t)refresh_indicator) |
1963 _VAL2FLD(CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE, 0);
1964
1965 result = CY_SMIF_SUCCESS;
1966 }
1967 }
1968
1969 return (result);
1970 }
1971 #endif /* CY_IP_MXSMIF_VERSION */
1972
1973
1974 /*******************************************************************************
1975 * Function Name: Cy_SMIF_SetCryptoKey
1976 ****************************************************************************//**
1977 *
1978 * Sets the AES-128 encryption key into SMIF crypto registers.
1979 *
1980 * \param base
1981 * Holds the base address of the SMIF block registers.
1982 *
1983 * \param key
1984 * An array containing 128 bit crypto key: uint32_t key[4].
1985 * The least significant word first.
1986 *
1987 *******************************************************************************/
Cy_SMIF_SetCryptoKey(SMIF_Type * base,uint32_t * key)1988 void Cy_SMIF_SetCryptoKey(SMIF_Type *base, uint32_t *key)
1989 {
1990 SMIF_CRYPTO_KEY0(base) = key[0U];
1991 SMIF_CRYPTO_KEY1(base) = key[1U];
1992 SMIF_CRYPTO_KEY2(base) = key[2U];
1993 SMIF_CRYPTO_KEY3(base) = key[3U];
1994 }
1995
1996 /*******************************************************************************
1997 * Function Name: Cy_SMIF_SetCryptoIV
1998 ****************************************************************************//**
1999 *
2000 * Sets the 96 bit initialization vector (nonce) into SMIF crypto registers.
2001 *
2002 * \param base
2003 * Holds the base address of the SMIF block registers.
2004 *
2005 * \param nonce
2006 * An array containing 96 bit initialization vector (nonce)
2007 *
2008 *******************************************************************************/
Cy_SMIF_SetCryptoIV(SMIF_Type * base,uint32_t * nonce)2009 void Cy_SMIF_SetCryptoIV(SMIF_Type *base, uint32_t *nonce)
2010 {
2011 /* SMIF_CRYPTO_INPUT0 is a counter, the rest 3 registers are nonce */
2012 SMIF_CRYPTO_INPUT1(base) = nonce[0U];
2013 SMIF_CRYPTO_INPUT2(base) = nonce[1U];
2014 SMIF_CRYPTO_INPUT3(base) = nonce[2U];
2015 }
2016
2017 /*******************************************************************************
2018 * Function Name: Cy_SMIF_ConvertSlaveSlotToIndex
2019 ****************************************************************************//**
2020 *
2021 * Converts Slave Select enum to the device index.
2022 *
2023 * \param ss
2024 * Slave Select enum.
2025 *
2026 * \param device_idx
2027 * A pointer to device index to be returned.
2028 *
2029 * \return \ref cy_en_smif_status_t.
2030 *
2031 *******************************************************************************/
Cy_SMIF_ConvertSlaveSlotToIndex(cy_en_smif_slave_select_t ss,uint32_t * device_idx)2032 cy_en_smif_status_t Cy_SMIF_ConvertSlaveSlotToIndex(cy_en_smif_slave_select_t ss, uint32_t *device_idx)
2033 {
2034 cy_en_smif_status_t ret = CY_SMIF_BAD_PARAM;
2035
2036 switch (ss)
2037 {
2038 case CY_SMIF_SLAVE_SELECT_0:
2039 *device_idx = 0U;
2040 ret = CY_SMIF_SUCCESS;
2041 break;
2042 case CY_SMIF_SLAVE_SELECT_1:
2043 *device_idx = 1U;
2044 ret = CY_SMIF_SUCCESS;
2045 break;
2046 case CY_SMIF_SLAVE_SELECT_2:
2047 *device_idx = 2U;
2048 ret = CY_SMIF_SUCCESS;
2049 break;
2050 case CY_SMIF_SLAVE_SELECT_3:
2051 *device_idx = 3U;
2052 ret = CY_SMIF_SUCCESS;
2053 break;
2054 default:
2055 /* The switch statement must have a non-empty default clause. MISRA 16.4 */
2056 ret = CY_SMIF_BAD_PARAM;
2057 break;
2058 }
2059 return ret;
2060 }
2061
2062 /*******************************************************************************
2063 * Function Name: Cy_SMIF_SetCryptoEnable
2064 ****************************************************************************//**
2065 *
2066 * Enables SMIF encryption
2067 *
2068 * \param base
2069 * Holds the base address of the SMIF block registers.
2070 *
2071 * \param slaveId
2072 * salve select line to indicate the device on which encryption should be enabled.
2073 *
2074 * \return \ref cy_en_smif_status_t.
2075 *
2076 * \note Please ensure cache is disabled using \ref Cy_SMIF_CacheDisable or
2077 * invalidated using \ref Cy_SMIF_CacheInvalidate or any other system level cache to
2078 * be cleared so that the next read/execute from flash operation results in correct data.
2079 *
2080 *******************************************************************************/
Cy_SMIF_SetCryptoEnable(SMIF_Type * base,cy_en_smif_slave_select_t slaveId)2081 cy_en_smif_status_t Cy_SMIF_SetCryptoEnable(SMIF_Type *base, cy_en_smif_slave_select_t slaveId)
2082 {
2083 uint32_t device_idx;
2084 cy_en_smif_status_t ret = CY_SMIF_BAD_PARAM;
2085
2086 if (CY_SMIF_SUCCESS == Cy_SMIF_ConvertSlaveSlotToIndex(slaveId, &device_idx))
2087 {
2088 SMIF_DEVICE_IDX_CTL(base, device_idx) |= SMIF_DEVICE_CTL_CRYPTO_EN_Msk;
2089 ret = CY_SMIF_SUCCESS;
2090 }
2091
2092 return ret;
2093 }
2094
2095
2096 /*******************************************************************************
2097 * Function Name: Cy_SMIF_SetCryptoDisable
2098 ****************************************************************************//**
2099 *
2100 * Disables SMIF encryption.
2101 *
2102 * \param base
2103 * Holds the base address of the SMIF block registers.
2104 *
2105 * \param slaveId
2106 * salve select line to indicate the device on which encryption should be disabled.
2107 *
2108 * \return \ref cy_en_smif_status_t.
2109 *
2110 * \note Please ensure cache is disabled using \ref Cy_SMIF_CacheDisable or
2111 * invalidated using \ref Cy_SMIF_CacheInvalidate or any other system level cache to
2112 * be cleared so that the next read/execute from flash operation results in correct data.
2113 *
2114 *******************************************************************************/
Cy_SMIF_SetCryptoDisable(SMIF_Type * base,cy_en_smif_slave_select_t slaveId)2115 cy_en_smif_status_t Cy_SMIF_SetCryptoDisable(SMIF_Type *base, cy_en_smif_slave_select_t slaveId)
2116 {
2117 cy_en_smif_status_t ret = CY_SMIF_BAD_PARAM;
2118 uint32_t device_idx;
2119
2120 if (CY_SMIF_SUCCESS == Cy_SMIF_ConvertSlaveSlotToIndex(slaveId, &device_idx))
2121 {
2122 SMIF_DEVICE_IDX_CTL(base, device_idx) &= ~SMIF_DEVICE_CTL_CRYPTO_EN_Msk;
2123 ret = CY_SMIF_SUCCESS;
2124 }
2125 return ret;
2126 }
2127
2128 /*******************************************************************************
2129 * Function Name: Cy_SMIF_Encrypt()
2130 ****************************************************************************//**
2131 *
2132 * Uses the Encryption engine to create an encrypted result when the input, key
2133 * and data arrays are provided. The AES-128 encryption of the address with the
2134 * key, fetching the result and XOR with the data array are all done in the
2135 * function. The operational scheme is the following:
2136 * data = XOR(AES128(address, key), data)
2137 * Decryption is done using the input data-array identically to the encryption.
2138 * In the XIP mode, encryption and decryption are done without calling this
2139 * function. The operational scheme in the XIP mode is the same. The address
2140 * parameter in the XIP mode equals the actual address in the PSoC memory map.
2141 * The SMIF encryption engine is designed for code storage.
2142 * For data storage, the encryption key can be changed.
2143 * For sensitive data, the Crypto block is used.
2144 *
2145 * \note The API does not have access to the encryption key. The key must be
2146 * placed in the register using \ref Cy_SMIF_SetCryptoKey() before calling this API.
2147 * The crypto routine that can access the key storage area is recommended.
2148 * This crypto routine is typically a protection context 0 function.
2149 *
2150 * \note This is a blocking API. The API waits for encryption completion. Will
2151 * exit if a timeout is set (not equal to 0) and expired.
2152 *
2153 * \param base
2154 * Holds the base address of the SMIF block registers.
2155 *
2156 * \param address
2157 * The address that gets encrypted is a masked 16-byte block address. The 32-bit
2158 * address with the last 4 bits masked is placed as the last 4 bytes in the
2159 * 128-bit input. The rest of the higher bit for the 128 bits are padded zeros by default.
2160 * PA[127:0]:
2161 * PA[3:0] = 0
2162 * PA[7:4] = ADDR[7:4].
2163 * PA[15:8] = ADDR[15:8].
2164 * PA[23:16] = ADDR[23:16].
2165 * PA[31:24] = ADDR[31:24].
2166 * The other twelve of the sixteen plain text address bytes of PA[127:0] are "0" by default.
2167 * User can initialize PA[127:32] with \ref Cy_SMIF_SetCryptoIV().
2168 *
2169 * \param data
2170 * This is the location where the input data-array is passed while the function
2171 * is called. This array gets populated with the result after encryption is
2172 * completed.
2173 *
2174 * \param size
2175 * Provides a size of the array.
2176 *
2177 * \param context
2178 * Passes a configuration structure that contains the transfer parameters of the
2179 * SMIF block.
2180 *
2181 * \return A status of the command transmit.
2182 * - \ref CY_SMIF_SUCCESS
2183 * - \ref CY_SMIF_EXCEED_TIMEOUT
2184 * - \ref CY_SMIF_BAD_PARAM
2185 *
2186 * \funcusage
2187 * \snippet smif/snippet/main.c snippet_Cy_SMIF_Encrypt
2188 *
2189 *******************************************************************************/
Cy_SMIF_Encrypt(SMIF_Type * base,uint32_t address,uint8_t data[],uint32_t size,cy_stc_smif_context_t const * context)2190 cy_en_smif_status_t Cy_SMIF_Encrypt(SMIF_Type *base,
2191 uint32_t address,
2192 uint8_t data[],
2193 uint32_t size,
2194 cy_stc_smif_context_t const *context)
2195 {
2196 uint32_t bufIndex;
2197 cy_en_smif_status_t status = CY_SMIF_BAD_PARAM;
2198 uint32_t timeoutUnits = context->timeout;
2199
2200 CY_ASSERT_L2(size > 0U);
2201
2202 if((NULL != data) && ((address & (~CY_SMIF_CRYPTO_ADDR_MASK)) == 0UL) )
2203 {
2204 status = CY_SMIF_SUCCESS;
2205 /* Fill the output array */
2206 for(bufIndex = 0U; bufIndex < (size / CY_SMIF_AES128_BYTES); bufIndex++)
2207 {
2208 uint32_t dataIndex = bufIndex * CY_SMIF_AES128_BYTES;
2209 uint8_t cryptoOut[CY_SMIF_AES128_BYTES];
2210 uint32_t outIndex;
2211
2212 /* Fill the input field */
2213 SMIF_CRYPTO_INPUT0(base) = (uint32_t) (address +
2214 ((bufIndex * CY_SMIF_AES128_BYTES) & CY_SMIF_CRYPTO_ADDR_MASK));
2215
2216 /* Start the encryption */
2217 SMIF_CRYPTO_CMD(base) &= ~SMIF_CRYPTO_CMD_START_Msk;
2218 SMIF_CRYPTO_CMD(base) = (uint32_t)(_VAL2FLD(SMIF_CRYPTO_CMD_START,
2219 CY_SMIF_CRYPTO_START));
2220
2221 while((CY_SMIF_CRYPTO_COMPLETED != _FLD2VAL(SMIF_CRYPTO_CMD_START,
2222 SMIF_CRYPTO_CMD(base))) &&
2223 (CY_SMIF_EXCEED_TIMEOUT != status))
2224 {
2225 /* Wait until the encryption is completed and check the
2226 * timeout
2227 */
2228 status = Cy_SMIF_TimeoutRun(&timeoutUnits);
2229 }
2230
2231 if (CY_SMIF_EXCEED_TIMEOUT == status)
2232 {
2233 break;
2234 }
2235
2236 Cy_SMIF_UnPackByteArray(SMIF_CRYPTO_OUTPUT0(base),
2237 &cryptoOut[CY_SMIF_CRYPTO_FIRST_WORD] , true);
2238 Cy_SMIF_UnPackByteArray(SMIF_CRYPTO_OUTPUT1(base),
2239 &cryptoOut[CY_SMIF_CRYPTO_SECOND_WORD], true);
2240 Cy_SMIF_UnPackByteArray(SMIF_CRYPTO_OUTPUT2(base),
2241 &cryptoOut[CY_SMIF_CRYPTO_THIRD_WORD] , true);
2242 Cy_SMIF_UnPackByteArray(SMIF_CRYPTO_OUTPUT3(base),
2243 &cryptoOut[CY_SMIF_CRYPTO_FOURTH_WORD], true);
2244
2245 for(outIndex = 0U; outIndex < CY_SMIF_AES128_BYTES; outIndex++)
2246 {
2247 data[dataIndex + outIndex] ^= cryptoOut[outIndex];
2248 }
2249 }
2250 }
2251 return (status);
2252 }
2253
2254
2255 /*******************************************************************************
2256 * Function Name: Cy_SMIF_CacheEnable
2257 ****************************************************************************//**
2258 *
2259 * This function is used to enable the fast cache, the slow cache or both.
2260 *
2261 * \param base
2262 * Holds the base address of the SMIF block registers.
2263 *
2264 * \param cacheType
2265 * Holds the type of the cache to be modified. \ref cy_en_smif_cache_t
2266 *
2267 * \return A status of function completion.
2268 * - \ref CY_SMIF_SUCCESS
2269 * - \ref CY_SMIF_BAD_PARAM
2270 *
2271 *******************************************************************************/
Cy_SMIF_CacheEnable(SMIF_Type * base,cy_en_smif_cache_t cacheType)2272 cy_en_smif_status_t Cy_SMIF_CacheEnable(SMIF_Type *base,
2273 cy_en_smif_cache_t cacheType)
2274 {
2275 cy_en_smif_status_t status = CY_SMIF_SUCCESS;
2276 switch (cacheType)
2277 {
2278 case CY_SMIF_CACHE_SLOW:
2279 SMIF_SLOW_CA_CTL(base) |= SMIF_SLOW_CA_CTL_ENABLED_Msk;
2280 break;
2281 case CY_SMIF_CACHE_FAST:
2282 SMIF_FAST_CA_CTL(base) |= SMIF_FAST_CA_CTL_ENABLED_Msk;
2283 break;
2284 case CY_SMIF_CACHE_BOTH:
2285 SMIF_SLOW_CA_CTL(base) |= SMIF_SLOW_CA_CTL_ENABLED_Msk;
2286 SMIF_FAST_CA_CTL(base) |= SMIF_FAST_CA_CTL_ENABLED_Msk;
2287 break;
2288 default:
2289 /* A user error */
2290 status = CY_SMIF_BAD_PARAM;
2291 break;
2292 }
2293 return (status);
2294 }
2295
2296
2297 /*******************************************************************************
2298 * Function Name: Cy_SMIF_CacheDisable
2299 ****************************************************************************//**
2300 *
2301 * This function is used to disable the fast cache, the slow cache or both
2302 *
2303 * \param base
2304 * Holds the base address of the SMIF block registers.
2305 *
2306 * \param cacheType
2307 * Holds the type of the cache to be modified. \ref cy_en_smif_cache_t
2308 *
2309 * \return A status of function completion.
2310 * - \ref CY_SMIF_SUCCESS
2311 * - \ref CY_SMIF_BAD_PARAM
2312 *
2313 *******************************************************************************/
Cy_SMIF_CacheDisable(SMIF_Type * base,cy_en_smif_cache_t cacheType)2314 cy_en_smif_status_t Cy_SMIF_CacheDisable(SMIF_Type *base,
2315 cy_en_smif_cache_t cacheType)
2316 {
2317 cy_en_smif_status_t status = CY_SMIF_SUCCESS;
2318 switch (cacheType)
2319 {
2320 case CY_SMIF_CACHE_SLOW:
2321 SMIF_SLOW_CA_CTL(base) &= ~SMIF_SLOW_CA_CTL_ENABLED_Msk;
2322 break;
2323 case CY_SMIF_CACHE_FAST:
2324 SMIF_FAST_CA_CTL(base) &= ~SMIF_FAST_CA_CTL_ENABLED_Msk;
2325 break;
2326 case CY_SMIF_CACHE_BOTH:
2327 SMIF_SLOW_CA_CTL(base) &= ~SMIF_SLOW_CA_CTL_ENABLED_Msk;
2328 SMIF_FAST_CA_CTL(base) &= ~SMIF_FAST_CA_CTL_ENABLED_Msk;
2329 break;
2330 default:
2331 /* User error */
2332 status = CY_SMIF_BAD_PARAM;
2333 break;
2334 }
2335 return (status);
2336 }
2337
2338
2339 /*******************************************************************************
2340 * Function Name: Cy_SMIF_CachePrefetchingEnable
2341 ****************************************************************************//**
2342 *
2343 * This function is used to enable pre-fetching for the fast cache, the slow
2344 * cache or both.
2345 *
2346 * \param base
2347 * Holds the base address of the SMIF block registers.
2348 *
2349 * \param cacheType
2350 * Holds the type of the cache to be modified. \ref cy_en_smif_cache_t
2351 *
2352 * \return A status of function completion.
2353 * - \ref CY_SMIF_SUCCESS
2354 * - \ref CY_SMIF_BAD_PARAM
2355 *
2356 *******************************************************************************/
Cy_SMIF_CachePrefetchingEnable(SMIF_Type * base,cy_en_smif_cache_t cacheType)2357 cy_en_smif_status_t Cy_SMIF_CachePrefetchingEnable(SMIF_Type *base,
2358 cy_en_smif_cache_t cacheType)
2359 {
2360 cy_en_smif_status_t status = CY_SMIF_SUCCESS;
2361 switch (cacheType)
2362 {
2363 case CY_SMIF_CACHE_SLOW:
2364 SMIF_SLOW_CA_CTL(base) |= SMIF_SLOW_CA_CTL_PREF_EN_Msk;
2365 break;
2366 case CY_SMIF_CACHE_FAST:
2367 SMIF_FAST_CA_CTL(base) |= SMIF_FAST_CA_CTL_PREF_EN_Msk;
2368 break;
2369 case CY_SMIF_CACHE_BOTH:
2370 SMIF_SLOW_CA_CTL(base) |= SMIF_SLOW_CA_CTL_PREF_EN_Msk;
2371 SMIF_FAST_CA_CTL(base) |= SMIF_FAST_CA_CTL_PREF_EN_Msk;
2372 break;
2373 default:
2374 /* A user error */
2375 status = CY_SMIF_BAD_PARAM;
2376 break;
2377 }
2378 return (status);
2379 }
2380
2381
2382 /*******************************************************************************
2383 * Function Name: Cy_SMIF_CachePrefetchingDisable
2384 ****************************************************************************//**
2385 *
2386 * This function is used to disable pre-fetching for the fast cache, the slow
2387 * cache or both
2388 *
2389 * \param base
2390 * Holds the base address of the SMIF block registers.
2391 *
2392 * \param cacheType
2393 * Holds the type of the cache to be modified. \ref cy_en_smif_cache_t
2394 *
2395 * \return A status of function completion.
2396 * - \ref CY_SMIF_SUCCESS
2397 * - \ref CY_SMIF_BAD_PARAM
2398 *
2399 *******************************************************************************/
Cy_SMIF_CachePrefetchingDisable(SMIF_Type * base,cy_en_smif_cache_t cacheType)2400 cy_en_smif_status_t Cy_SMIF_CachePrefetchingDisable(SMIF_Type *base,
2401 cy_en_smif_cache_t cacheType)
2402 {
2403 cy_en_smif_status_t status = CY_SMIF_SUCCESS;
2404 switch (cacheType)
2405 {
2406 case CY_SMIF_CACHE_SLOW:
2407 SMIF_SLOW_CA_CTL(base) &= ~SMIF_SLOW_CA_CTL_PREF_EN_Msk;
2408 break;
2409 case CY_SMIF_CACHE_FAST:
2410 SMIF_FAST_CA_CTL(base) &= ~SMIF_FAST_CA_CTL_PREF_EN_Msk;
2411 break;
2412 case CY_SMIF_CACHE_BOTH:
2413 SMIF_SLOW_CA_CTL(base) &= ~SMIF_SLOW_CA_CTL_PREF_EN_Msk;
2414 SMIF_FAST_CA_CTL(base) &= ~SMIF_FAST_CA_CTL_PREF_EN_Msk;
2415 break;
2416 default:
2417 /* A user error */
2418 status = CY_SMIF_BAD_PARAM;
2419 break;
2420 }
2421 return (status);
2422 }
2423
2424
2425 /*******************************************************************************
2426 * Function Name: Cy_SMIF_CacheInvalidate
2427 ****************************************************************************//**
2428 *
2429 * This function is used to invalidate/clear the fast cache, the slow cache or
2430 * both
2431 *
2432 * \param base
2433 * Holds the base address of the SMIF block registers.
2434 *
2435 * \param cacheType
2436 * Holds the type of the cache to be modified. \ref cy_en_smif_cache_t
2437 *
2438 * \return A status of function completion.
2439 * - \ref CY_SMIF_SUCCESS
2440 * - \ref CY_SMIF_BAD_PARAM
2441 *
2442 *******************************************************************************/
Cy_SMIF_CacheInvalidate(SMIF_Type * base,cy_en_smif_cache_t cacheType)2443 cy_en_smif_status_t Cy_SMIF_CacheInvalidate(SMIF_Type *base,
2444 cy_en_smif_cache_t cacheType)
2445 {
2446 cy_en_smif_status_t status = CY_SMIF_SUCCESS;
2447 switch (cacheType)
2448 {
2449 case CY_SMIF_CACHE_SLOW:
2450 SMIF_SLOW_CA_CMD(base) |= SMIF_SLOW_CA_CMD_INV_Msk;
2451 break;
2452 case CY_SMIF_CACHE_FAST:
2453 SMIF_FAST_CA_CMD(base) |= SMIF_FAST_CA_CMD_INV_Msk;
2454 break;
2455 case CY_SMIF_CACHE_BOTH:
2456 SMIF_SLOW_CA_CMD(base) |= SMIF_SLOW_CA_CMD_INV_Msk;
2457 SMIF_FAST_CA_CMD(base) |= SMIF_FAST_CA_CMD_INV_Msk;
2458 break;
2459 default:
2460 /* A user error */
2461 status = CY_SMIF_BAD_PARAM;
2462 break;
2463 }
2464 return (status);
2465 }
2466
2467 #if (CY_IP_MXSMIF_VERSION>=4) || defined (CY_DOXYGEN)
2468 /*******************************************************************************
2469 * Function Name: Cy_SMIF_SetRxCaptureMode
2470 ****************************************************************************//**
2471 * This function sets the Rx Capture mode setting for SMIF IP block instance
2472 *
2473 * \param base
2474 * Holds the base address of the SMIF block registers.
2475 *
2476 * \param mode
2477 * Rx Capture mode \ref cy_en_smif_capture_mode_t
2478 *
2479 * \param slaveId
2480 * Slave ID for which RX Capture configuration has to be updated.
2481 *
2482 * \snippet smif/snippet/main.c snippet_SMIF_DLP
2483 *
2484 * \note
2485 * This API is available for CAT1D and CAT1C (TVIIC only) devices.
2486 *******************************************************************************/
Cy_SMIF_SetRxCaptureMode(SMIF_Type * base,cy_en_smif_capture_mode_t mode,cy_en_smif_slave_select_t slaveId)2487 cy_en_smif_status_t Cy_SMIF_SetRxCaptureMode(SMIF_Type *base, cy_en_smif_capture_mode_t mode, cy_en_smif_slave_select_t slaveId)
2488 {
2489 CY_ASSERT_L1(NULL != base);
2490 uint32_t device_idx;
2491
2492 /* RX CAPTURE MODE cannot be changed when IP is in enabled state */
2493 if ((SMIF_CTL(base) & SMIF_CTL_ENABLED_Msk) != 0U)
2494 {
2495 return CY_SMIF_BAD_PARAM;
2496 }
2497 else
2498 {
2499 SMIF_CTL2(base) &= ~SMIF_CORE_CTL2_RX_CAPTURE_MODE_Msk;
2500 SMIF_CTL2(base) |= _VAL2FLD(SMIF_CORE_CTL2_RX_CAPTURE_MODE, (uint32_t)mode);
2501
2502 /* For RX Capture MODE 2, DDR_PIPELINE_POS_DAT must be set to 1 */
2503 if (CY_SMIF_SUCCESS == Cy_SMIF_ConvertSlaveSlotToIndex(slaveId, &device_idx))
2504 {
2505 SMIF_DEVICE_IDX_RX_CAPTURE_CONFIG(base, device_idx) |= SMIF_CORE_DEVICE_RX_CAPTURE_CONFIG_DDR_PIPELINE_POS_DAT_Msk;
2506 }
2507
2508 return CY_SMIF_SUCCESS;
2509 }
2510 }
2511 #endif /* (CY_IP_MXSMIF_VERSION>=4) || defined (CY_DOXYGEN) */
2512
2513 #if ((CY_IP_MXSMIF_VERSION>=4) && (defined (SMIF_DLP_PRESENT) && (SMIF_DLP_PRESENT > 0))) || defined (CY_DOXYGEN)
2514 /*******************************************************************************
2515 * Function Name: Cy_SMIF_SetMasterDLP
2516 ****************************************************************************//**
2517 * This function sets the data learning pattern
2518 *
2519 * \param base
2520 * Holds the base address of the SMIF block registers.
2521 *
2522 * \param dlp
2523 * data learning pattern (maximum 16-bit)
2524 *
2525 * \param size
2526 * pattern size (allowed range 1 to 16 bits)
2527 *
2528 * \return status of configuration.
2529 * - \ref CY_SMIF_SUCCESS
2530 * - \ref CY_SMIF_BAD_PARAM
2531 *
2532 * \snippet smif/snippet/main.c snippet_SMIF_DLP
2533 *
2534 * \note
2535 * This API is available for CAT1D and CAT1C (TVIIC only) devices with Rx Capture mode set to \ref CY_SMIF_SEL_NORMAL_SPI_WITH_DLP
2536 *******************************************************************************/
Cy_SMIF_SetMasterDLP(SMIF_Type * base,uint16 dlp,uint8_t size)2537 cy_en_smif_status_t Cy_SMIF_SetMasterDLP(SMIF_Type *base, uint16 dlp, uint8_t size)
2538 {
2539 cy_en_smif_status_t status = CY_SMIF_SUCCESS;
2540
2541 CY_ASSERT_L1(NULL != base);
2542
2543 if ((size == 0U) || (size > 16U))
2544 {
2545 status = CY_SMIF_BAD_PARAM;
2546 }
2547
2548 if ( status == CY_SMIF_SUCCESS)
2549 {
2550 /* Clear values before writing user provided inputs */
2551 SMIF_DLP_CTL(base) = (_VAL2FLD(SMIF_CORE_DLP_CTL_DLP, 0) |
2552 _VAL2FLD(SMIF_CORE_DLP_CTL_DLP_SIZE, 0));
2553
2554 /* Configure user inputs */
2555 SMIF_DLP_CTL(base) = (_VAL2FLD(SMIF_CORE_DLP_CTL_DLP, dlp) |
2556 _VAL2FLD(SMIF_CORE_DLP_CTL_DLP_SIZE, (uint32_t)size - 1UL));
2557 }
2558 return status;
2559 }
2560 /*******************************************************************************
2561 * Function Name: Cy_SMIF_GetMasterDLP
2562 ****************************************************************************//**
2563 * This function gets the data learning pattern configured.
2564 *
2565 * \param base
2566 * Holds the base address of the SMIF block registers.
2567 *
2568 * \return Data learning pattern configured
2569 *
2570 *
2571 * \snippet smif/snippet/main.c snippet_SMIF_DLP
2572 *
2573 * \note
2574 * This API is available for CAT1D and CAT1C (TVIIC only) devices.
2575 *******************************************************************************/
Cy_SMIF_GetMasterDLP(SMIF_Type * base)2576 uint16_t Cy_SMIF_GetMasterDLP(SMIF_Type *base)
2577 {
2578 return (uint16_t)_FLD2VAL(SMIF_CORE_DLP_CTL_DLP, SMIF_DLP_CTL(base));
2579 }
2580 /*******************************************************************************
2581 * Function Name: Cy_SMIF_GetMasterDLPSize
2582 ****************************************************************************//**
2583 * This function gets the data learning pattern size configured.
2584 *
2585 * \param base
2586 * Holds the base address of the SMIF block registers.
2587 *
2588 * \return Data learning pattern size configured.
2589 *
2590 * \snippet smif/snippet/main.c snippet_SMIF_DLP
2591 *
2592 * \note
2593 * This API is available for CAT1D and CAT1C (TVIIC only) devices.
2594 *******************************************************************************/
Cy_SMIF_GetMasterDLPSize(SMIF_Type * base)2595 uint8_t Cy_SMIF_GetMasterDLPSize(SMIF_Type *base)
2596 {
2597 return (uint8_t)(_FLD2VAL(SMIF_CORE_DLP_CTL_DLP_SIZE, SMIF_DLP_CTL(base)) + 1U);
2598 }
2599 /*******************************************************************************
2600 * Function Name: Cy_SMIF_GetTapNumCapturedCorrectDLP
2601 ****************************************************************************//**
2602 * This function gets number of delay taps used for specified data line.
2603 *
2604 * \param base
2605 * Holds the base address of the SMIF block registers.
2606 *
2607 * \param bit
2608 * DLP Tap selection for the bit position mapped as per \ref Cy_SMIF_SetDataSelect.
2609 *
2610 * \return Data learning pattern configured
2611 *
2612 * \snippet smif/snippet/main.c snippet_Cy_SMIF_GetTapNumCapturedCorrectDLP
2613 *
2614 * \note
2615 * This API is available for CAT1D and CAT1C (TVIIC only) devices.
2616 *******************************************************************************/
Cy_SMIF_GetTapNumCapturedCorrectDLP(SMIF_Type * base,uint8_t bit)2617 uint8_t Cy_SMIF_GetTapNumCapturedCorrectDLP(SMIF_Type *base, uint8_t bit)
2618 {
2619 uint32_t delay_tap = 0;
2620
2621 switch(bit)
2622 {
2623 case 0:
2624 {
2625 delay_tap = _FLD2VAL(SMIF_CORE_DLP_DELAY_TAP_SEL0_DATA_BIT0_TAP_SEL, SMIF_DLP_DELAY_TAP_SEL0(base));
2626 }
2627 break;
2628 case 1:
2629 {
2630 delay_tap = _FLD2VAL(SMIF_CORE_DLP_DELAY_TAP_SEL0_DATA_BIT1_TAP_SEL, SMIF_DLP_DELAY_TAP_SEL0(base));
2631 }
2632 break;
2633 case 2:
2634 {
2635 delay_tap = _FLD2VAL(SMIF_CORE_DLP_DELAY_TAP_SEL0_DATA_BIT2_TAP_SEL, SMIF_DLP_DELAY_TAP_SEL0(base));
2636 }
2637 break;
2638 case 3:
2639 {
2640 delay_tap = _FLD2VAL(SMIF_CORE_DLP_DELAY_TAP_SEL0_DATA_BIT3_TAP_SEL, SMIF_DLP_DELAY_TAP_SEL0(base));
2641 }
2642 break;
2643 case 4:
2644 {
2645 delay_tap = _FLD2VAL(SMIF_CORE_DLP_DELAY_TAP_SEL1_DATA_BIT4_TAP_SEL, SMIF_DLP_DELAY_TAP_SEL1(base));
2646 }
2647 break;
2648 case 5:
2649 {
2650 delay_tap = _FLD2VAL(SMIF_CORE_DLP_DELAY_TAP_SEL1_DATA_BIT5_TAP_SEL, SMIF_DLP_DELAY_TAP_SEL1(base));
2651 }
2652 break;
2653 case 6:
2654 {
2655 delay_tap = _FLD2VAL(SMIF_CORE_DLP_DELAY_TAP_SEL1_DATA_BIT6_TAP_SEL, SMIF_DLP_DELAY_TAP_SEL1(base));
2656 }
2657 break;
2658 case 7:
2659 {
2660 delay_tap = _FLD2VAL(SMIF_CORE_DLP_DELAY_TAP_SEL1_DATA_BIT7_TAP_SEL, SMIF_DLP_DELAY_TAP_SEL1(base));
2661 }
2662 break;
2663 default:
2664 delay_tap = 0;
2665 break;
2666 }
2667 return (uint8_t)delay_tap;
2668 }
2669 #endif /* ((CY_IP_MXSMIF_VERSION>=4) && (defined (SMIF_DLP_PRESENT) && (SMIF_DLP_PRESENT > 0))) || defined (CY_DOXYGEN) */
2670
2671 #if (CY_IP_MXSMIF_VERSION>=2) || defined (CY_DOXYGEN)
2672 /*******************************************************************************
2673 * Function Name: Cy_SMIF_DeviceTransfer_SetMergeTimeout
2674 ****************************************************************************//**
2675 *
2676 * This function enables merging continuous transfers over XIP so that the overhead
2677 * of transferring command and address will not be there for reading consecutive addresses.
2678 * User can specify a timeout value to specify how long the device would be selected waiting
2679 * for next incremental address read.
2680 *
2681 * \param base
2682 * Holds the base address of the SMIF block registers.
2683 *
2684 * \param slave
2685 * Holds the slave select line for which merge should be enabled.
2686 *
2687 * \param timeout (see \ref cy_en_smif_merge_timeout_t)
2688 *
2689 * \note This API is not supported on CAT1A devices.
2690 * \note External memory should also support this mode of transfer.
2691 *
2692 * \snippet smif/snippet/main.c snippet_Cy_SMIF_MergeTimeout
2693 *******************************************************************************/
Cy_SMIF_DeviceTransfer_SetMergeTimeout(SMIF_Type * base,cy_en_smif_slave_select_t slave,cy_en_smif_merge_timeout_t timeout)2694 void Cy_SMIF_DeviceTransfer_SetMergeTimeout(SMIF_Type *base, cy_en_smif_slave_select_t slave, cy_en_smif_merge_timeout_t timeout)
2695 {
2696 SMIF_DEVICE_Type volatile * device = Cy_SMIF_GetDeviceBySlot(base, slave);
2697 uint32_t temp;
2698 temp = SMIF_DEVICE_CTL(device);
2699 temp &= ~(SMIF_DEVICE_CTL_MERGE_TIMEOUT_Msk);
2700 SMIF_DEVICE_CTL(device) = temp | _VAL2FLD(SMIF_DEVICE_CTL_MERGE_EN, 1U) |
2701 _VAL2FLD(SMIF_DEVICE_CTL_MERGE_TIMEOUT, (uint32_t)timeout);
2702 }
2703
2704 /*******************************************************************************
2705 * Function Name: Cy_SMIF_DeviceTransfer_ClearMergeTimeout
2706 ****************************************************************************//**
2707 *
2708 * This function disables continuous transfer merging.
2709 *
2710 * \param base
2711 * Holds the base address of the SMIF block registers.
2712 *
2713 * \param slave
2714 * Holds the slave select line for which merge should be disabled.
2715 *
2716 * \note This API is not supported on CAT1A devices.
2717 * \note External memory should also support this mode of transfer.
2718 *
2719 * \snippet smif/snippet/main.c snippet_Cy_SMIF_MergeTimeout
2720 *******************************************************************************/
Cy_SMIF_DeviceTransfer_ClearMergeTimeout(SMIF_Type * base,cy_en_smif_slave_select_t slave)2721 void Cy_SMIF_DeviceTransfer_ClearMergeTimeout(SMIF_Type *base, cy_en_smif_slave_select_t slave)
2722 {
2723 SMIF_DEVICE_Type volatile * device = Cy_SMIF_GetDeviceBySlot(base, slave);
2724 uint32_t temp;
2725 temp = SMIF_DEVICE_CTL(device);
2726 temp &= ~(SMIF_DEVICE_CTL_MERGE_EN_Msk | SMIF_DEVICE_CTL_MERGE_TIMEOUT_Msk);
2727 SMIF_DEVICE_CTL(device) = temp;
2728 }
2729 #endif /* (CY_IP_MXSMIF_VERSION>=2) || defined (CY_DOXYGEN) */
2730
2731 #if (CY_IP_MXSMIF_VERSION>=5) || defined (CY_DOXYGEN)
2732 /*******************************************************************************
2733 * Function Name: Cy_SMIF_SetSelectedDelayTapSel
2734 ****************************************************************************//**
2735 *
2736 * This function sets delay tap for a particular data line.
2737 *
2738 * \param base
2739 * Holds the base address of the SMIF block registers.
2740 *
2741 * \param slave
2742 * Holds the slave select line for which delay tap setting should be applied for.
2743 *
2744 * \param data_line
2745 * Holds the data line for which delay tap setting should be applied for.
2746 *
2747 * \param tapSel
2748 * tap selection value where lower nibble indicates the delay tap setting for positive clock phase
2749 * and higher nibble indicates the setting for negative clock phase delay tap selection.
2750 *
2751 * \return \ref cy_en_smif_status_t.
2752 *
2753 * \note This API is supported on CAT1D devices.
2754 *
2755 *******************************************************************************/
Cy_SMIF_SetSelectedDelayTapSel(SMIF_Type * base,cy_en_smif_slave_select_t slave,cy_en_smif_mem_data_line_t data_line,uint8_t tapSel)2756 cy_en_smif_status_t Cy_SMIF_SetSelectedDelayTapSel(SMIF_Type *base,
2757 cy_en_smif_slave_select_t slave,
2758 cy_en_smif_mem_data_line_t data_line,
2759 uint8_t tapSel)
2760 {
2761 cy_en_smif_status_t result = CY_SMIF_GENERAL_ERROR;
2762
2763 SMIF_DEVICE_Type volatile * device = Cy_SMIF_GetDeviceBySlot(base, slave);
2764
2765 /* Check if DEVICE is in FW CALIBRATION MODE */
2766 if ((SMIF_DEVICE_RX_CAPTURE_CONFIG(device) & SMIF_CORE_DEVICE_RX_CAPTURE_CONFIG_FW_CALIBRATION_MODE_Msk) != 0UL)
2767 {
2768 result = CY_SMIF_SUCCESS;
2769
2770 switch(data_line)
2771 {
2772 case CY_SMIF_DATA_BIT0_TAP_SEL:
2773 {
2774 SMIF_DEVICE_HB_FW_DEL_TAP_SEL_0(device) = _VAL2FLD(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_0_DATA_BIT0_TAP_SEL_POS, tapSel);
2775 break;
2776 }
2777 case CY_SMIF_DATA_BIT1_TAP_SEL:
2778 {
2779 SMIF_DEVICE_HB_FW_DEL_TAP_SEL_0(device) = _VAL2FLD(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_0_DATA_BIT1_TAP_SEL_POS, tapSel);
2780 break;
2781 }
2782 case CY_SMIF_DATA_BIT2_TAP_SEL:
2783 {
2784 SMIF_DEVICE_HB_FW_DEL_TAP_SEL_0(device) = _VAL2FLD(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_0_DATA_BIT2_TAP_SEL_POS, tapSel);
2785 break;
2786 }
2787 case CY_SMIF_DATA_BIT3_TAP_SEL:
2788 {
2789 SMIF_DEVICE_HB_FW_DEL_TAP_SEL_0(device) = _VAL2FLD(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_0_DATA_BIT3_TAP_SEL_POS, tapSel);
2790 break;
2791 }
2792 case CY_SMIF_DATA_BIT4_TAP_SEL:
2793 {
2794 SMIF_DEVICE_HB_FW_DEL_TAP_SEL_1(device) = _VAL2FLD(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_1_DATA_BIT4_TAP_SEL_POS, tapSel);
2795 break;
2796 }
2797 case CY_SMIF_DATA_BIT5_TAP_SEL:
2798 {
2799 SMIF_DEVICE_HB_FW_DEL_TAP_SEL_1(device) = _VAL2FLD(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_1_DATA_BIT5_TAP_SEL_POS, tapSel);
2800 break;
2801 }
2802 case CY_SMIF_DATA_BIT6_TAP_SEL:
2803 {
2804 SMIF_DEVICE_HB_FW_DEL_TAP_SEL_1(device) = _VAL2FLD(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_1_DATA_BIT6_TAP_SEL_POS, tapSel);
2805 break;
2806 }
2807 case CY_SMIF_DATA_BIT7_TAP_SEL:
2808 {
2809 SMIF_DEVICE_HB_FW_DEL_TAP_SEL_1(device) = _VAL2FLD(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_1_DATA_BIT7_TAP_SEL_POS, tapSel);
2810 break;
2811 }
2812 default:
2813 {
2814 /* Unsupported data line index */
2815 break;
2816 }
2817 }
2818 }
2819
2820 return result;
2821 }
2822 /*******************************************************************************
2823 * Function Name: Cy_SMIF_GetSelectedDelayTapSel
2824 ****************************************************************************//**
2825 *
2826 * This function gets delay tap set for a particular data line.
2827 *
2828 * \param base
2829 * Holds the base address of the SMIF block registers.
2830 *
2831 * \param slave
2832 * Holds the slave select line for which delay tap setting should be retrieved.
2833 *
2834 * \param data_line
2835 * Holds the data line for which delay tap setting should be retrieved.
2836 *
2837 * \return uint8_t
2838 * tap selection value where lower nibble indicates the delay tap setting for positive clock phase
2839 * and higher nibble indicates the setting for negative clock phase delay tap selection.
2840 *
2841 * \note This API is supported on CAT1D devices.
2842 *
2843 *******************************************************************************/
Cy_SMIF_GetSelectedDelayTapSel(SMIF_Type * base,cy_en_smif_slave_select_t slave,cy_en_smif_mem_data_line_t data_line)2844 uint8_t Cy_SMIF_GetSelectedDelayTapSel(SMIF_Type *base, cy_en_smif_slave_select_t slave, cy_en_smif_mem_data_line_t data_line)
2845 {
2846 SMIF_DEVICE_Type volatile * device = Cy_SMIF_GetDeviceBySlot(base, slave);
2847 uint8_t delay_tap = 0;
2848
2849 switch(data_line)
2850 {
2851 case CY_SMIF_DATA_BIT0_TAP_SEL:
2852 {
2853 delay_tap =(uint8_t)(_FLD2VAL(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_0_DATA_BIT0_TAP_SEL_POS, SMIF_DEVICE_HB_FW_DEL_TAP_SEL_0(device)));
2854 break;
2855 }
2856 case CY_SMIF_DATA_BIT1_TAP_SEL:
2857 {
2858 delay_tap = (uint8_t)(_FLD2VAL(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_0_DATA_BIT1_TAP_SEL_POS, SMIF_DEVICE_HB_FW_DEL_TAP_SEL_0(device)));
2859 break;
2860 }
2861 case CY_SMIF_DATA_BIT2_TAP_SEL:
2862 {
2863 delay_tap = (uint8_t)(_FLD2VAL(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_0_DATA_BIT2_TAP_SEL_POS, SMIF_DEVICE_HB_FW_DEL_TAP_SEL_0(device)));
2864 break;
2865 }
2866 case CY_SMIF_DATA_BIT3_TAP_SEL:
2867 {
2868 delay_tap = (uint8_t)(_FLD2VAL(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_0_DATA_BIT3_TAP_SEL_POS, SMIF_DEVICE_HB_FW_DEL_TAP_SEL_0(device)));
2869 break;
2870 }
2871 case CY_SMIF_DATA_BIT4_TAP_SEL:
2872 {
2873 delay_tap = (uint8_t)(_FLD2VAL(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_1_DATA_BIT4_TAP_SEL_POS, SMIF_DEVICE_HB_FW_DEL_TAP_SEL_1(device)));
2874 break;
2875 }
2876 case CY_SMIF_DATA_BIT5_TAP_SEL:
2877 {
2878 delay_tap = (uint8_t)(_FLD2VAL(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_1_DATA_BIT5_TAP_SEL_POS, SMIF_DEVICE_HB_FW_DEL_TAP_SEL_1(device)));
2879 break;
2880 }
2881 case CY_SMIF_DATA_BIT6_TAP_SEL:
2882 {
2883 delay_tap = (uint8_t)(_FLD2VAL(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_1_DATA_BIT6_TAP_SEL_POS, SMIF_DEVICE_HB_FW_DEL_TAP_SEL_1(device)));
2884 break;
2885 }
2886 case CY_SMIF_DATA_BIT7_TAP_SEL:
2887 {
2888 delay_tap = (uint8_t)(_FLD2VAL(SMIF_CORE_DEVICE_HB_FW_DEL_TAP_SEL_1_DATA_BIT7_TAP_SEL_POS, SMIF_DEVICE_HB_FW_DEL_TAP_SEL_1(device)));
2889 break;
2890 }
2891 default:
2892 {
2893 /* Unsupported data line index */
2894 break;
2895 }
2896 }
2897 return delay_tap;
2898 }
2899
2900 #endif
2901
2902 #if defined (CY_IP_MXS40SRSS) || defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS)
2903 /*******************************************************************************
2904 * Function Name: Cy_SMIF_DeepSleepCallback
2905 ****************************************************************************//**
2906 *
2907 * This function handles the transition of the SMIF into and out of Deep
2908 * Sleep mode. It prevents the device from entering DeepSleep if SMIF is actively
2909 * communicating, or there is any data in the TX or RX FIFOs, or SMIF is in
2910 * memory mode.
2911 *
2912 * This function should be called while execution of \ref Cy_SysPm_CpuEnterDeepSleep
2913 * therefore must be registered as a callback before the call. To register it
2914 * call \ref Cy_SysPm_RegisterCallback and specify \ref CY_SYSPM_DEEPSLEEP
2915 * as the callback type.
2916 *
2917 * \note
2918 * This API is template and user should add code for external memory enter/exit
2919 * low power mode.
2920 *
2921 * \param callbackParams
2922 * The pointer to the structure with SMIF SysPm callback parameters (pointer to
2923 * SMIF registers, context and call mode \ref cy_stc_syspm_callback_params_t).
2924 *
2925 * \param mode
2926 * Callback mode, see \ref cy_en_syspm_callback_mode_t
2927 *
2928 * \return
2929 * \ref cy_en_syspm_status_t
2930 *
2931 * Example setup of SysPM deep sleep and hibernate mode
2932 * \snippet smif/snippet/main.c SMIF SysPM Callback
2933 *
2934 *******************************************************************************/
Cy_SMIF_DeepSleepCallback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)2935 cy_en_syspm_status_t Cy_SMIF_DeepSleepCallback(cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode)
2936 {
2937 cy_en_syspm_status_t retStatus = CY_SYSPM_SUCCESS;
2938
2939 CY_ASSERT_L1(NULL != callbackParams);
2940
2941 SMIF_Type *locBase = (SMIF_Type *) callbackParams->base;
2942 cy_stc_smif_context_t *locContext = (cy_stc_smif_context_t *) callbackParams->context;
2943
2944 switch(mode)
2945 {
2946 case CY_SYSPM_CHECK_READY:
2947 {
2948 /* Check if API is not busy executing transfer operation */
2949 /* If SPI bus is not busy, all data elements are transferred on
2950 * the bus from the TX FIFO and shifter and the RX FIFIOs is
2951 * empty - the SPI is ready enter Deep Sleep.
2952 */
2953 bool checkFail = (CY_SMIF_RX_BUSY == (cy_en_smif_txfr_status_t)
2954 Cy_SMIF_GetTransferStatus(locBase, locContext));
2955 checkFail = (Cy_SMIF_BusyCheck(locBase)) || checkFail;
2956 checkFail = (Cy_SMIF_GetMode(locBase) == CY_SMIF_MEMORY) || checkFail;
2957
2958 if (checkFail)
2959 {
2960 retStatus = CY_SYSPM_FAIL;
2961 }
2962 else
2963 {
2964 #if (CY_IP_MXSMIF_VERSION == 5u) || (CY_IP_MXSMIF_VERSION == 4u)
2965 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE0)
2966 {
2967 (void)Cy_SysClk_ClkHfDisable(CY_SMIF_CORE_0_HF);
2968 }
2969 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE1)
2970 {
2971 (void)Cy_SysClk_ClkHfDisable(CY_SMIF_CORE_1_HF);
2972 }
2973 #endif
2974 Cy_SMIF_Disable(locBase);
2975 retStatus = CY_SYSPM_SUCCESS;
2976 }
2977 /* Add check memory that memory not in progress */
2978 }
2979 break;
2980
2981 case CY_SYSPM_CHECK_FAIL:
2982 {
2983 /* Other driver is not ready for Deep Sleep. Restore Active mode
2984 * configuration.
2985 */
2986 #if (CY_IP_MXSMIF_VERSION == 5u) || (CY_IP_MXSMIF_VERSION == 4u)
2987 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE0)
2988 {
2989 (void)Cy_SysClk_ClkHfEnable(CY_SMIF_CORE_0_HF);
2990 }
2991 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE1)
2992 {
2993 (void)Cy_SysClk_ClkHfEnable(CY_SMIF_CORE_1_HF);
2994 }
2995 #endif
2996 Cy_SMIF_Enable(locBase, locContext);
2997
2998 }
2999 break;
3000
3001 case CY_SYSPM_BEFORE_TRANSITION:
3002 {
3003 /* This code executes inside critical section and enabling active
3004 * interrupt source makes interrupt pending in the NVIC. However
3005 * interrupt processing is delayed until code exists critical
3006 * section. The pending interrupt force WFI instruction does
3007 * nothing and device remains in the active mode.
3008 */
3009
3010 /* Put external memory in low power mode */
3011 }
3012 break;
3013
3014 case CY_SYSPM_AFTER_TRANSITION:
3015 {
3016 #if (CY_IP_MXSMIF_VERSION == 5u) || (CY_IP_MXSMIF_VERSION == 4u)
3017 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE0)
3018 {
3019 (void)Cy_SysClk_ClkHfEnable(CY_SMIF_CORE_0_HF);
3020 }
3021 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE1)
3022 {
3023 (void)Cy_SysClk_ClkHfEnable(CY_SMIF_CORE_1_HF);
3024 }
3025 #endif
3026 /* Put external memory in active mode */
3027 Cy_SMIF_Enable(locBase, locContext);
3028 }
3029 break;
3030
3031 default:
3032 retStatus = CY_SYSPM_FAIL;
3033 break;
3034 }
3035
3036 return (retStatus);
3037 }
3038
3039
3040 /*******************************************************************************
3041 * Function Name: Cy_SMIF_HibernateCallback
3042 ****************************************************************************//**
3043 *
3044 * This function handles the transition of the SMIF into Hibernate mode.
3045 * It prevents the device from entering Hibernate if the SMIF
3046 * is actively communicating, or there is any data in the TX or RX FIFO, or SMIF
3047 * is in memory mode.
3048 *
3049 * This function should be called during execution of \ref Cy_SysPm_SystemEnterHibernate
3050 * therefore it must be registered as a callback before the call. To register it
3051 * call \ref Cy_SysPm_RegisterCallback and specify \ref CY_SYSPM_HIBERNATE
3052 * as the callback type.
3053 *
3054 * \note
3055 * This API is template and user should add code for external memory enter/exit
3056 * low power mode.
3057 *
3058 * \param callbackParams
3059 * The pointer to the structure with SMIF SysPm callback parameters (pointer to
3060 * SMIF registers, context and call mode \ref cy_stc_syspm_callback_params_t).
3061 *
3062 * \param mode
3063 * Callback mode, see \ref cy_en_syspm_callback_mode_t
3064 *
3065 * \return
3066 * \ref cy_en_syspm_status_t
3067 *
3068 * Example setup of SysPM deep sleep and hibernate mode
3069 * \snippet smif/snippet/main.c SMIF SysPM Callback
3070 *
3071 *******************************************************************************/
Cy_SMIF_HibernateCallback(cy_stc_syspm_callback_params_t * callbackParams,cy_en_syspm_callback_mode_t mode)3072 cy_en_syspm_status_t Cy_SMIF_HibernateCallback(cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode)
3073 {
3074 cy_en_syspm_status_t retStatus = CY_SYSPM_SUCCESS;
3075
3076 CY_ASSERT_L1(NULL != callbackParams);
3077
3078 SMIF_Type *locBase = (SMIF_Type *) callbackParams->base;
3079 cy_stc_smif_context_t *locContext = (cy_stc_smif_context_t *) callbackParams->context;
3080
3081 switch(mode)
3082 {
3083 case CY_SYSPM_CHECK_READY:
3084 {
3085 /* Check if API is not busy executing transfer operation
3086 * If SPI bus is not busy, all data elements are transferred on
3087 * the bus from the TX FIFO and shifter and the RX FIFIOs is
3088 * empty - the SPI is ready enter Deep Sleep.
3089 */
3090 bool checkFail = (CY_SMIF_RX_BUSY == (cy_en_smif_txfr_status_t)
3091 Cy_SMIF_GetTransferStatus(locBase, locContext));
3092 checkFail = (Cy_SMIF_BusyCheck(locBase)) || checkFail;
3093 checkFail = (Cy_SMIF_GetMode(locBase) == CY_SMIF_MEMORY) || checkFail;
3094
3095 if (checkFail)
3096 {
3097 retStatus = CY_SYSPM_FAIL;
3098
3099 }
3100 else
3101 {
3102 retStatus = CY_SYSPM_SUCCESS;
3103 #if (CY_IP_MXSMIF_VERSION == 5u) || (CY_IP_MXSMIF_VERSION == 4u)
3104 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE0)
3105 {
3106 (void)Cy_SysClk_ClkHfDisable(CY_SMIF_CORE_0_HF);
3107 }
3108 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE1)
3109 {
3110 (void)Cy_SysClk_ClkHfDisable(CY_SMIF_CORE_1_HF);
3111 }
3112 #endif
3113 Cy_SMIF_Disable(locBase);
3114 }
3115 /* Add check memory that memory not in progress */
3116 }
3117 break;
3118
3119 case CY_SYSPM_CHECK_FAIL:
3120 {
3121 /* Other driver is not ready for Deep Sleep. Restore Active mode
3122 * configuration.
3123 */
3124 #if (CY_IP_MXSMIF_VERSION == 5u) || (CY_IP_MXSMIF_VERSION == 4u)
3125 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE0)
3126 {
3127 (void)Cy_SysClk_ClkHfEnable(CY_SMIF_CORE_0_HF);
3128 }
3129 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE1)
3130 {
3131 (void)Cy_SysClk_ClkHfEnable(CY_SMIF_CORE_1_HF);
3132 }
3133 #endif
3134 Cy_SMIF_Enable(locBase, locContext);
3135
3136 }
3137 break;
3138
3139 case CY_SYSPM_BEFORE_TRANSITION:
3140 {
3141 /* Put external memory in low power mode */
3142 }
3143 break;
3144
3145 case CY_SYSPM_AFTER_TRANSITION:
3146 {
3147 #if (CY_IP_MXSMIF_VERSION == 5u) || (CY_IP_MXSMIF_VERSION == 4u)
3148 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE0)
3149 {
3150 (void)Cy_SysClk_ClkHfEnable(CY_SMIF_CORE_0_HF);
3151 }
3152 if ((SMIF_CORE_Type *)locBase == (SMIF_CORE_Type *)SMIF0_CORE1)
3153 {
3154 (void)Cy_SysClk_ClkHfEnable(CY_SMIF_CORE_1_HF);
3155 }
3156 #endif
3157
3158 Cy_SMIF_Enable(locBase, locContext);
3159 /* Put external memory in active mode */
3160
3161 }
3162 break;
3163
3164 default:
3165 retStatus = CY_SYSPM_FAIL;
3166 break;
3167 }
3168
3169 return (retStatus);
3170 }
3171
3172
3173 #if (CY_IP_MXSMIF_VERSION == 2U)
3174 /*******************************************************************************
3175 * Function Name: Cy_SMIF_Set_DelayTapSel
3176 ****************************************************************************//**
3177 *
3178 * This function sets delay tap number for the SMIF (common for all its devices).
3179 * To ensure compatibility with users of this API independent of the current
3180 * SMIF IP version, it accepts any SMIF pointer as parameter, e.g. a SMIF base
3181 * pointer or a SMIF_DEVICE base pointer. This means this API can be called with
3182 * a SMIF_DEVICE base pointer.
3183 *
3184 * \param base
3185 * Holds the base address of the SMIF block or SMIF_DEVICE block registers.
3186 *
3187 * \param tapSel
3188 * delay tap selection to be set
3189 *
3190 * \return status (see \ref cy_en_smif_status_t).
3191 *
3192 * \note This API is supported on CAT1C devices.
3193 *
3194 * \snippet smif/snippet/main.c snippet_Cy_SMIF_DelayTapSel
3195 *******************************************************************************/
Cy_SMIF_Set_DelayTapSel(SMIF_Type * base,uint8_t tapSel)3196 cy_en_smif_status_t Cy_SMIF_Set_DelayTapSel(SMIF_Type *base, uint8_t tapSel)
3197 {
3198 if(tapSel > (SMIF_DELAY_TAPS_NR - 1U))
3199 {
3200 return CY_SMIF_BAD_PARAM;
3201 }
3202
3203 SMIF_DELAY_TAP_SEL(base) = tapSel;
3204
3205 return CY_SMIF_SUCCESS;
3206 }
3207
3208 /*******************************************************************************
3209 * Function Name: Cy_SMIF_Get_DelayTapSel
3210 ****************************************************************************//**
3211 *
3212 * This function returns delay tap number which has been set for the SMIF (common for all its devices).
3213 * To ensure compatibility with users of this API independent of the current
3214 * SMIF IP version, it accepts any SMIF pointer as parameter, e.g. a SMIF base
3215 * pointer or a SMIF_DEVICE base pointer. This means this API can be called with
3216 * a SMIF_DEVICE base pointer.
3217 *
3218 * \param base
3219 * Holds the base address of the SMIF block or SMIF_DEVICE block registers.
3220 *
3221 * \return read tap selection
3222 *
3223 * \note This API is supported on CAT1C devices.
3224 *
3225 * \snippet smif/snippet/main.c snippet_Cy_SMIF_DelayTapSel
3226 *******************************************************************************/
Cy_SMIF_Get_DelayTapSel(SMIF_Type * base)3227 uint8_t Cy_SMIF_Get_DelayTapSel(SMIF_Type *base)
3228 {
3229 return (uint8_t)(SMIF_DELAY_TAP_SEL(base));
3230 }
3231 #endif /*(CY_IP_MXSMIF_VERSION==2)*/
3232
3233 #endif /* defined (CY_IP_MXS40SRSS) || defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS) */
3234
3235 #if defined(__cplusplus)
3236 }
3237 #endif
3238
3239 #endif /* CY_IP_MXSMIF */
3240
3241 /* [] END OF FILE */
3242