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