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