1 /***************************************************************************//**
2 * \file cy_smif.h
3 * \version 2.100
4 *
5 * Provides an API declaration of the Cypress SMIF driver.
6 *
7 ********************************************************************************
8 * \copyright
9 * Copyright 2016-2022 Cypress Semiconductor Corporation
10 * SPDX-License-Identifier: Apache-2.0
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *******************************************************************************/
24
25 /**
26 * \addtogroup group_smif
27 * \{
28 * The SPI-based communication interface to the external quad SPI (QSPI)
29 * high-speed memory devices.
30 *
31 * The functions and other declarations used in this driver are in cy_smif.h and
32 * cy_smif_memslot.h (if used). If you are using the ModusToolbox QSPI Configurator,
33 * also include cycfg_qspi_memslot.h.
34 *
35 * **SMIF: Serial Memory Interface**: This IP block implements an SPI-based
36 * communication interface for interfacing external memory devices to PSoC.
37 * The SMIF supports SPI, dual SPI (DSPI), quad SPI (QSPI), dual QSPI and octal SPI.
38 *
39 * Features
40 * - Standard SPI Master interface
41 * - Supports single/dual/quad/octal SPI memory devices
42 * - Supports dual quad SPI mode
43 * - Design-time configurable support for multiple (up to 4) external serial
44 * memory devices
45 * - eXecute-In-Place (XIP) operation mode for both read and write accesses
46 * with 4KB XIP read cache and on-the-fly encryption and decryption
47 * - Supports external serial memory initialization via
48 * <a href="https://www.jedec.org/standards-documents/docs/jesd216b" target="_blank">
49 * Serial Flash Discoverable Parameters (SFDP)</a> standard
50 *
51 * The primary usage model for the SMIF is that of an external memory interface.
52 * The SMIF is capable of interfacing with different types of memory, up to four
53 * types.
54 *
55 * \b SMIF driver is divided into three layers
56 * - cy_smif.h API
57 * - cy_smif_memslot.h API
58 * - SMIF configuration structures
59 *
60 * The SMIF API is divided into the low-level functions and memory-slot functions. Use
61 * the low level API for the SMIF block initialization and for implementing a generic
62 * SPI communication interface using the SMIF block.
63 *
64 * The memory slot API has functions to implement the basic memory operations such as
65 * program, read, erase etc. These functions are implemented using the memory
66 * parameters in the memory device configuration data structure. The
67 * Cy_SMIF_MemInit() API initializes all the memory slots based on the settings
68 * in the array.
69 *
70 * \image html smif_3_0_p01_layers.png
71 *
72 * \note
73 * Above image is applicable only for SMIF v3 IP.
74 *
75 * \image html smif_1_0_p01_layers.png
76 *
77 * \note
78 * Above image is applicable only for SMIF v1 IP.
79 *
80 * SMIF Configuration Tool is a stand-alone application, which is a part of PDL
81 * (Creator) and could be found in \<PDL_DIR\>/tools/\<OS_DIR\>/SMIFConfigurationTool
82 * (e.g. for PDL 3.0.0 and Windows OS PDL/3.0.0/tools/win/SMIFConfigurationTool).
83 *
84 * In ModusToolbox this tool is called QSPI Configurator. QSPI Configurator is a part of
85 * PSoC 6 Software Library and can be found in \<ModusToolbox\>/tools/qspi-configurator-1.1
86 *
87 * Tool generates *.c and *.h file with configuration structures. These configuration
88 * structures are input parameters for cy_smif_memslot API level
89 *
90 * \warning The driver is not responsible for external memory persistence. You cannot edit
91 * a buffer during the Read/Write operations. If there is a memory error, the SMIF ip block
92 * can require a reset. To determine if this has happened, check the SMIF
93 * busy status using Cy_SMIF_BusyCheck() and implement a timeout. Reset the SMIF
94 * block by toggling CTL.ENABLED. Then reconfigure the SMIF block.
95 *
96 * For the Write operation, check that the SMIF driver has completed
97 * transferring by calling Cy_SMIF_BusyCheck(). Also, check that the memory is
98 * available with Cy_SMIF_MemIsBusy() before proceeding.
99 *
100 * Simple example of external flash memory programming using low level SMIF API.
101 * All steps mentioned in example below are incorporated in
102 * \ref Cy_SMIF_MemCmdWriteEnable(), \ref Cy_SMIF_MemCmdProgram(), and
103 * \ref Cy_SMIF_MemIsBusy() of the
104 * \ref group_smif_mem_slot_functions "memory slot level API".
105 * \warning Example is simplified, without checks of error conditions.
106 * \note Flash memories need erase operation before programming. Refer to
107 * external memory datasheet for specific memory commands.
108 *
109 * \snippet smif/snippet/main.c SMIF_API: Write example
110 *
111 * For the Read operation, before accessing the read buffer, check that it is ready
112 * by calling Cy_SMIF_GetTxFifoStatus().
113 *
114 * Simple example of external flash memory read using low level SMIF API. All
115 * steps mentioned in example below are incorporated in
116 * \ref Cy_SMIF_MemCmdRead() of the
117 * \ref group_smif_mem_slot_functions "memory slot level API".
118 * \warning Example is simplified, without checks of error conditions.
119 * \note Refer to external memory datasheet for specific memory commands.
120 *
121 * \snippet smif/snippet/main.c SMIF_API: Read example
122 *
123 * The user should invalidate the cache by calling Cy_SMIF_CacheInvalidate() when
124 * switching from the MMIO mode to XIP mode.
125 *
126 * \section group_smif_configuration Configuration Considerations
127 *
128 * PDL API has common parameters: base, context, config described in
129 * \ref page_getting_started_pdl_design "PDL Design" section.
130 *
131 * See the documentation for Cy_SMIF_Init() and Cy_SMIF_MemInit() for details
132 * on the required configuration structures and other initialization topics.
133 *
134 * The normal (MMIO) mode is used for implementing a generic SPI/DSPI/QSPI/dual
135 * QSPI/octal SPI communication interface using the SMIF block. This
136 * interface can be used to implement special commands like Program/Erase of
137 * flash, memory device configuration, sleep mode entry for memory devices or
138 * other special commands specific to the memory device. The transfer width
139 * (SPI/DSPI/QSPI/octal SPI) of a transmission is a parameter set for each
140 * transmit/receive operation. So these can be changed at run time.
141 *
142 * In a typical memory interface with flash memory, the SMIF is used in the
143 * memory mode when reading from the memory and it switches to the normal mode when
144 * writing to flash memory.
145 * A typical memory device has multiple types of commands.
146 *
147 * The SMIF interface can be used to transmit different types of commands. Each
148 * command has different phases: command, dummy cycles, and transmit and receive
149 * data which require separate APIs.
150 *
151 * \subsection group_smif_init SMIF Initialization
152 * Create interrupt function and allocate memory for SMIF context
153 * structure
154 * \snippet smif/snippet/main.c SMIF_INIT: context and interrupt
155 * SMIF driver initialization for low level API usage (cysmif.h)
156 * \snippet smif/snippet/main.c SMIF_INIT: low level
157 * Additional steps to initialize SMIF driver for memory slot level API usage
158 * (cy_smif_memslot.h).
159 * \snippet smif/snippet/main.c SMIF_INIT: memslot level
160 * \note Example does not include initialization of all needed configuration
161 * structures (\ref cy_stc_smif_mem_device_cfg_t, \ref cy_stc_smif_mem_cmd_t).
162 * SMIF/QSPI Configuration tool generates all configuration structures needed for
163 * memslot level API usage.
164 *
165 * \subsection group_smif_xip_init SMIF XIP Initialization
166 * The eXecute In Place (XIP) is a mode of operation where read or write commands
167 * to the memory device are directed through the SMIF without any use of API
168 * function calls. In this mode the SMIF block maps the AHB bus-accesses to
169 * external memory device addresses to make it behave similar to internal memory.
170 * This allows the CPU to execute code directly from external memory. This mode
171 * is not limited to code and is suitable also for data read and write accesses.
172 * The memory regions available for XIP addresses allocation are defined
173 * in a linker script file (.ld).
174 *
175 * With SMIF V3 IP, MMIO mode transactions are also allowed when the device is set
176 * to XIP mode. However, only blocking SMIF API's are expected to be used for erase or
177 * program operations as external flash will be busy for such operation and may not be
178 * available for XIP at that moment. User can make use of \ref Cy_SMIF_MemRead,
179 * \ref Cy_SMIF_MemWrite, \ref Cy_SMIF_MemEraseSector API's which ensure that user gets
180 * control only after completing the requested operation.
181 * This will ensure the transaction is complete and then switch back to XIP.
182 * In case user wishes to make use of low level API's like \ref Cy_SMIF_TransmitCommand_Ext,
183 * \ref Cy_SMIF_TransmitData_Ext, \ref Cy_SMIF_SendDummyCycles_Ext user has to ensure the
184 * code is not running already from XIP location and complete the operation before switching
185 * back to XIP mode of execution. Also, user has to bound his complete SMIF operation using
186 * \ref Cy_SysLib_EnterCriticalSection and \ref Cy_SysLib_ExitCriticalSection so that there is
187 * no interruption for the operation due to any other interrupts.
188 *
189 * \snippet smif/snippet/main.c SMIF_INIT: XIP
190 * \note Example of input parameters initialization is in \ref group_smif_init
191 * section.
192 * \warning Functions that called from external memory should be declared with
193 * long call attribute.
194 *
195 * \subsection group_smif_xip_crypto SMIF XIP On-the-fly encryption
196 * In XIP mode, a cryptography component supports on-the-fly encryption for write data and
197 * on-the-fly decryption for read data. On-the-fly encryption/decryption in XIP mode can be
198 * enabled by setting the flags \ref CY_SMIF_FLAG_CRYPTO_ENABLE.
199 * Encryption and decryption are based on the AES-128 forward block cipher: advanced
200 * encryption standard blockcipher with a 128-bit key. KEY[127:0] is a secret (private) key
201 * programmed into the CRYPTO_KEY3,...,CRYPTO_KEY0 registers using \ref Cy_SMIF_SetCryptoKey.
202 * These registers are software write-only. A software read returns 0. In the SMIF hardware,
203 * by applying AES-128 with KEY[127:0] on a plaintext PT[127:0], we get a ciphertext CT[127:0].
204 * In XIP mode, the XIP address is used as the plaintext PT[]. The resulting ciphertext CT[]
205 * is used on-the-fly and not software accessible. The XIP address is extended with the
206 * CRYPTO_INPUT3, ..., CRYPTO_INPUT0 registers. \ref Cy_SMIF_SetCryptoIV can be used to set
207 * initialization vector (96-bits).
208 * In XIP mode, the resulting ciphertext CT[] (of the encrypted address) is XORed with the memory
209 * transfers read data or write data. Note that the AES-128 block cipher is on the address of the
210 * data and not on the data itself.
211 *
212 * \image html smif_xip_mode_functionality.png
213 *
214 * \subsection group_smif_usage_rules Rules for PSoC6 QSPI/SMIF Block Usage
215 * 1. All operations must use one or more dummy cycles between the PSoC 6 Command
216 * and Address phase (when the PSoC 6 MCU drives the data pins) and the device's
217 * Response phase (when the device drives the same data pins). Bus contention may
218 * occur if no (zero) dummy cycles are used.
219 * 2. Any transfer that does not allow dummy cycles (such as Register Status
220 * Reads) must use the single-bit transfer mode. In single-bit mode, the PSoC 6
221 * drives the Command on the Data0 line and the device responds on the Data1
222 * line, so bus contention cannot occur.
223 *
224 * \section group_smif_more_information More Information
225 *
226 * More information regarding the Serial Memory Interface can be found in the component
227 * datasheet and the Technical Reference Manual (TRM).
228 * More information regarding the SMIF Configuration Tool are in SMIF
229 * Configuration Tool User Guide located in \<PDL_DIR\>/tools/\<OS_DIR\>/SMIFConfigurationTool/
230 * folder
231 *
232 * \section group_smif_changelog Changelog
233 * <table class="doxtable">
234 * <tr><th>Version</th><th>Changes</th><th>Reason for Change</th></tr>
235 * <tr>
236 * <td>2.100</td>
237 * <td>Updated slaveSelect validity check to allow Dual QSPI use case.</td>
238 * <td>Bug fixes.</td>
239 * </tr>
240 * <tr>
241 * <td>2.90</td>
242 * <td>Updated internal API</td>
243 * <td>Bug fixes.</td>
244 * </tr>
245 * <tr>
246 * <td>2.80</td>
247 * <td>Added hyperbus support to CAT1C family.</td>
248 * <td>Code Enhancements.</td>
249 * </tr>
250 * <tr>
251 * <td rowspan="2">2.70</td>
252 * <td>Added enhancements related to CAT1D family.</td>
253 * <td>Support added for sending dummy cycles using RWDS line, selecting DLL speed options and RX Capture mode.</td>
254 * </tr>
255 * <tr>
256 * <td>Added API \ref Cy_SMIF_Reset_Memory, updated APIs \ref Cy_SMIF_MemInit,
257 * - \ref Cy_SMIF_MemOctalEnable, \ref Cy_SMIF_MemRead, \ref Cy_SMIF_MemWrite.</td>
258 * <td>Support added for SMIF octal DDR with RWDS and bug fixes.</td>
259 * </tr>
260 * <tr>
261 * <td rowspan="3">2.60</td>
262 * <td>Modified private APIs </td>
263 * <td>MISRA-10.6 violation and Bug fixes.</td>
264 * </tr>
265 * <tr>
266 * <td>Added new API \ref Cy_SMIF_SetSelectedDelayTapSel and \ref Cy_SMIF_GetSelectedDelayTapSel.</td>
267 * <td>Support for CAT1D devices.</td>
268 * </tr>
269 * <tr>
270 * <td>Modified \ref Cy_SMIF_MemWrite and \ref Cy_SMIF_MemDeInit APIs.</td>
271 * <td>Code Enhancement.</td>
272 * </tr>
273 * <tr>
274 * <td>2.50</td>
275 * <td>Future functionality support for Hyperbus devices.</td>
276 * <td>Code Enhancements.</td>
277 * </tr>
278 * <tr>
279 * <td rowspan="4">2.40</td>
280 * <td>Enhanced \ref Cy_SMIF_MemEraseSector to compute sector boundary for erase operation and \n
281 * Minor Bug fixes.
282 * </td>
283 * <td>Code Enhancements.</td>
284 * </tr>
285 * <tr>
286 * <td>Added new API \ref Cy_SMIF_MemCmdPowerDown and \ref Cy_SMIF_MemCmdReleasePowerDown.</td>
287 * <td>Reduce power consumption.</td>
288 * </tr>
289 * <tr>
290 * <td>Added new API \ref Cy_SMIF_DeviceTransfer_SetMergeTimeout and \ref Cy_SMIF_DeviceTransfer_ClearMergeTimeout.</td>
291 * <td>Allow user to configure merge timeout.</td>
292 * </tr>
293 * <tr>
294 * <td>Removed Bridge API support.</td>
295 * <td>Removed feature not supported in existing devices.</td>
296 * </tr>
297 * <tr>
298 * <td rowspan="5">2.30</td>
299 * <td>Octal SDR and DDR support using SFDP mode.</td>
300 * <td>Octal device support.</td>
301 * </tr>
302 * <tr>
303 * <td>Move SFDP related functionality to cy_smif_sfdp.c. </td>
304 * <td>Code Enhancements.</td>
305 * </tr>
306 * <tr>
307 * <td>Added support for new product families</td>
308 * <td>Support for CAT1B and CAT1C devices.</td>
309 * </tr>
310 * <tr>
311 * <td>Added new API's:\n
312 * \ref Cy_SMIF_MemInitSfdpMode()\n
313 * \ref Cy_SMIF_SetCryptoIV()\n
314 * \ref Cy_SMIF_SetCryptoKey()\n
315 * \ref Cy_SMIF_ConvertSlaveSlotToIndex()\n
316 * \ref Cy_SMIF_SetCryptoEnable()\n
317 * \ref Cy_SMIF_SetCryptoDisable()\n
318 * \ref Cy_SMIF_SetReadyPollingDelay()\n
319 *
320 * Following macros renamed:\n
321 * CY_SMIF_WRITE_STATUS_REG2_CMD to CY_SMIF_WRITE_STATUS_REG2_T1_CMD.</td>
322 * <td>Support for SFDP 1.0 devices.</td>
323 * </tr>
324 * <tr>
325 * <td>Added new API's for CAT1D devices\n
326 * \ref Cy_SMIF_SetRxCaptureMode()\n
327 * Cy_SMIF_Bridge_Enable()\n
328 * Cy_SMIF_Bridge_SetPortPriority()\n
329 * Cy_SMIF_Bridge_SetSimpleRemapRegion()\n
330 * Cy_SMIF_Bridge_SetInterleavingRemapRegion()\n
331 * \ref Cy_SMIF_MemOctalEnable()\n
332 * </td>
333 * <td>Support for CAT1D devices.</td>
334 * </tr>
335 * <tr>
336 * <td>2.20</td>
337 * <td>Bug fixes in \ref Cy_SMIF_MemEraseSector for Hybrid memory configuration.
338 * Updated \ref Cy_SMIF_MemIsReady to use \ref Cy_SysLib_Rtos_Delay and \ref Cy_SysLib_Rtos_DelayUs.</td>
339 * <td>Code enhancement.</td>
340 * </tr>
341 * <tr>
342 * <td>2.10</td>
343 * <td>New silicon family support.</td>
344 * <td>Added extended API for DDR support.</td>
345 * </tr>
346 * <tr>
347 * <td rowspan="4">2.0</td>
348 * <td>Reworked the \ref Cy_SMIF_MemRead and \ref Cy_SMIF_MemWrite functions to use polling instead of interrupts.</td>
349 * <td>Extend the usability of these functions.</td>
350 * </tr>
351 * <tr>
352 * <td>Reworked the length-parameter check in the \ref Cy_SMIF_MemEraseSector function.
353 * The Erase operation is not performed and \ref CY_SMIF_SUCCESS is no longer returned when the sectors are not aligned.</td>
354 * <td>Fix the user error-handling of the length parameter.</td>
355 * </tr>
356 * <tr>
357 * <td>Fixed the address-parameter check in the \ref Cy_SMIF_MemLocateHybridRegion function.
358 * \ref CY_SMIF_SUCCESS or \ref CY_SMIF_NOT_HYBRID_MEM is no longer returned when the address exceeds the memory size.</td>
359 * <td>Address a defect.</td>
360 * </tr>
361 * <tr>
362 * <td>Fixed MISRA 2012 violations.</td>
363 * <td>MISRA 2012 compliance.</td>
364 * </tr>
365 * <tr>
366 * <td>1.50.1</td>
367 * <td>Minor documentation updates. </td>
368 * <td>Documentation improvement. </td>
369 * </tr>
370 * <tr>
371 * <td>1.50</td>
372 * <td>Added a new function: \ref Cy_SMIF_MemLocateHybridRegion.\n
373 * Added a new structure \ref cy_stc_smif_hybrid_region_info_t.\n
374 * Updated the \ref Cy_SMIF_MemEraseSector and \ref Cy_SMIF_MemCmdSectorErase functions.\n
375 * Updated the \ref Cy_SMIF_MemSfdpDetect function. \n
376 * Updated the \ref cy_stc_smif_mem_device_cfg_t structure.</td>
377 * <td>Support for memories with hybrid regions.</td>
378 * </tr>
379 * <tr>
380 * <td rowspan="2">1.40.1</td>
381 * <td>The \ref Cy_SMIF_MemInit is changed. </td>
382 * <td>Corrected a false assertion during initialization in SFDP mode.</td>
383 * </tr>
384 * <tr>
385 * <td>Minor documentation updates. </td>
386 * <td></td>
387 * </tr>
388 * <tr>
389 * <td rowspan="5">1.40</td>
390 * <td>The following functions are renamed:\n
391 * Cy_SMIF_GetTxfrStatus into Cy_SMIF_GetTransferStatus;\n
392 * Cy_SMIF_Memslot_Init into Cy_SMIF_MemInit;\n
393 * Cy_SMIF_Memslot_DeInit into Cy_SMIF_MemDeInit;\n
394 * Cy_SMIF_Memslot_CmdWriteEnable into Cy_SMIF_MemCmdWriteEnable;\n
395 * Cy_SMIF_Memslot_CmdWriteDisable into Cy_SMIF_MemCmdWriteDisable;\n
396 * Cy_SMIF_Memslot_IsBusy into Cy_SMIF_MemIsBusy;\n
397 * Cy_SMIF_Memslot_QuadEnable into Cy_SMIF_MemQuadEnable;\n
398 * Cy_SMIF_Memslot_CmdReadSts into Cy_SMIF_MemCmdReadStatus;\n
399 * Cy_SMIF_Memslot_CmdWriteSts into Cy_SMIF_MemCmdWriteStatus;\n
400 * Cy_SMIF_Memslot_CmdChipErase into Cy_SMIF_MemCmdChipErase;\n
401 * Cy_SMIF_Memslot_CmdSectorErase into Cy_SMIF_MemCmdSectorErase;\n
402 * Cy_SMIF_Memslot_SfdpDetect into Cy_SMIF_MemSfdpDetect;\n
403 * Cy_SMIF_Memslot_CmdProgram into Cy_SMIF_MemCmdProgram;\n
404 * Cy_SMIF_Memslot_CmdRead into Cy_SMIF_MemCmdRead.\n
405 * The following ENUMa are renamed:\n
406 * CY_SMIF_SEND_CMPLT into CY_SMIF_SEND_COMPLETE;\n
407 * CY_SMIF_REC_CMPLT into CY_SMIF_RX_COMPLETE;\n
408 * CY_SMIF_REC_BUSY into CY_SMIF_RX_BUSY;\n
409 * CY_SMIF_SEL_INV_INTERNAL_CLK into CY_SMIF_SEL_INVERTED_INTERNAL_CLK;\n
410 * CY_SMIF_SEL_INV_FEEDBACK_CLK into CY_SMIF_SEL_INVERTED_FEEDBACK_CLK;\n
411 * cy_en_smif_cache_en_t into cy_en_smif_cache_t.\n
412 * The following MACROs are renamed:\n
413 * CY_SMIF_FLAG_WR_EN into CY_SMIF_FLAG_WRITE_ENABLE;\n
414 * CY_SMIF_FLAG_CRYPTO_EN into CY_SMIF_FLAG_CRYPTO_ENABLE;\n
415 * CY_SMIF_SFDP_SING_BYTE_00 into CY_SMIF_SFDP_SIGNATURE_BYTE_00;\n
416 * CY_SMIF_SFDP_SING_BYTE_01 into CY_SMIF_SFDP_SIGNATURE_BYTE_01;\n
417 * CY_SMIF_SFDP_SING_BYTE_02 into CY_SMIF_SFDP_SIGNATURE_BYTE_02;\n
418 * CY_SMIF_SFDP_SING_BYTE_03 into CY_SMIF_SFDP_SIGNATURE_BYTE_03;\n
419 * CY_SMIF_WR_STS_REG1_CMD into CY_SMIF_WRITE_STATUS_REG1_CMD;\n
420 * CY_SMIF_WR_DISABLE_CMD into CY_SMIF_WRITE_DISABLE_CMD;\n
421 * CY_SMIF_RD_STS_REG1_CMD into CY_SMIF_READ_STATUS_REG1_CMD;\n
422 * CY_SMIF_WR_ENABLE_CMD into CY_SMIF_WRITE_ENABLE_CMD;\n
423 * CY_SMIF_RD_STS_REG2_T1_CMD into CY_SMIF_READ_STATUS_REG2_T1_CMD;\n
424 * CY_SMIF_WR_STS_REG2_CMD into CY_SMIF_WRITE_STATUS_REG2_CMD;\n
425 * CY_SMIF_RD_STS_REG2_T2_CMD into CY_SMIF_READ_STATUS_REG2_T2_CMD;\n
426 * CY_SMIF_QE_BIT_STS_REG2_T1 into CY_SMIF_QE_BIT_STATUS_REG2_T1;\n
427 * CY_SMIF_STS_REG_BUSY_MASK into CY_SMIF_STATUS_REG_BUSY_MASK.\n
428 * </td>
429 * <td rowspan="2">Documentation improvement.</td>
430 * </tr>
431 * <tr>
432 * <td>Updated the description of the Cy_SMIF_MemInit() function.
433 * Updated the Cy_SMIF_Encrypt() function usage example.
434 * </td>
435 * </tr>
436 * <tr>
437 * <td>The type of arguments that are not modified by the functions are set to const.
438 * </td>
439 * <td>Usability improvement.
440 * </td>
441 * </tr>
442 * <tr>
443 * <td>The Cy_SMIF_MemSfdpDetect() function is updated to support new
444 * commands for 4 bytes addressing.
445 * </td>
446 * <td>Memory devices with new 4 byte addressing commands support.
447 * </td>
448 * </tr>
449 * <tr>
450 * <td>Added the blocking functions which take care of the
451 * busy-status check of the memory:
452 * - \ref Cy_SMIF_MemIsReady
453 * - \ref Cy_SMIF_MemIsQuadEnabled
454 * - \ref Cy_SMIF_MemEnableQuadMode
455 * - \ref Cy_SMIF_MemRead
456 * - \ref Cy_SMIF_MemWrite
457 * - \ref Cy_SMIF_MemEraseSector
458 * - \ref Cy_SMIF_MemEraseChip
459 * </td>
460 * <td>Added new high-level blocking functions.
461 * </td>
462 * </tr>
463 * <tr>
464 * <td rowspan="5">1.30</td>
465 * <td>The CY_SMIF_CMD_FIFO_WR_RX_COUNT_Msk value is changed to 0x0000FFFFUL.</td>
466 * <td rowspan="4">Driver maintenance.</td>
467 * </tr>
468 * <tr>
469 * <td>Added the check of the size parameter in the Cy_SMIF_TransmitData() function.</td>
470 * </tr>
471 * <tr>
472 * <td>Added conditional check for presence of the SMIF hardware IP.</td>
473 * </tr>
474 * <tr>
475 * <td>Fixed the wrong erase command in the SFDP protocol for devices with Erase Type 3.</td>
476 * </tr>
477 * <tr>
478 * <td>Updated the General Description section with minor changes.
479 * Updated the ordering of the parameters descriptions for some functions.
480 * Added the text saying that the Cy_SMIF_MemInit() function is applicable
481 * to use the external memory as memory-mapped to PSoC (XIP mode).
482 * Added the snippet for the Cy_SMIF_Encrypt() function to show how to use this function.
483 * Added below the picture in the Low-Level Functions section the sequence of PDL
484 * functions required in a Read or Write transaction.
485 * Added the text below the picture about the address.
486 * Updated DUMMY COUNT in this picture.
487 * Added checking of the size parameter in the Cy_SMIF_TransmitData() function.
488 * </td>
489 * <td>Documentation improvement.</td>
490 * </tr>
491 * <tr>
492 * <td>1.20.1</td>
493 * <td>Added upper limit to size parameter in several functions.</td>
494 * <td>Documentation improvement.</td>
495 * </tr>
496 * <tr>
497 * <td rowspan="3">1.20</td>
498 * <td>Flattened the organization of the driver source code into the single
499 * source directory and the single include directory.
500 * </td>
501 * <td>Driver library directory-structure simplification.</td>
502 * </tr>
503 * <tr>
504 * <td>Added a new return status and transfer width option for the case when the memory command is not supported.</td>
505 * <td>Improved the memory command structure usability.</td>
506 * </tr>
507 * <tr>
508 * <td>Added register access layer. Use register access macros instead
509 * of direct register access using dereferenced pointers.</td>
510 * <td>Makes register access device-independent, so that the PDL does
511 * not need to be recompiled for each supported part number.</td>
512 * </tr>
513 * <tr>
514 * <td rowspan="2">1.11</td>
515 * <td>Fixed internal function that writes to the SMIF FIFO</td>
516 * <td>The write function stuck in the loop when write speed in external
517 * memory is significantly lower than PSoC CPU core speed and write
518 * transfer is not finished during the single function call.
519 * </td>
520 * </tr>
521 * <tr>
522 * <td>Added optional mode part to the program command flow</td>
523 * <td>Extend usability of program command</td>
524 * </tr>
525 * <tr>
526 * <td>1.10.1</td>
527 * <td>Added Low Power Callback section</td>
528 * <td>Documentation update and clarification</td>
529 * </tr>
530 * <tr>
531 * <td>1.10</td>
532 * <td>Fix write to external memory from CM0+ core. Add checks of API input parameters.
533 * Minor documentation updates</td>
534 * <td></td>
535 * </tr>
536 * <tr>
537 * <td>1.0</td>
538 * <td>Initial version</td>
539 * <td></td>
540 * </tr>
541 * </table>
542 *
543 * \defgroup group_smif_macros Macros
544 * \{
545 * \defgroup group_smif_macros_status Status Macros
546 * \defgroup group_smif_macros_cmd Command Macros
547 * \defgroup group_smif_macros_flags External Memory Flags
548 * \defgroup group_smif_macros_sfdp SFDP Macros
549 * \defgroup group_smif_macros_isr Interrupt Macros
550 * \}
551 * \defgroup group_smif_functions Functions
552 * \{
553 * \defgroup group_smif_low_level_functions Low Level Functions
554 * \{
555 * The SMIF interface can be used to transmit different types of commands.
556 * Each command has different phases: command, dummy cycles, and transmit and receive data which require separate APIs.
557 *
558 * During the time that Slave Select line is active (LOW) the clock signal (CLK) is toggled while command information is first
559 * transferred on the data (IO) signals from the master to the slave. The clock continues to toggle during any period required for
560 * information access in the slave. The clock continues to toggle during the transfer of read data from the slave to the master
561 * or write data from the master to the slave. When the master has transferred the desired amount of data, the master drives the
562 * Slave Select line inactive (HIGH).
563 * Basic flow for read/write commands using \ref Cy_SMIF_TransmitCommand, \ref Cy_SMIF_TransmitData, \ref Cy_SMIF_ReceiveData and
564 * \ref Cy_SMIF_SendDummyCycles with a Quad SPI interface.
565 *
566 * \image html smif_1_0_p03_rw_cmd.png
567 *
568 * The sequence of the PDL functions required in a read or write transaction is:
569 * \ref Cy_SMIF_TransmitCommand() ->
570 * \ref Cy_SMIF_SendDummyCycles() ->
571 * \ref Cy_SMIF_ReceiveData() / \ref Cy_SMIF_TransmitData() ->
572 * \ref Cy_SMIF_BusyCheck().
573 * The address is sent as part of the Cy_SMIF_TransmitCommand() function.
574 * No separate function call is required.
575 *
576 * \}
577 * \defgroup group_smif_mem_slot_functions Memory Slot Functions
578 * \defgroup group_smif_functions_syspm_callback Low Power Callback
579 * \}
580 * \defgroup group_smif_data_structures Data Structures
581 * \{
582 * \defgroup group_smif_data_structures_memslot SMIF Memory Description Structures
583 * General hierarchy of memory structures are:
584 *
585 * \image html smif_3_0_p02_memslot_stc.png
586 *
587 * \note
588 * Above image is applicable only for SMIF v3 IP.
589 *
590 * \image html smif_1_0_p02_memslot_stc.png
591 *
592 * \note
593 * Above image is applicable only for SMIF v1 IP.
594 *
595 * Top structure is \ref cy_stc_smif_block_config_t, which could have links up to
596 * 4 \ref cy_stc_smif_mem_config_t which describes each connected to the SMIF
597 * external memory.
598 * \}
599 * \defgroup group_smif_enums Enumerated Types
600 */
601
602 #if !defined (CY_SMIF_H)
603 #define CY_SMIF_H
604
605 #include "cy_device.h"
606
607 #if defined (CY_IP_MXSMIF)
608
609 #include <stdint.h>
610 #include <stdbool.h>
611 #include <stddef.h>
612 #include "cy_syslib.h"
613 #include "cy_syspm.h"
614
615 #if defined(__cplusplus)
616 extern "C" {
617 #endif
618
619 /***************************************
620 * Constants
621 ****************************************/
622
623 /**
624 * \addtogroup group_smif_macros
625 * \{
626 */
627
628 /** The driver major version */
629 #define CY_SMIF_DRV_VERSION_MAJOR 2
630
631 /** The driver minor version */
632 #define CY_SMIF_DRV_VERSION_MINOR 100
633
634 /** One microsecond timeout for Cy_SMIF_TimeoutRun() */
635 #define CY_SMIF_WAIT_1_UNIT (1U)
636
637 /** The SMIF driver ID, reported as part of an unsuccessful API return status
638 * \ref cy_en_smif_status_t */
639 #define CY_SMIF_ID CY_PDL_DRV_ID(0x2CUL)
640
641
642 /**
643 * \addtogroup group_smif_macros_isr
644 * \{
645 */
646
647 /** Enable XIP_ALIGNMENT_ERROR interrupt see TRM for details */
648 #define CY_SMIF_ALIGNMENT_ERROR (SMIF_INTR_XIP_ALIGNMENT_ERROR_Msk)
649 /** Enable RX_DATA_FIFO_UNDERFLOW interrupt see TRM for details */
650 #define CY_SMIF_RX_DATA_FIFO_UNDERFLOW (SMIF_INTR_RX_DATA_FIFO_UNDERFLOW_Msk)
651 /** Enable TX_DATA_FIFO_OVERFLOW interrupt see TRM for details */
652 #define CY_SMIF_TX_DATA_FIFO_OVERFLOW (SMIF_INTR_TX_DATA_FIFO_OVERFLOW_Msk)
653 /** Enable TX_CMD_FIFO_OVERFLOW interrupt see TRM for details */
654 #define CY_SMIF_TX_COMMAND_FIFO_OVERFLOW (SMIF_INTR_TX_CMD_FIFO_OVERFLOW_Msk)
655 /** Enable TR_TX_REQ interrupt see TRM for details */
656 #define CY_SMIF_TX_DATA_FIFO_LEVEL_TRIGGER (SMIF_INTR_TR_TX_REQ_Msk)
657 /** Enable TR_RX_REQ interrupt see TRM for details */
658 #define CY_SMIF_RX_DATA_FIFO_LEVEL_TRIGGER (SMIF_INTR_TR_RX_REQ_Msk)
659
660 /** \} group_smif_macros_isr */
661
662 /** \cond INTERNAL */
663
664 #if ((CY_IP_MXSMIF_VERSION==2) || (CY_IP_MXSMIF_VERSION==3))
665 #define SMIF_INTR_RX_DATA_FIFO_UNDERFLOW_Msk SMIF_INTR_RX_DATA_MMIO_FIFO_UNDERFLOW_Msk
666 #define SMIF_RX_DATA_FIFO_CTL SMIF_RX_DATA_MMIO_FIFO_CTL
667 #define SMIF_RX_DATA_FIFO_RD4 SMIF_RX_DATA_MMIO_FIFO_RD4
668 #define SMIF_RX_DATA_FIFO_RD1 SMIF_RX_DATA_MMIO_FIFO_RD1
669 #define SMIF_RX_DATA_FIFO_RD2 SMIF_RX_DATA_MMIO_FIFO_RD2
670 #endif /* CY_IP_MXSMIF_VERSION */
671
672 #if (CY_IP_MXSMIF_VERSION==2)
673 /* SMIF IP V2 do not use register name MMIO */
674 #define SMIF_TX_CMD_MMIO_FIFO_WR SMIF_TX_CMD_FIFO_WR
675 #define SMIF_TX_DATA_MMIO_FIFO_WR1ODD SMIF_TX_DATA_FIFO_WR1ODD
676 #define SMIF_TX_DATA_MMIO_FIFO_WR1 SMIF_TX_DATA_FIFO_WR1
677 #endif
678
679 #if (CY_IP_MXSMIF_VERSION==3)
680 #define SMIF_TX_DATA_FIFO_CTL SMIF_TX_DATA_MMIO_FIFO_CTL
681 #define SMIF_TX_DATA_FIFO_WR4 SMIF_TX_DATA_MMIO_FIFO_WR4
682 #define SMIF_TX_DATA_FIFO_WR1 SMIF_TX_DATA_MMIO_FIFO_WR1
683 #define SMIF_TX_DATA_FIFO_WR2 SMIF_TX_DATA_MMIO_FIFO_WR2
684 #define SMIF_CRYPTO_CMD_START_Msk SMIF_SMIF_CRYPTO_CRYPTO_CMD_START_Msk
685 #define SMIF_CRYPTO_CMD_START_Pos SMIF_SMIF_CRYPTO_CRYPTO_CMD_START_Pos
686 #endif /* CY_IP_MXSMIF_VERSION */
687
688 #define CY_SMIF_CMD_FIFO_TX_MODE (0UL)
689 #define CY_SMIF_CMD_FIFO_TX_COUNT_MODE (1UL)
690 #define CY_SMIF_CMD_FIFO_RX_COUNT_MODE (2UL)
691 #define CY_SMIF_CMD_FIFO_DUMMY_COUNT_MODE (3UL)
692
693 #if (CY_IP_MXSMIF_VERSION>=2)
694 #define CY_SMIF_TX_CMD_FIFO_STATUS_RANGE (8U)
695 #else
696 #define CY_SMIF_TX_CMD_FIFO_STATUS_RANGE (4U)
697 #endif /* CY_IP_MXSMIF_VERSION */
698
699 #define CY_SMIF_TX_DATA_FIFO_STATUS_RANGE (8U)
700 #define CY_SMIF_RX_DATA_FIFO_STATUS_RANGE (8U)
701
702 #define CY_SMIF_ONE_BYTE (1U)
703 #define CY_SMIF_TWO_BYTES (2U)
704 #define CY_SMIF_THREE_BYTES (3U)
705 #define CY_SMIF_FOUR_BYTES (4U)
706 #define CY_SMIF_FIVE_BYTES (5U)
707 #define CY_SMIF_SIX_BYTES (6U)
708 #define CY_SMIF_SEVEN_BYTES (7U)
709 #define CY_SMIF_EIGHT_BYTES (8U)
710
711 #define CY_SMIF_CRYPTO_FIRST_WORD (0U)
712 #define CY_SMIF_CRYPTO_SECOND_WORD (4U)
713 #define CY_SMIF_CRYPTO_THIRD_WORD (8U)
714 #define CY_SMIF_CRYPTO_FOURTH_WORD (12U)
715
716 #define CY_SMIF_CRYPTO_START (1UL)
717 #define CY_SMIF_CRYPTO_COMPLETED (0UL)
718 #define CY_SMIF_CRYPTO_ADDR_MASK (0xFFFFFFF0UL)
719 #define CY_SMIF_AES128_BYTES (16U)
720
721 #define CY_SMIF_CTL_REG_DEFAULT (0x00000300U) /* 3 - [13:12] CLOCK_IF_RX_SEL */
722 #define CY_SMIF_CTL2_REG_DEFAULT (0x0080D000U)
723
724 #define CY_SMIF_SFDP_FAIL (0x08U)
725 #define CY_SMIF_SFDP_FAIL_SS0_POS (0x00U)
726 #define CY_SMIF_SFDP_FAIL_SS1_POS (0x01U)
727 #define CY_SMIF_SFDP_FAIL_SS2_POS (0x02U)
728 #define CY_SMIF_SFDP_FAIL_SS3_POS (0x03U)
729
730 #define CY_SMIF_MAX_DESELECT_DELAY (7U)
731 #define CY_SMIF_MAX_TX_TR_LEVEL (8U)
732 #define CY_SMIF_MAX_RX_TR_LEVEL (8U)
733
734 #define CY_SMIF_MODE_VALID(mode) ((CY_SMIF_NORMAL == (cy_en_smif_mode_t)(mode)) || \
735 (CY_SMIF_MEMORY == (cy_en_smif_mode_t)(mode)))
736 #define CY_SMIF_BLOCK_EVENT_VALID(event) ((CY_SMIF_BUS_ERROR == (cy_en_smif_error_event_t)(event)) || \
737 (CY_SMIF_WAIT_STATES == (cy_en_smif_error_event_t)(event)))
738 #if (CY_IP_MXSMIF_VERSION>=2)
739 #define CY_SMIF_CLOCK_SEL_VALID(clkSel) ((CY_SMIF_SEL_OUTPUT_CLK == (cy_en_smif_clk_select_t)(clkSel)) || \
740 (CY_SMIF_SEL_INVERTED_OUTPUT_CLK == (cy_en_smif_clk_select_t)(clkSel)) || \
741 (CY_SMIF_SEL_INTERNAL_CLK == (cy_en_smif_clk_select_t)(clkSel)) || \
742 (CY_SMIF_SEL_INVERTED_INTERNAL_CLK == (cy_en_smif_clk_select_t)(clkSel)) || \
743 (CY_SMIF_SEL_FEEDBACK_CLK == (cy_en_smif_clk_select_t)(clkSel)) || \
744 (CY_SMIF_SEL_INVERTED_FEEDBACK_CLK == (cy_en_smif_clk_select_t)(clkSel)) ||\
745 (CY_SMIF_SEL_INVERTED_SPHB_RWDS_CLK == (cy_en_smif_clk_select_t)(clkSel)) || \
746 (CY_SMIF_SEL_SPHB_RWDS_CLK == (cy_en_smif_clk_select_t)(clkSel)))
747 #else
748 #define CY_SMIF_CLOCK_SEL_VALID(clkSel) ((CY_SMIF_SEL_INTERNAL_CLK == (cy_en_smif_clk_select_t)(clkSel)) || \
749 (CY_SMIF_SEL_INVERTED_INTERNAL_CLK == (cy_en_smif_clk_select_t)(clkSel)) || \
750 (CY_SMIF_SEL_FEEDBACK_CLK == (cy_en_smif_clk_select_t)(clkSel)) || \
751 (CY_SMIF_SEL_INVERTED_FEEDBACK_CLK == (cy_en_smif_clk_select_t)(clkSel)))
752 #endif /* CY_IP_MXSMIF_VERSION */
753
754 #define CY_SMIF_DESELECT_DELAY_VALID(delay) ((delay) <= CY_SMIF_MAX_DESELECT_DELAY)
755 #define CY_SMIF_SLAVE_SEL_VALID(ss) ((CY_SMIF_SLAVE_SELECT_0 == (ss)) || \
756 (CY_SMIF_SLAVE_SELECT_1 == (ss)) || \
757 (CY_SMIF_SLAVE_SELECT_2 == (ss)) || \
758 (CY_SMIF_SLAVE_SELECT_3 == (ss)) || \
759 ((CY_SMIF_SLAVE_SELECT_0 | CY_SMIF_SLAVE_SELECT_1) == (ss)))
760 #define CY_SMIF_DATA_SEL_VALID(ss) ((CY_SMIF_DATA_SEL0 == (ss)) || \
761 (CY_SMIF_DATA_SEL1 == (ss)) || \
762 (CY_SMIF_DATA_SEL2 == (ss)) || \
763 (CY_SMIF_DATA_SEL3 == (ss)))
764 #define CY_SMIF_TXFR_WIDTH_VALID(width) ((CY_SMIF_WIDTH_SINGLE == (width)) || \
765 (CY_SMIF_WIDTH_DUAL == (width)) || \
766 (CY_SMIF_WIDTH_QUAD == (width)) || \
767 (CY_SMIF_WIDTH_OCTAL == (width)) || \
768 (CY_SMIF_WIDTH_NA == (width)))
769 #define CY_SMIF_CMD_PARAM_VALID(param, paramSize) (((paramSize) > 0U)? (NULL != (param)) : (true))
770
771 #define CY_SMIF_WIDTH_NA_VALID(paramWidth, paramSize) (((paramSize) > 0U)? \
772 (CY_SMIF_WIDTH_NA != (paramWidth)) : (true))
773 #define CY_SMIF_CMD_DATA_RATE_VALID(rate) ((CY_SMIF_SDR == (rate)) || \
774 (CY_SMIF_DDR == (rate)))
775 #define CY_SMIF_CMD_PARAM_DATA_RATE_VALID(rate) ((CY_SMIF_SDR == (rate)) || \
776 (CY_SMIF_DDR == (rate)))
777 #define CY_SMIF_DATA_DATA_RATE_VALID(rate) ((CY_SMIF_SDR == (rate)) || \
778 (CY_SMIF_DDR == (rate)))
779
780 #define CY_SMIF_BUFFER_SIZE_MAX (65536UL)
781 #define CY_SMIF_BUF_SIZE_VALID(size) (((CY_SMIF_BUFFER_SIZE_MAX) >= (size)) && ((0UL) < (size)))
782
783 /***************************************
784 * Command FIFO Register
785 ***************************************/
786
787 #if (CY_IP_MXSMIF_VERSION>=2)
788 /* SMIF->TX_CMD_FIFO_MMIO_WR Commands Fields */
789 #define CY_SMIF_CMD_MMIO_FIFO_WR_MODE_Pos (24UL) /* [26:24] Command data mode */
790 #define CY_SMIF_CMD_MMIO_FIFO_WR_MODE_Msk (0x07000000UL) /* DATA[26:24] Command data mode */
791
792 #define CY_SMIF_CMD_MMIO_FIFO_WR_SS_Pos (20UL) /* [23:20] Slave select */
793 #define CY_SMIF_CMD_MMIO_FIFO_WR_SS_Msk (0x00F00000UL) /* DATA[23:20] Slave select */
794
795 #define CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE_Pos (19UL) /* [19] Last byte */
796 #define CY_SMIF_CMD_MMIO_FIFO_WR_LAST_BYTE_Msk (0x00080000UL) /* DATA[19] Last byte */
797
798 #define CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE_Pos (18UL) /* [18] Data Rate */
799 #define CY_SMIF_CMD_MMIO_FIFO_WR_DATA_RATE_Msk (0x00040000UL) /* DATA[18] Data Rate */
800
801 #define CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH_Pos (16UL) /* [17:16] Transfer width */
802 #define CY_SMIF_CMD_MMIO_FIFO_WR_WIDTH_Msk (0x00030000UL) /* DATA[17:16] Transfer width */
803
804 #define CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_2_Pos (8UL) /* [15:8] */
805 #define CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_2_Msk (0x0000FF00UL) /* DATA[15:8] second byte */
806
807 #define CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_1_Pos (0UL) /* [7:0] first byte */
808 #define CY_SMIF_CMD_MMIO_FIFO_WR_TXDATA_BYTE_1_Msk (0x000000FFUL) /* DATA[7:0] first byte */
809
810 #define CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY_Pos (0UL) /* [0] Dummy count */
811 #define CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY_Msk (0x0000FFFFUL) /* DATA[15:0] Dummy count */
812
813 #define CY_SMIF_CMD_MMIO_FIFO_WR_TX_COUNT_Msk (0x0000FFFFUL) /* DATA[15:0] TX count */
814 #define CY_SMIF_CMD_MMIO_FIFO_WR_TX_COUNT_Pos (0UL) /* [0] TX count */
815
816 #define CY_SMIF_CMD_MMIO_FIFO_WR_RX_COUNT_Msk (0x0000FFFFUL) /* DATA[15:0] RX count */
817 #define CY_SMIF_CMD_MMIO_FIFO_WR_RX_COUNT_Pos (0UL) /* [0] RX count */
818
819 #define CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY_READ_RWDS_Msk (0x00800000UL) /* DATA[23] Read with RWDS */
820 #define CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY_READ_RWDS_Pos (23UL) /* [23] Read with RWDS */
821
822 #define CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY_WRITE_RWDS_Msk (0x00200000UL) /* DATA[21] Write with RWDS */
823 #define CY_SMIF_CMD_MMIO_FIFO_WR_DUMMY_WRITE_RWDS_Pos (21UL) /* [21] Dummy RWDS */
824
825 #define CY_SMIF_CMD_MMIO_FIFO_WR_RWDS_REFRESH_Msk (0x00100000UL) /* DATA[20] RWDS Refresh indicator */
826 #define CY_SMIF_CMD_MMIO_FIFO_WR_RWDS_REFRESH_Pos (20UL) /* [20] RWDS Refresh indicator */
827 #else
828 /* SMIF->TX_CMD_FIFO_WR */
829 #define CY_SMIF_TX_CMD_FIFO_WR_MODE_POS (18U) /* [19:18] Command data mode */
830 #define CY_SMIF_TX_CMD_FIFO_WR_WIDTH_POS (16U) /* [17:16] Transfer width */
831 #define CY_SMIF_TX_CMD_FIFO_WR_LAST_BYTE_POS (15U) /* [15] Last byte */
832 #define CY_SMIF_TX_CMD_FIFO_WR_SS_POS (8U) /* [11:8] Slave select */
833 #define CY_SMIF_TX_CMD_FIFO_WR_TXDATA_POS (0U) /* [0] Transmitted byte */
834 #define CY_SMIF_TX_CMD_FIFO_WR_DUMMY_POS (0U) /* [0] Dummy count */
835 #define CY_SMIF_TX_CMD_FIFO_WR_TX_COUNT_POS (0U) /* [0] TX count */
836 #define CY_SMIF_TX_CMD_FIFO_WR_RX_COUNT_POS (0U) /* [0] RX count */
837
838 /* SMIF->TX_CMD_FIFO_WR Commands Fields */
839 #define CY_SMIF_CMD_FIFO_WR_MODE_Pos (18UL) /* [19:18] Command data mode */
840 #define CY_SMIF_CMD_FIFO_WR_MODE_Msk (0x000C0000UL) /* DATA[19:18] Command data mode */
841
842 #define CY_SMIF_CMD_FIFO_WR_WIDTH_Pos (16UL) /* [17:16] Transfer width */
843 #define CY_SMIF_CMD_FIFO_WR_WIDTH_Msk (0x00030000UL) /* DATA[17:16] Transfer width */
844
845 #define CY_SMIF_CMD_FIFO_WR_LAST_BYTE_Pos (15UL) /* [15] Last byte */
846 #define CY_SMIF_CMD_FIFO_WR_LAST_BYTE_Msk (0x00008000UL) /* DATA[15] Last byte */
847
848 #define CY_SMIF_CMD_FIFO_WR_SS_Pos (8UL) /* [11:8] Slave select */
849 #define CY_SMIF_CMD_FIFO_WR_SS_Msk (0x00000F00UL) /* DATA[11:8] Slave select */
850
851 #define CY_SMIF_CMD_FIFO_WR_TXDATA_Pos (0UL) /* [0] Transmitted byte */
852 #define CY_SMIF_CMD_FIFO_WR_TXDATA_Msk (0x000000FFUL) /* DATA[7:0] Transmitted byte */
853 #define CY_SMIF_CMD_FIFO_WR_DUMMY_Pos (0UL) /* [0] Dummy count */
854 #define CY_SMIF_CMD_FIFO_WR_DUMMY_Msk (0x0000FFFFUL) /* DATA[15:0] Dummy count */
855 #define CY_SMIF_CMD_FIFO_WR_TX_COUNT_Msk (0x0000FFFFUL) /* DATA[15:0] TX count */
856 #define CY_SMIF_CMD_FIFO_WR_TX_COUNT_Pos (0UL) /* [0] TX count */
857 #define CY_SMIF_CMD_FIFO_WR_RX_COUNT_Msk (0x0000FFFFUL) /* DATA[15:0] RX count */
858 #define CY_SMIF_CMD_FIFO_WR_RX_COUNT_Pos (0UL) /* [0] RX count */
859 #endif /* CY_IP_MXSMIF_VERSION */
860
861 #if (CY_IP_MXSMIF_VERSION == 5u) || (CY_IP_MXSMIF_VERSION == 4u)
862 #define CY_SMIF_CORE_0_HF 3U
863 #define CY_SMIF_CORE_1_HF 4U
864 #endif
865
866 /** \endcond */
867 /** \} group_smif_macros */
868
869
870 /**
871 * \addtogroup group_smif_enums
872 * \{
873 */
874
875 /** The Transfer width options for the command, data, the address and the mode. */
876 typedef enum
877 {
878 CY_SMIF_WIDTH_SINGLE = 0U, /**< Single SPI mode. */
879 CY_SMIF_WIDTH_DUAL = 1U, /**< Dual SPI mode. */
880 CY_SMIF_WIDTH_QUAD = 2U, /**< Quad SPI mode. */
881 CY_SMIF_WIDTH_OCTAL = 3U, /**< Octal SPI mode. */
882 CY_SMIF_WIDTH_NA = 0xFFU /**< The specific width parameter is not applicable for this memory command. */
883 } cy_en_smif_txfr_width_t;
884
885 /** The SMIF error-event selection. */
886 typedef enum
887 {
888 /**< Generates a bus error. */
889 CY_SMIF_BUS_ERROR = 0UL,
890 /** Stalls the bus with the wait states. This option will increase the
891 * interrupt latency.
892 */
893 CY_SMIF_WAIT_STATES = 1UL
894 } cy_en_smif_error_event_t;
895
896 /** Specifies the delay line used for RX data capturing with */
897 typedef enum
898 {
899 CY_SMIF_1_NEW_SEL_PER_TAP = 0, /**< 1 of these new delay cells per tap providing:
900 granularity of max. ~0.22ns */
901 CY_SMIF_1_SEL_PER_TAP = 1, /**< 1 cell per tap providing:
902 granularity of max. ~0.4ns */
903 CY_SMIF_2_SEL_PER_TAP = 2, /**< 2 cells per tap providing:
904 granularity of max. ~0.8ns */
905 CY_SMIF_4_SEL_PER_TAP = 3, /**< 4 cells per tap providing:
906 granularity of max. ~1.6ns */
907 CY_SMIF_NO_DELAY_SEL = 0xFF,/**< No delay line (disabled) */
908 } cy_en_smif_delay_line_t;
909
910 /** The data line-selection options for a slave device. */
911 typedef enum
912 {
913 /**
914 * smif.spi_data[0] = DATA0, smif.spi_data[1] = DATA1, ..., smif.spi_data[7] = DATA7.
915 * This value is allowed for the SPI, DSPI, QSPI, dual QSPI, and octal SPI modes.
916 */
917 CY_SMIF_DATA_SEL0 = 0,
918 /**
919 * smif.spi_data[2] = DATA0, smif.spi_data[3] = DATA1.
920 * This value is only allowed for the SPI and DSPI modes.
921 */
922 CY_SMIF_DATA_SEL1 = 1,
923 /**
924 * smif.spi_data[4] = DATA0, smif.spi_data[5] = DATA1, ..., smif.spi_data[7] = DATA3.
925 * This value is only allowed for the SPI, DSPI, QSPI and dual QSPI modes.
926 */
927 CY_SMIF_DATA_SEL2 = 2,
928 /**
929 * smif.spi_data[6] = DATA0, smif.spi_data[7] = DATA1.
930 * This value is only allowed for the SPI and DSPI modes.
931 */
932 CY_SMIF_DATA_SEL3 = 3
933 } cy_en_smif_data_select_t;
934
935 /** The SMIF modes to work with an external memory. */
936 typedef enum
937 {
938 CY_SMIF_NORMAL, /**< Command mode (MMIO mode). */
939 CY_SMIF_MEMORY /**< XIP (eXecute In Place) mode. */
940 } cy_en_smif_mode_t;
941
942 /**
943 * \note
944 * This enum is available for CAT1D devices.
945 **/
946 typedef enum
947 {
948 CY_SMIF_DLL_DIVIDE_BY_2 = 0, /**< Divides DLL Clock by 2 */
949 CY_SMIF_DLL_DIVIDE_BY_4 = 1, /**< Divides DLL Clock by 4 */
950 CY_SMIF_DLL_DIVIDE_BY_8 = 2, /**< Divides DLL Clock by 8 */
951 CY_SMIF_DLL_DIVIDE_BY_16 = 3, /**< Divides DLL Clock by 16 */
952 } cy_en_smif_dll_divider_t;
953
954
955 /**
956 * \note
957 * This enum is available for CAT1B, CAT1C and CAT1D devices.
958 **/
959 typedef enum
960 {
961 CY_SMIF_DELAY_TAP_DISABLE = 0, /**< The SMIF Delay tap disable */
962 CY_SMIF_DELAY_TAP_ENABLE = 1, /**< The SMIF Delay tap enable */
963 } cy_en_smif_delay_tap_t;
964
965 /** The SMIF transfer status return values. */
966 typedef enum
967 {
968 CY_SMIF_STARTED, /**< The SMIF started. */
969 CY_SMIF_SEND_COMPLETE, /**< The data transmission is complete. */
970 CY_SMIF_SEND_BUSY, /**< The data transmission is in progress. */
971 CY_SMIF_RX_COMPLETE, /**< The data reception is completed. */
972 CY_SMIF_RX_BUSY, /**< The data reception is in progress. */
973 CY_SMIF_XIP_ERROR, /**< An XIP alignment error. */
974 CY_SMIF_CMD_ERROR, /**< A TX CMD FIFO overflow. */
975 CY_SMIF_TX_ERROR, /**< A TX DATA FIFO overflow. */
976 CY_SMIF_RX_ERROR /**< An RX DATA FIFO underflow. */
977
978 } cy_en_smif_txfr_status_t;
979
980 /** The SMIF API return values. */
981 typedef enum
982 {
983 CY_SMIF_SUCCESS = 0x00U, /**< Successful SMIF operation. */
984 CY_SMIF_CMD_FIFO_FULL = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x01U, /**< The command is cancelled. The command FIFO is full. */
985 CY_SMIF_EXCEED_TIMEOUT = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x02U, /**< The SMIF operation timeout exceeded. */
986 /**
987 * The device does not have a QE bit. The device detects
988 * 1-1-4 and 1-4-4 Reads based on the instruction.
989 */
990 CY_SMIF_NO_QE_BIT = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x03U,
991 CY_SMIF_BAD_PARAM = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x04U, /**< The SMIF API received the wrong parameter */
992 CY_SMIF_NO_SFDP_SUPPORT = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x05U, /**< The external memory does not support SFDP (JESD216B). */
993 CY_SMIF_NOT_HYBRID_MEM = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x06U, /**< The external memory is not hybrid */
994 CY_SMIF_SFDP_CORRUPTED_TABLE = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x07U, /**< The SFDP table is corrupted */
995 /** Failed to initialize the slave select 0 external memory by auto detection (SFDP). */
996 CY_SMIF_SFDP_SS0_FAILED = CY_SMIF_ID |CY_PDL_STATUS_ERROR |
997 ((uint32_t)CY_SMIF_SFDP_FAIL << CY_SMIF_SFDP_FAIL_SS0_POS),
998 /** Failed to initialize the slave select 1 external memory by auto detection (SFDP). */
999 CY_SMIF_SFDP_SS1_FAILED = CY_SMIF_ID | CY_PDL_STATUS_ERROR |
1000 ((uint32_t)CY_SMIF_SFDP_FAIL << CY_SMIF_SFDP_FAIL_SS1_POS),
1001 /** Failed to initialize the slave select 2 external memory by auto detection (SFDP). */
1002 CY_SMIF_SFDP_SS2_FAILED = CY_SMIF_ID |CY_PDL_STATUS_ERROR |
1003 ((uint32_t)CY_SMIF_SFDP_FAIL << CY_SMIF_SFDP_FAIL_SS2_POS),
1004 /** Failed to initialize the slave select 3 external memory by auto detection (SFDP). */
1005 CY_SMIF_SFDP_SS3_FAILED = CY_SMIF_ID |CY_PDL_STATUS_ERROR |
1006 ((uint32_t)CY_SMIF_SFDP_FAIL << CY_SMIF_SFDP_FAIL_SS3_POS),
1007 /** The command API is not supported for this memory device. */
1008 CY_SMIF_CMD_NOT_FOUND = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x80U,
1009 /** SFDP Buffer Insufficient. */
1010 CY_SMIF_SFDP_BUFFER_INSUFFICIENT = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x81U,
1011 /**
1012 * The device does not have a OE bit. The device detects
1013 * 1-1-8 and 1-8-8 Reads based on the instruction.
1014 */
1015 CY_SMIF_NO_OE_BIT = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x82U,
1016 /** SMIF is currently busy and cannot accept the request */
1017 CY_SMIF_BUSY = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x83U,
1018 CY_SMIF_GENERAL_ERROR = CY_SMIF_ID |CY_PDL_STATUS_ERROR | 0x84U, /**< Some general error */
1019 } cy_en_smif_status_t;
1020
1021 /** The SMIF slave select definitions for the driver API. Each slave select is
1022 * represented by an enumeration that has the bit corresponding to the slave
1023 * select number set. */
1024 typedef enum
1025 {
1026 CY_SMIF_SLAVE_SELECT_0 = 1U, /**< The SMIF slave select 0 */
1027 CY_SMIF_SLAVE_SELECT_1 = 2U, /**< The SMIF slave select 1 */
1028 CY_SMIF_SLAVE_SELECT_2 = 4U, /**< The SMIF slave select 2 */
1029 CY_SMIF_SLAVE_SELECT_3 = 8U /**< The SMIF slave select 3 */
1030 } cy_en_smif_slave_select_t;
1031
1032 #if (CY_IP_MXSMIF_VERSION>=2) || defined (CY_DOXYGEN)
1033 /** Specifies receive capture mode. */
1034 /**
1035 * \note
1036 * This enum is available for CAT1D devices.
1037 **/
1038 typedef enum
1039 {
1040 CY_SMIF_SEL_NORMAL_SPI = 0U, /**< Normal SPI without DLP. */
1041 CY_SMIF_SEL_NORMAL_SPI_WITH_DLP = 1U, /**< Normal SPI with DLP (Data Learning Pattern). */
1042 CY_SMIF_SEL_XSPI_HYPERBUS_WITH_DQS = 2U, /**< xSPI or HYPER BUS with Data strobe line. */
1043 } cy_en_smif_capture_mode_t;
1044 #endif
1045
1046 #if (CY_IP_MXSMIF_VERSION>=2) || defined (CY_DOXYGEN)
1047
1048 /** Specifies the clock source for the receiver clock. */
1049 /**
1050 * \note
1051 * This enum is available for CAT1B and CAT1C devices.
1052 **/
1053 typedef enum
1054 {
1055 CY_SMIF_SEL_OUTPUT_CLK = 0U, /**< The SMIF output clock */
1056 CY_SMIF_SEL_INVERTED_OUTPUT_CLK = 1U, /**< The SMIF inverted output clock */
1057 CY_SMIF_SEL_FEEDBACK_CLK = 2U, /**< The SMIF feedback clock */
1058 CY_SMIF_SEL_INVERTED_FEEDBACK_CLK = 3U, /**< The SMIF feedback inverted clock */
1059 CY_SMIF_SEL_INTERNAL_CLK = 4U, /**< The SMIF internal clock */
1060 CY_SMIF_SEL_INVERTED_INTERNAL_CLK = 5U, /**< The SMIF internal inverted clock */
1061 CY_SMIF_SEL_INVERTED_SPHB_RWDS_CLK = 6U, /**< The SMIF internal inverted clock */
1062 CY_SMIF_SEL_SPHB_RWDS_CLK = 7U, /**< The SMIF internal inverted clock */
1063 } cy_en_smif_clk_select_t;
1064 #endif
1065 #if (CY_IP_MXSMIF_VERSION==1) || defined (CY_DOXYGEN)
1066 /**
1067 * \note
1068 * This enum is available for CAT1A devices.
1069 **/
1070 typedef enum
1071 {
1072 CY_SMIF_SEL_INTERNAL_CLK = 0U, /**< The SMIF internal clock */
1073 CY_SMIF_SEL_INVERTED_INTERNAL_CLK = 1U, /**< The SMIF internal inverted clock */
1074 CY_SMIF_SEL_FEEDBACK_CLK = 2U, /**< The SMIF feedback clock */
1075 CY_SMIF_SEL_INVERTED_FEEDBACK_CLK = 3U /**< The SMIF feedback inverted clock */
1076 } cy_en_smif_clk_select_t;
1077 #endif /* CY_IP_MXSMIF_VERSION */
1078
1079 /** Specifies enabled type of SMIF cache. */
1080 typedef enum
1081 {
1082 CY_SMIF_CACHE_SLOW = 1U, /**< The SMIF slow cache (in the clk_slow domain) see TRM for details */
1083 CY_SMIF_CACHE_FAST = 2U, /**< The SMIF fast cache (in the clk_fast domain) see TRM for details */
1084 CY_SMIF_CACHE_BOTH = 3U /**< The SMIF both caches */
1085 } cy_en_smif_cache_t;
1086
1087 /** Specifies the quad enable requirement case.
1088 * JEDEC Basic Flash Parameter Table: 15th DWORD
1089 **/
1090 typedef enum
1091 {
1092 CY_SMIF_SFDP_QER_0 = 0, /**< No QE Bit */
1093 CY_SMIF_SFDP_QER_1 = 1, /**< Bit 1 of Status Register 2 - Write uses 2 bytes using 01h */
1094 CY_SMIF_SFDP_QER_2 = 2, /**< Bit 6 of Status Register 1 - Write uses 1 byte */
1095 CY_SMIF_SFDP_QER_3 = 3, /**< Bit 7 of Status Register 2- Write uses 1 byte */
1096 CY_SMIF_SFDP_QER_4 = 4, /**< Bit 1 of Status Register 2 - Write uses 1 or 2 bytes */
1097 CY_SMIF_SFDP_QER_5 = 5, /**< Bit 1 of Status Register 2 - Write status uses 01h */
1098 CY_SMIF_SFDP_QER_6 = 6, /**< Bit 1 of Status Register 2 - Write uses 1 byte using 31h */
1099 } cy_en_smif_qer_t;
1100
1101 /** Specifies the memory interface frequency range of operation.
1102 **/
1103 typedef enum
1104 {
1105 CY_SMIF_100MHZ_OPERATION = 0, /**< 100 MHz default operation */
1106 CY_SMIF_133MHZ_OPERATION = 1, /**< 133 MHz operation */
1107 CY_SMIF_166MHZ_OPERATION = 2, /**< 166 MHz operation */
1108 CY_SMIF_200MHZ_OPERATION = 3, /**< 200 MHz operation */
1109 } cy_en_smif_interface_freq_t;
1110
1111 #if (CY_IP_MXSMIF_VERSION>=2) || defined (CY_DOXYGEN)
1112 /** Specifies the data rate. */
1113 /**
1114 * \note
1115 * This enum is available for CAT1B, CAT1C and CAT1D devices.
1116 **/
1117 typedef enum
1118 {
1119 CY_SMIF_SDR = 0, /**< The SMIF Single Data Rate (SDR) */
1120 CY_SMIF_DDR = 1, /**< The SMIF Double Data Rate (DDR) */
1121 } cy_en_smif_data_rate_t;
1122
1123 /** Specifies the presence of the field. */
1124 /**
1125 * \note
1126 * This enum is available for CAT1B, CAT1C and CAT1D devices.
1127 **/
1128 typedef enum
1129 {
1130 CY_SMIF_NOT_PRESENT = 0,
1131 CY_SMIF_PRESENT_1BYTE = 1,
1132 CY_SMIF_PRESENT_2BYTE = 2,
1133 } cy_en_smif_field_presence_t;
1134
1135 /** Specifies the merge transaction timeout in terms of clock cycles. */
1136 /**
1137 * \note
1138 * This enum is available for CAT1B, CAT1C and CAT1D devices.
1139 **/
1140 typedef enum
1141 {
1142 CY_SMIF_MERGE_TIMEOUT_1_CYCLE = 0,
1143 CY_SMIF_MERGE_TIMEOUT_16_CYCLES = 1,
1144 CY_SMIF_MERGE_TIMEOUT_256_CYCLES = 2,
1145 CY_SMIF_MERGE_TIMEOUT_4096_CYCLES = 3,
1146 CY_SMIF_MERGE_TIMEOUT_65536_CYCLES = 4,
1147 } cy_en_smif_merge_timeout_t;
1148
1149 #endif /* CY_IP_MXSMIF_VERSION */
1150
1151 /** Specifies the data line index. */
1152 typedef enum
1153 {
1154 CY_SMIF_DATA_BIT0_TAP_SEL = 0U, /**< Data line zero. */
1155 CY_SMIF_DATA_BIT1_TAP_SEL = 1U, /**< Data line one. */
1156 CY_SMIF_DATA_BIT2_TAP_SEL = 2U, /**< Data line two. */
1157 CY_SMIF_DATA_BIT3_TAP_SEL = 3U, /**< Data line three. */
1158 CY_SMIF_DATA_BIT4_TAP_SEL = 4U, /**< Data line four. */
1159 CY_SMIF_DATA_BIT5_TAP_SEL = 5U, /**< Data line five. */
1160 CY_SMIF_DATA_BIT6_TAP_SEL = 6U, /**< Data line six. */
1161 CY_SMIF_DATA_BIT7_TAP_SEL = 7U, /**< Data line seven. */
1162 } cy_en_smif_mem_data_line_t;
1163
1164
1165 /** \cond INTERNAL */
1166 /*******************************************************************************
1167 * These are legacy macros. They are left here just for backward compatibility.
1168 * Do not use them in new designs.
1169 *******************************************************************************/
1170
1171 #define CY_SMIF_SEND_CMPLT CY_SMIF_SEND_COMPLETE
1172 #define CY_SMIF_REC_CMPLT CY_SMIF_RX_COMPLETE
1173 #define CY_SMIF_REC_BUSY CY_SMIF_RX_BUSY
1174 #define CY_SMIF_SEL_INV_INTERNAL_CLK CY_SMIF_SEL_INVERTED_INTERNAL_CLK
1175 #define CY_SMIF_SEL_INV_FEEDBACK_CLK CY_SMIF_SEL_INVERTED_FEEDBACK_CLK
1176 #define cy_en_smif_cache_en_t cy_en_smif_cache_t
1177 #define Cy_SMIF_GetTxfrStatus Cy_SMIF_GetTransferStatus
1178
1179 /** \endcond */
1180
1181 /** \} group_smif_enums */
1182
1183
1184 /**
1185 * \addtogroup group_smif_data_structures
1186 * \{
1187 */
1188
1189 /***************************************************************************//**
1190 *
1191 * The SMIF user callback function type called at the end of a transfer.
1192 *
1193 * \param event
1194 * The event which caused a callback call.
1195 *
1196 *******************************************************************************/
1197 typedef void (*cy_smif_event_cb_t)(uint32_t event);
1198
1199
1200 /** The SMIF configuration structure. */
1201 typedef struct
1202 {
1203 uint32_t mode; /**< Specifies the mode of operation \ref cy_en_smif_mode_t. */
1204 uint32_t deselectDelay; /**< Specifies the minimum duration of SPI de-selection between SPI transfers:
1205 * - "0": 1 clock cycle.
1206 * - "1": 2 clock cycles.
1207 * - "2": 3 clock cycles.
1208 * - "3": 4 clock cycles.
1209 * - "4": 5 clock cycles.
1210 * - "5": 6 clock cycles.
1211 * - "6": 7 clock cycles.
1212 * - "7": 8 clock cycles. */
1213 uint32_t rxClockSel; /**< Specifies the clock source for the receiver
1214 * clock \ref cy_en_smif_clk_select_t. Used for CAT1A, CAT1B and CAT1C devices. */
1215 uint32_t blockEvent; /**< Specifies what happens when there is a Read
1216 * from an empty RX FIFO or a Write to a full
1217 * TX FIFO. \ref cy_en_smif_error_event_t. */
1218 cy_en_smif_delay_tap_t delayTapEnable; /**< Delay tap can be enabled or disabled \ref cy_en_smif_delay_tap_t. */
1219 cy_en_smif_delay_line_t delayLineSelect; /**< set line selection which is input. \ref cy_en_smif_delay_line_t */
1220 #if (CY_IP_MXSMIF_VERSION >=4)
1221 uint32_t inputFrequencyMHz; /**< Input frequency. Used when internal DLL is enabled for setting the speed mode */
1222 bool enable_internal_dll; /**< Enables internal DLL. Default value by passes DLL */
1223 cy_en_smif_dll_divider_t dll_divider_value; /**< Divider value for DLL */
1224 cy_en_smif_capture_mode_t rx_capture_mode; /**< RX Capture mode used in CAT1D Devices */
1225 #endif
1226 } cy_stc_smif_config_t;
1227
1228 /** The SMIF internal context data. The user must not modify it. */
1229 typedef struct
1230 {
1231 uint8_t const volatile * volatile txBufferAddress; /**< The pointer to the data to transfer */
1232 uint32_t txBufferSize; /**< The size of the data to transmit in bytes */
1233 /**
1234 * The transfer counter. The number of the transmitted bytes = txBufferSize - txBufferCounter
1235 */
1236 uint32_t volatile txBufferCounter;
1237 uint8_t volatile * volatile rxBufferAddress; /**< The pointer to the variable where the received data is stored */
1238 uint32_t rxBufferSize; /**< The size of the data to be received in bytes */
1239 /**
1240 * The transfer counter. The number of the received bytes = rxBufferSize - rxBufferCounter
1241 */
1242 uint32_t volatile rxBufferCounter;
1243 /**
1244 * The status of the transfer. The transmitting / receiving is completed / in progress
1245 */
1246 uint32_t volatile transferStatus;
1247 cy_smif_event_cb_t volatile txCompleteCb; /**< The user-defined callback executed at the completion of a transmission */
1248 cy_smif_event_cb_t volatile rxCompleteCb; /**< The user-defined callback executed at the completion of a reception */
1249 /**
1250 * The timeout in microseconds for the blocking functions. This timeout value applies to all blocking APIs.
1251 */
1252 uint32_t timeout;
1253 /**
1254 * The timeout in microseconds for polling memory device on its readiness.
1255 */
1256 uint16_t memReadyPollDelay;
1257 #if (CY_IP_MXSMIF_VERSION>=2) || defined (CY_DOXYGEN)
1258 /**
1259 * \note
1260 * This parameter is available for CAT1B, CAT1C and CAT1D devices.
1261 **/
1262 cy_en_smif_data_rate_t preCmdDataRate; /**< preferred command data rate */
1263 /**
1264 * \note
1265 * This parameter is available for CAT1B, CAT1C and CAT1D devices.
1266 **/
1267 cy_en_smif_txfr_width_t preCmdWidth; /**< preferred command data rate */
1268 /**
1269 * \note
1270 * This parameter is available for CAT1B, CAT1C and CAT1D devices.
1271 **/
1272 cy_en_smif_data_rate_t preXIPDataRate; /**< preferred XIP data rate */
1273 /**
1274 * \note
1275 * This parameter is available for CAT1B, CAT1C and CAT1D devices for Hyperflash/HyperRAM.
1276 **/
1277 uint32_t dummyCycles; /**< preferred dummy cycles per transaction */
1278 /** Determines if the device is memory-mapped, enables the Autodetect
1279 * using the SFDP, enables the write capability, or enables the crypto
1280 * support for this memory slave */
1281 uint32_t flags;
1282 #endif /* CY_IP_MXSMIF_VERSION */
1283 } cy_stc_smif_context_t;
1284
1285 /** \} group_smif_data_structures */
1286
1287
1288 /**
1289 * \addtogroup group_smif_low_level_functions
1290 * \{
1291 */
1292
1293 cy_en_smif_status_t Cy_SMIF_Init(SMIF_Type *base, cy_stc_smif_config_t const *config,
1294 uint32_t timeout,
1295 cy_stc_smif_context_t *context);
1296 void Cy_SMIF_DeInit(SMIF_Type *base);
1297 void Cy_SMIF_SetDataSelect(SMIF_Type *base, cy_en_smif_slave_select_t slaveSelect,
1298 cy_en_smif_data_select_t dataSelect);
1299 void Cy_SMIF_SetMode(SMIF_Type *base, cy_en_smif_mode_t mode);
1300 cy_en_smif_mode_t Cy_SMIF_GetMode(SMIF_Type const *base);
1301 cy_en_smif_status_t Cy_SMIF_TransmitCommand(SMIF_Type *base,
1302 uint8_t cmd,
1303 cy_en_smif_txfr_width_t cmdTxfrWidth,
1304 uint8_t const cmdParam[], uint32_t paramSize,
1305 cy_en_smif_txfr_width_t paramTxfrWidth,
1306 cy_en_smif_slave_select_t slaveSelect, uint32_t completeTxfr,
1307 cy_stc_smif_context_t const *context);
1308 cy_en_smif_status_t Cy_SMIF_TransmitData(SMIF_Type *base,
1309 uint8_t const *txBuffer, uint32_t size,
1310 cy_en_smif_txfr_width_t transferWidth,
1311 cy_smif_event_cb_t TxCompleteCb,
1312 cy_stc_smif_context_t *context);
1313 cy_en_smif_status_t Cy_SMIF_TransmitDataBlocking(SMIF_Type *base,
1314 uint8_t const *txBuffer,
1315 uint32_t size,
1316 cy_en_smif_txfr_width_t transferWidth,
1317 cy_stc_smif_context_t const *context);
1318 cy_en_smif_status_t Cy_SMIF_ReceiveData(SMIF_Type *base,
1319 uint8_t *rxBuffer, uint32_t size,
1320 cy_en_smif_txfr_width_t transferWidth,
1321 cy_smif_event_cb_t RxCompleteCb,
1322 cy_stc_smif_context_t *context);
1323 cy_en_smif_status_t Cy_SMIF_ReceiveDataBlocking(SMIF_Type *base,
1324 uint8_t *rxBuffer,
1325 uint32_t size,
1326 cy_en_smif_txfr_width_t transferWidth,
1327 cy_stc_smif_context_t const *context);
1328 cy_en_smif_status_t Cy_SMIF_SendDummyCycles(SMIF_Type *base, uint32_t cycles);
1329 uint32_t Cy_SMIF_GetTransferStatus(SMIF_Type const *base, cy_stc_smif_context_t const *context);
1330 void Cy_SMIF_Enable(SMIF_Type *base, cy_stc_smif_context_t *context);
1331
1332 #if (CY_IP_MXSMIF_VERSION>=2) || defined (CY_DOXYGEN)
1333 cy_en_smif_status_t Cy_SMIF_TransmitCommand_Ext(SMIF_Type *base,
1334 uint16_t cmd,
1335 bool isCommand2byte,
1336 cy_en_smif_txfr_width_t cmdTxfrWidth,
1337 cy_en_smif_data_rate_t cmdDataRate,
1338 uint8_t const cmdParam[],
1339 uint32_t paramSize,
1340 cy_en_smif_txfr_width_t paramTxfrWidth,
1341 cy_en_smif_data_rate_t paramDataRate,
1342 cy_en_smif_slave_select_t slaveSelect,
1343 uint32_t completeTxfr,
1344 cy_stc_smif_context_t const *context);
1345
1346 cy_en_smif_status_t Cy_SMIF_TransmitData_Ext(SMIF_Type *base,
1347 uint8_t const *txBuffer,
1348 uint32_t size,
1349 cy_en_smif_txfr_width_t transferWidth,
1350 cy_en_smif_data_rate_t dataDataRate,
1351 cy_smif_event_cb_t TxCmpltCb,
1352 cy_stc_smif_context_t *context);
1353
1354 cy_en_smif_status_t Cy_SMIF_TransmitDataBlocking_Ext(SMIF_Type *base,
1355 uint8_t const *txBuffer,
1356 uint32_t size,
1357 cy_en_smif_txfr_width_t transferWidth,
1358 cy_en_smif_data_rate_t dataDataRate,
1359 cy_stc_smif_context_t const *context);
1360
1361 cy_en_smif_status_t Cy_SMIF_ReceiveData_Ext(SMIF_Type *base,
1362 uint8_t *rxBuffer,
1363 uint32_t size,
1364 cy_en_smif_txfr_width_t transferWidth,
1365 cy_en_smif_data_rate_t dataRate,
1366 cy_smif_event_cb_t RxCmpltCb,
1367 cy_stc_smif_context_t *context);
1368
1369 cy_en_smif_status_t Cy_SMIF_ReceiveDataBlocking_Ext(SMIF_Type *base,
1370 uint8_t *rxBuffer,
1371 uint32_t size,
1372 cy_en_smif_txfr_width_t transferWidth,
1373 cy_en_smif_data_rate_t dataRate,
1374 cy_stc_smif_context_t const *context);
1375
1376 cy_en_smif_status_t Cy_SMIF_SendDummyCycles_Ext(SMIF_Type *base,
1377 cy_en_smif_txfr_width_t transferWidth,
1378 cy_en_smif_data_rate_t dataRate,
1379 uint32_t cycles);
1380 cy_en_smif_status_t Cy_SMIF_SendDummyCycles_With_RWDS(SMIF_Type *base,
1381 bool read_rwds,
1382 bool refresh_indicator,
1383 uint32_t cycles);
1384 void Cy_SMIF_DeviceTransfer_SetMergeTimeout(SMIF_Type *base, cy_en_smif_slave_select_t slave, cy_en_smif_merge_timeout_t timeout);
1385 void Cy_SMIF_DeviceTransfer_ClearMergeTimeout(SMIF_Type *base, cy_en_smif_slave_select_t slave);
1386
1387 #if (CY_IP_MXSMIF_VERSION == 2U)
1388 cy_en_smif_status_t Cy_SMIF_Set_DelayTapSel(SMIF_Type *base, uint8_t tapSel);
1389 uint8_t Cy_SMIF_Get_DelayTapSel(SMIF_Type *base);
1390 #endif /* (CY_IP_MXSMIF_VERSION==2) */
1391 #endif /* CY_IP_MXSMIF_VERSION>=2*/
1392
1393 __STATIC_INLINE void Cy_SMIF_Disable(SMIF_Type *base);
1394 __STATIC_INLINE void Cy_SMIF_SetInterruptMask(SMIF_Type *base, uint32_t interrupt);
1395 __STATIC_INLINE uint32_t Cy_SMIF_GetInterruptMask(SMIF_Type const *base);
1396 __STATIC_INLINE uint32_t Cy_SMIF_GetInterruptStatusMasked(SMIF_Type const *base);
1397 __STATIC_INLINE uint32_t Cy_SMIF_GetInterruptStatus(SMIF_Type const *base);
1398 __STATIC_INLINE void Cy_SMIF_SetInterrupt(SMIF_Type *base, uint32_t interrupt);
1399 __STATIC_INLINE void Cy_SMIF_ClearInterrupt(SMIF_Type *base, uint32_t interrupt);
1400 __STATIC_INLINE void Cy_SMIF_SetTxFifoTriggerLevel(SMIF_Type *base, uint32_t level);
1401 __STATIC_INLINE void Cy_SMIF_SetRxFifoTriggerLevel(SMIF_Type *base, uint32_t level);
1402 __STATIC_INLINE uint32_t Cy_SMIF_GetCmdFifoStatus(SMIF_Type const *base);
1403 __STATIC_INLINE uint32_t Cy_SMIF_GetTxFifoStatus(SMIF_Type const *base);
1404 __STATIC_INLINE uint32_t Cy_SMIF_GetRxFifoStatus(SMIF_Type const *base);
1405 cy_en_smif_status_t Cy_SMIF_Encrypt(SMIF_Type *base,
1406 uint32_t address,
1407 uint8_t data[],
1408 uint32_t size,
1409 cy_stc_smif_context_t const *context);
1410 __STATIC_INLINE bool Cy_SMIF_BusyCheck(SMIF_Type const *base);
1411 __STATIC_INLINE void Cy_SMIF_Interrupt(SMIF_Type *base, cy_stc_smif_context_t *context);
1412 cy_en_smif_status_t Cy_SMIF_CacheEnable(SMIF_Type *base, cy_en_smif_cache_t cacheType);
1413 cy_en_smif_status_t Cy_SMIF_CacheDisable(SMIF_Type *base, cy_en_smif_cache_t cacheType);
1414 cy_en_smif_status_t Cy_SMIF_CachePrefetchingEnable(SMIF_Type *base, cy_en_smif_cache_t cacheType);
1415 cy_en_smif_status_t Cy_SMIF_CachePrefetchingDisable(SMIF_Type *base, cy_en_smif_cache_t cacheType);
1416 cy_en_smif_status_t Cy_SMIF_CacheInvalidate(SMIF_Type *base, cy_en_smif_cache_t cacheType);
1417 void Cy_SMIF_SetCryptoKey(SMIF_Type *base, uint32_t *key);
1418 void Cy_SMIF_SetCryptoIV(SMIF_Type *base, uint32_t *nonce);
1419 cy_en_smif_status_t Cy_SMIF_SetCryptoEnable(SMIF_Type *base, cy_en_smif_slave_select_t slaveId);
1420 cy_en_smif_status_t Cy_SMIF_SetCryptoDisable(SMIF_Type *base, cy_en_smif_slave_select_t slaveId);
1421 cy_en_smif_status_t Cy_SMIF_ConvertSlaveSlotToIndex(cy_en_smif_slave_select_t ss, uint32_t *device_idx);
1422 #if (CY_IP_MXSMIF_VERSION>=4) || defined (CY_DOXYGEN)
1423 cy_en_smif_status_t Cy_SMIF_SetRxCaptureMode(SMIF_Type *base, cy_en_smif_capture_mode_t mode, cy_en_smif_slave_select_t slaveId);
1424 cy_en_smif_status_t Cy_SMIF_SetMasterDLP(SMIF_Type *base, uint16 dlp, uint8_t size);
1425 uint16_t Cy_SMIF_GetMasterDLP(SMIF_Type *base);
1426 uint8_t Cy_SMIF_GetMasterDLPSize(SMIF_Type *base);
1427 uint8_t Cy_SMIF_GetTapNumCapturedCorrectDLP(SMIF_Type *base, uint8_t bit);
1428 #endif
1429 #if (CY_IP_MXSMIF_VERSION>=5) || defined (CY_DOXYGEN)
1430 cy_en_smif_status_t Cy_SMIF_SetSelectedDelayTapSel(SMIF_Type *base, cy_en_smif_slave_select_t slave,
1431 cy_en_smif_mem_data_line_t data_line, uint8_t tapSel);
1432 uint8_t Cy_SMIF_GetSelectedDelayTapSel(SMIF_Type *base, cy_en_smif_slave_select_t slave,
1433 cy_en_smif_mem_data_line_t data_line);
1434 #endif
1435 /** \addtogroup group_smif_functions_syspm_callback
1436 * The driver supports SysPm callback for Deep Sleep and Hibernate transition.
1437 * \{
1438 */
1439 #if defined (CY_IP_MXS40SRSS) || defined (CY_IP_MXS40SSRSS) || defined (CY_IP_MXS22SRSS)
1440 cy_en_syspm_status_t Cy_SMIF_DeepSleepCallback(cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode);
1441 cy_en_syspm_status_t Cy_SMIF_HibernateCallback(cy_stc_syspm_callback_params_t *callbackParams, cy_en_syspm_callback_mode_t mode);
1442 #endif
1443 /** \} */
1444
1445
1446 /***************************************
1447 * Internal SMIF function declarations
1448 ****************************************/
1449 /** \cond INTERNAL */
1450 __STATIC_INLINE void Cy_SMIF_PushTxFifo(SMIF_Type *baseaddr, cy_stc_smif_context_t *context); /**< Writes transmitted data into the FIFO. */
1451 __STATIC_INLINE void Cy_SMIF_PopRxFifo(SMIF_Type *baseaddr, cy_stc_smif_context_t *context); /**< Reads received data from the FIFO. */
1452 __STATIC_INLINE uint32_t Cy_SMIF_PackBytesArray(uint8_t const buff[], bool fourBytes);
1453 __STATIC_INLINE void Cy_SMIF_UnPackByteArray(uint32_t inValue, uint8_t outBuff[], bool fourBytes);
1454 __STATIC_INLINE cy_en_smif_status_t Cy_SMIF_TimeoutRun(uint32_t *timeoutUnits);
1455 __STATIC_INLINE SMIF_DEVICE_Type volatile * Cy_SMIF_GetDeviceBySlot(SMIF_Type *base, cy_en_smif_slave_select_t slaveSelect);
1456 /** \endcond */
1457
1458 /** \} group_smif_low_level_functions */
1459
1460
1461 /**
1462 * \addtogroup group_smif_low_level_functions
1463 * \{
1464 */
1465
1466 /*******************************************************************************
1467 * Function Name: Cy_SMIF_Disable
1468 ****************************************************************************//**
1469 *
1470 * Disables the operation of the SMIF block. The SMIF block can be disabled only
1471 * when it is not in the active state. Use the Cy_SMIF_BusyCheck() API to check
1472 * it before calling this API. Make sure the clock supplied to SMIF block is also
1473 * disabled before calling this API using \ref Cy_SysClk_ClkHfDisable
1474 *
1475 * \param base
1476 * Holds the base address of the SMIF block registers.
1477 *
1478 *******************************************************************************/
Cy_SMIF_Disable(SMIF_Type * base)1479 __STATIC_INLINE void Cy_SMIF_Disable(SMIF_Type *base)
1480 {
1481 SMIF_CTL(base) &= ~SMIF_CTL_ENABLED_Msk;
1482 }
1483
1484
1485 /*******************************************************************************
1486 * Function Name: Cy_SMIF_SetInterruptMask
1487 ****************************************************************************//**
1488 *
1489 * This function is used to set an interrupt mask for the SMIF Interrupt.
1490 *
1491 * \param base
1492 * Holds the base address of the SMIF block registers.
1493 *
1494 * \param interrupt
1495 * This is the mask for different source options that can be masked. See
1496 * \ref group_smif_macros_isr "Interrupt Macros" for possible values.
1497 *
1498 *******************************************************************************/
Cy_SMIF_SetInterruptMask(SMIF_Type * base,uint32_t interrupt)1499 __STATIC_INLINE void Cy_SMIF_SetInterruptMask(SMIF_Type *base, uint32_t interrupt)
1500 {
1501 SMIF_INTR_MASK(base) = interrupt;
1502 }
1503
1504
1505 /*******************************************************************************
1506 * Function Name: Cy_SMIF_GetInterruptMask
1507 ****************************************************************************//**
1508 *
1509 * This function is used to read an interrupt mask for the SMIF Interrupt.
1510 *
1511 * \param base
1512 * Holds the base address of the SMIF block registers.
1513 *
1514 * \return Returns the mask set for the SMIF interrupt.
1515 *
1516 *******************************************************************************/
Cy_SMIF_GetInterruptMask(SMIF_Type const * base)1517 __STATIC_INLINE uint32_t Cy_SMIF_GetInterruptMask(SMIF_Type const *base)
1518 {
1519 return (SMIF_INTR_MASK(base));
1520 }
1521
1522
1523 /*******************************************************************************
1524 * Function Name: Cy_SMIF_GetInterruptStatusMasked
1525 ****************************************************************************//**
1526 *
1527 * This function is used to read an active masked interrupt. This function can
1528 * be used in the interrupt service-routine to find which source triggered the
1529 * interrupt.
1530 *
1531 * \param base
1532 * Holds the base address of the SMIF block registers.
1533 *
1534 * \return Returns a word with bits set at positions corresponding to the
1535 * interrupts triggered in the system.
1536 *
1537 *******************************************************************************/
Cy_SMIF_GetInterruptStatusMasked(SMIF_Type const * base)1538 __STATIC_INLINE uint32_t Cy_SMIF_GetInterruptStatusMasked(SMIF_Type const *base)
1539 {
1540 return (SMIF_INTR_MASKED(base));
1541 }
1542
1543
1544 /*******************************************************************************
1545 * Function Name: Cy_SMIF_GetInterruptStatus
1546 ****************************************************************************//**
1547 *
1548 * This function is used to read an active interrupt. This status is the unmasked
1549 * result, so will also show interrupts that will not generate active interrupts.
1550 *
1551 * \param base
1552 * Holds the base address of the SMIF block registers.
1553 *
1554 * \return Returns a word with bits set at positions corresponding to the
1555 * interrupts triggered in the system.
1556 *
1557 *******************************************************************************/
Cy_SMIF_GetInterruptStatus(SMIF_Type const * base)1558 __STATIC_INLINE uint32_t Cy_SMIF_GetInterruptStatus(SMIF_Type const *base)
1559 {
1560 return (SMIF_INTR(base));
1561 }
1562
1563
1564 /*******************************************************************************
1565 * Function Name: Cy_SMIF_SetInterrupt
1566 ****************************************************************************//**
1567 *
1568 * This function is used to set an interrupt source. This function can be used
1569 * to activate interrupts through the software.
1570 *
1571 * \note Interrupt sources set using this interrupt will generate interrupts only
1572 * if they are not masked.
1573 *
1574 * \param base
1575 * Holds the base address of the SMIF block registers.
1576 *
1577 * \param interrupt
1578 * An encoded integer with a bit set corresponding to the interrupt to be
1579 * triggered. See \ref group_smif_macros_isr "Interrupt Macros" for possible
1580 * values.
1581 *
1582 *******************************************************************************/
Cy_SMIF_SetInterrupt(SMIF_Type * base,uint32_t interrupt)1583 __STATIC_INLINE void Cy_SMIF_SetInterrupt(SMIF_Type *base, uint32_t interrupt)
1584 {
1585 SMIF_INTR_SET(base) = interrupt;
1586 }
1587
1588
1589 /*******************************************************************************
1590 * Function Name: Cy_SMIF_ClearInterrupt
1591 ****************************************************************************//**
1592 *
1593 * This function is used to clear an interrupt source. This function can be used
1594 * in the user code to clear all pending interrupts.
1595 *
1596 * \param base
1597 * Holds the base address of the SMIF block registers.
1598 *
1599 * \param interrupt
1600 * An encoded integer with a bit set corresponding to the interrupt that must
1601 * be cleared. See \ref group_smif_macros_isr "Interrupt Macros" for possible
1602 * values.
1603 *
1604 *******************************************************************************/
Cy_SMIF_ClearInterrupt(SMIF_Type * base,uint32_t interrupt)1605 __STATIC_INLINE void Cy_SMIF_ClearInterrupt(SMIF_Type *base, uint32_t interrupt)
1606 {
1607 SMIF_INTR(base) = interrupt;
1608
1609 /* Ensure that the initial Write has been flushed out to the hardware. */
1610 interrupt = SMIF_INTR(base);
1611 }
1612
1613
1614 /*******************************************************************************
1615 * Function Name: Cy_SMIF_SetTxFifoTriggerLevel()
1616 ****************************************************************************//**
1617 *
1618 * This function is used to set a trigger level for the TX FIFO. This value must
1619 * be an integer between 0 and 7. For the normal mode only.
1620 * The triggering is active when TX_DATA_FIFO_STATUS <= level.
1621 *
1622 * \param base
1623 * Holds the base address of the SMIF block registers.
1624 *
1625 * \param level
1626 * The trigger level to set (0-8).
1627 *
1628 *******************************************************************************/
Cy_SMIF_SetTxFifoTriggerLevel(SMIF_Type * base,uint32_t level)1629 __STATIC_INLINE void Cy_SMIF_SetTxFifoTriggerLevel(SMIF_Type *base, uint32_t level)
1630 {
1631 CY_ASSERT_L2(level <= CY_SMIF_MAX_TX_TR_LEVEL);
1632 SMIF_TX_DATA_FIFO_CTL(base) = level;
1633 }
1634
1635
1636 /*******************************************************************************
1637 * Function Name: Cy_SMIF_SetRxFifoTriggerLevel()
1638 ****************************************************************************//**
1639 *
1640 * This function is used to set a trigger level for the RX FIFO. This value must
1641 * be an integer between 0 and 7. For the normal mode only.
1642 * The triggering is active when RX_DATA_FIFOSTATUS > level.
1643 *
1644 * \param base
1645 * Holds the base address of the SMIF block registers.
1646 *
1647 * \param level
1648 * The trigger level to set(0-8).
1649 *
1650 *******************************************************************************/
Cy_SMIF_SetRxFifoTriggerLevel(SMIF_Type * base,uint32_t level)1651 __STATIC_INLINE void Cy_SMIF_SetRxFifoTriggerLevel(SMIF_Type *base, uint32_t level)
1652 {
1653 CY_ASSERT_L2(level <= CY_SMIF_MAX_RX_TR_LEVEL);
1654 SMIF_RX_DATA_FIFO_CTL(base) = level;
1655 }
1656
1657
1658 /*******************************************************************************
1659 * Function Name: Cy_SMIF_GetCmdFifoStatus()
1660 ****************************************************************************//**
1661 *
1662 * This function is used to read the status of the CMD FIFO.
1663 *
1664 * \param base
1665 * Holds the base address of the SMIF block registers.
1666 *
1667 * \return Returns the number of the entries in the CMD FIFO.
1668 *
1669 *******************************************************************************/
Cy_SMIF_GetCmdFifoStatus(SMIF_Type const * base)1670 __STATIC_INLINE uint32_t Cy_SMIF_GetCmdFifoStatus(SMIF_Type const *base)
1671 {
1672 #if (CY_IP_MXSMIF_VERSION>=3)
1673 return (_FLD2VAL(SMIF_TX_CMD_MMIO_FIFO_STATUS_USED4, SMIF_TX_CMD_MMIO_FIFO_STATUS(base)));
1674 #elif (CY_IP_MXSMIF_VERSION == 2)
1675 return (_FLD2VAL(SMIF_TX_CMD_FIFO_STATUS_USED4, SMIF_TX_CMD_FIFO_STATUS(base)));
1676 #else
1677 return (_FLD2VAL(SMIF_TX_CMD_FIFO_STATUS_USED3, SMIF_TX_CMD_FIFO_STATUS(base)));
1678 #endif /* CY_IP_MXSMIF_VERSION */
1679 }
1680
1681
1682 /*******************************************************************************
1683 * Function Name: Cy_SMIF_GetTxFifoStatus()
1684 ****************************************************************************//**
1685 *
1686 * This function is used to read the status of the TX FIFO.
1687 *
1688 * \param base
1689 * Holds the base address of the SMIF block registers.
1690 *
1691 * \return Returns the number of the entries in the TX FIFO.
1692 *
1693 *******************************************************************************/
Cy_SMIF_GetTxFifoStatus(SMIF_Type const * base)1694 __STATIC_INLINE uint32_t Cy_SMIF_GetTxFifoStatus(SMIF_Type const *base)
1695 {
1696 #if (CY_IP_MXSMIF_VERSION>=3)
1697 return (_FLD2VAL(SMIF_TX_DATA_MMIO_FIFO_STATUS_USED4, SMIF_TX_DATA_MMIO_FIFO_STATUS(base)));
1698 #else
1699 return (_FLD2VAL(SMIF_TX_DATA_FIFO_STATUS_USED4, SMIF_TX_DATA_FIFO_STATUS(base)));
1700 #endif /* CY_IP_MXSMIF_VERSION */
1701 }
1702
1703
1704 /*******************************************************************************
1705 * Function Name: Cy_SMIF_GetRxFifoStatus()
1706 ****************************************************************************//**
1707 *
1708 * This function is used to read the status of the RX FIFO.
1709 *
1710 * \param base
1711 * Holds the base address of the SMIF block registers.
1712 *
1713 * \return Returns the number of the entries in the RX FIFO.
1714 *
1715 *******************************************************************************/
Cy_SMIF_GetRxFifoStatus(SMIF_Type const * base)1716 __STATIC_INLINE uint32_t Cy_SMIF_GetRxFifoStatus(SMIF_Type const *base)
1717 {
1718 #if (CY_IP_MXSMIF_VERSION>=2)
1719 return (_FLD2VAL(SMIF_RX_DATA_MMIO_FIFO_STATUS_USED4, SMIF_RX_DATA_MMIO_FIFO_STATUS(base)));
1720 #else
1721 return (_FLD2VAL(SMIF_RX_DATA_FIFO_STATUS_USED4, SMIF_RX_DATA_FIFO_STATUS(base)));
1722 #endif /* CY_IP_MXSMIF_VERSION */
1723 }
1724
1725
1726 /*******************************************************************************
1727 * Function Name: Cy_SMIF_BusyCheck
1728 ****************************************************************************//**
1729 *
1730 * This function provides the status of the IP block (False - not busy,
1731 * True - busy).
1732 *
1733 * \param base
1734 * Holds the base address of the SMIF block registers.
1735 *
1736 * \return Returns an IP block status.
1737 *
1738 *******************************************************************************/
Cy_SMIF_BusyCheck(SMIF_Type const * base)1739 __STATIC_INLINE bool Cy_SMIF_BusyCheck(SMIF_Type const *base)
1740 {
1741 return (1UL == _FLD2VAL(SMIF_STATUS_BUSY, SMIF_STATUS(base)));
1742 }
1743
1744
1745 /*******************************************************************************
1746 * Function Name: Cy_SMIF_Interrupt
1747 ****************************************************************************//**
1748 *
1749 * The Interrupt Service Routine for the SMIF. The interrupt code will be
1750 * responsible for the FIFO operations on FIFO interrupts during ongoing transfers.
1751 * The user must place a call to this interrupt function in the interrupt
1752 * routine corresponding to the interrupt attached to the SMIF. If the
1753 * user does not do this, will break: the functionality of all the API functions in
1754 * the SMIF driver that use SMIF interrupts to affect transfers.
1755 *
1756 * \param base
1757 * Holds the base address of the SMIF block registers.
1758 *
1759 * \param context
1760 * Passes a configuration structure that contains the transfer parameters of the
1761 * SMIF block.
1762 *
1763 * \globalvars
1764 * - context->txBufferAddress - The pointer to the data to be transferred.
1765 *
1766 * - context->txBufferSize - The size of txBuffer.
1767 *
1768 * - context->txBufferCounter - The number of data entries left to be transferred.
1769 *
1770 * All the Global variables described above are used when the Software Buffer is
1771 * used.
1772 *
1773 *******************************************************************************/
Cy_SMIF_Interrupt(SMIF_Type * base,cy_stc_smif_context_t * context)1774 __STATIC_INLINE void Cy_SMIF_Interrupt(SMIF_Type *base, cy_stc_smif_context_t *context)
1775 {
1776 uint32_t interruptStatus = Cy_SMIF_GetInterruptStatusMasked(base);
1777
1778 /* Check which interrupt occurred */
1779 if (0U != (interruptStatus & SMIF_INTR_TR_TX_REQ_Msk))
1780 {
1781 /* Send data */
1782 Cy_SMIF_PushTxFifo(base, context);
1783
1784 Cy_SMIF_ClearInterrupt(base, SMIF_INTR_TR_TX_REQ_Msk);
1785 }
1786 else if (0U != (interruptStatus & SMIF_INTR_TR_RX_REQ_Msk))
1787 {
1788 /* Receive data */
1789 Cy_SMIF_PopRxFifo(base, context);
1790
1791 Cy_SMIF_ClearInterrupt(base, SMIF_INTR_TR_RX_REQ_Msk);
1792 }
1793 else if (0U != (interruptStatus & SMIF_INTR_XIP_ALIGNMENT_ERROR_Msk))
1794 {
1795 /* An XIP alignment error */
1796 context->transferStatus = (uint32_t) CY_SMIF_XIP_ERROR;
1797
1798 Cy_SMIF_ClearInterrupt(base, SMIF_INTR_XIP_ALIGNMENT_ERROR_Msk);
1799 }
1800
1801 else if (0U != (interruptStatus & SMIF_INTR_TX_CMD_FIFO_OVERFLOW_Msk))
1802 {
1803 /* TX CMD FIFO overflow */
1804 context->transferStatus = (uint32_t) CY_SMIF_CMD_ERROR;
1805
1806 Cy_SMIF_ClearInterrupt(base, SMIF_INTR_TX_CMD_FIFO_OVERFLOW_Msk);
1807 }
1808
1809 else if (0U != (interruptStatus & SMIF_INTR_TX_DATA_FIFO_OVERFLOW_Msk))
1810 {
1811 /* A TX DATA FIFO overflow */
1812 context->transferStatus = (uint32_t) CY_SMIF_TX_ERROR;
1813
1814 Cy_SMIF_ClearInterrupt(base, SMIF_INTR_TX_DATA_FIFO_OVERFLOW_Msk);
1815 }
1816
1817 else if (0U != (interruptStatus & SMIF_INTR_RX_DATA_FIFO_UNDERFLOW_Msk))
1818 {
1819 /* RX DATA FIFO underflow */
1820 context->transferStatus = (uint32_t) CY_SMIF_RX_ERROR;
1821
1822 Cy_SMIF_ClearInterrupt(base, SMIF_INTR_RX_DATA_FIFO_UNDERFLOW_Msk);
1823 }
1824 else
1825 {
1826 /* Processing of errors */
1827 }
1828 }
1829
1830
1831 /*******************************************************************************
1832 * Internal SMIF in-line functions
1833 *******************************************************************************/
1834
1835 /** \cond INTERNAL */
1836
1837 /*******************************************************************************
1838 * Function Name: Cy_SMIF_PushTxFifo
1839 ***************************************************************************//***
1840 *
1841 * \internal
1842 *
1843 * \param baseaddr
1844 * Holds the base address of the SMIF block registers.
1845 *
1846 * \param context
1847 * Passes a configuration structure that contains the transfer parameters of the
1848 * SMIF block.
1849 *
1850 * This function writes data in the TX FIFO SMIF buffer by 4, 2, or 1 bytes based
1851 * on the residual number of bytes and the available space in the TX FIFO.
1852 *
1853 *******************************************************************************/
Cy_SMIF_PushTxFifo(SMIF_Type * baseaddr,cy_stc_smif_context_t * context)1854 __STATIC_INLINE void Cy_SMIF_PushTxFifo(SMIF_Type *baseaddr, cy_stc_smif_context_t *context)
1855 {
1856 /* The variable that shows which is smaller: the free FIFO size or amount of bytes to be sent */
1857 uint32_t writeBytes;
1858 uint32_t freeFifoBytes;
1859 uint32_t buffCounter = context->txBufferCounter;
1860 uint8_t *buff = (uint8_t*) context->txBufferAddress;
1861
1862 freeFifoBytes = CY_SMIF_TX_DATA_FIFO_STATUS_RANGE - Cy_SMIF_GetTxFifoStatus(baseaddr);
1863 writeBytes = (freeFifoBytes > buffCounter)? buffCounter: freeFifoBytes;
1864
1865 /* Check that after a FIFO Write, no data/FIFO space remains */
1866 while (0U != writeBytes)
1867 {
1868 /* The first main use case for long transfers */
1869 if (writeBytes == CY_SMIF_EIGHT_BYTES)
1870 {
1871 SMIF_TX_DATA_FIFO_WR4(baseaddr) = Cy_SMIF_PackBytesArray(&buff[0U], true);
1872 SMIF_TX_DATA_FIFO_WR4(baseaddr) = Cy_SMIF_PackBytesArray(&buff[4U], true);
1873 }
1874 /* The second main use case for short transfers */
1875 else if(writeBytes == CY_SMIF_ONE_BYTE)
1876 {
1877 #if (CY_IP_MXSMIF_VERSION>=2)
1878 if((context->preCmdDataRate == CY_SMIF_DDR) &&(context->preCmdWidth == CY_SMIF_WIDTH_OCTAL))
1879 {
1880 SMIF_TX_DATA_MMIO_FIFO_WR1ODD(baseaddr) = buff[0U];
1881 }
1882 else
1883 {
1884 SMIF_TX_DATA_MMIO_FIFO_WR1(baseaddr) = buff[0U];
1885 }
1886 #else
1887 SMIF_TX_DATA_FIFO_WR1(baseaddr) = buff[0U];
1888 #endif /* CY_IP_MXSMIF_VERSION */
1889 }
1890 else if ((writeBytes == CY_SMIF_TWO_BYTES) || (writeBytes == CY_SMIF_THREE_BYTES))
1891 {
1892 SMIF_TX_DATA_FIFO_WR2(baseaddr) = Cy_SMIF_PackBytesArray(&buff[0U], false);
1893 writeBytes = CY_SMIF_TWO_BYTES;
1894 }
1895 else if ((writeBytes == CY_SMIF_FOUR_BYTES) || (writeBytes == CY_SMIF_FIVE_BYTES))
1896 {
1897 SMIF_TX_DATA_FIFO_WR4(baseaddr) = Cy_SMIF_PackBytesArray(&buff[0U], true);
1898 writeBytes = CY_SMIF_FOUR_BYTES;
1899 }
1900 else if ((writeBytes == CY_SMIF_SIX_BYTES) || (writeBytes == CY_SMIF_SEVEN_BYTES))
1901 {
1902 SMIF_TX_DATA_FIFO_WR4(baseaddr) = Cy_SMIF_PackBytesArray(&buff[0U], true);
1903 SMIF_TX_DATA_FIFO_WR2(baseaddr) = Cy_SMIF_PackBytesArray(&buff[4U], false);
1904 writeBytes = CY_SMIF_SIX_BYTES;
1905 }
1906 else /* The future IP block with FIFO > 8*/
1907 {
1908 SMIF_TX_DATA_FIFO_WR4(baseaddr) = Cy_SMIF_PackBytesArray(&buff[0U], true);
1909 SMIF_TX_DATA_FIFO_WR4(baseaddr) = Cy_SMIF_PackBytesArray(&buff[4U], true);
1910 writeBytes = CY_SMIF_EIGHT_BYTES;
1911 }
1912 buff = &buff[writeBytes];
1913 buffCounter -= writeBytes;
1914
1915 /* Check if we already got new data in TX_FIFO */
1916 freeFifoBytes = CY_SMIF_TX_DATA_FIFO_STATUS_RANGE - Cy_SMIF_GetTxFifoStatus(baseaddr);
1917 writeBytes = (freeFifoBytes > buffCounter)? buffCounter: freeFifoBytes;
1918 }
1919
1920 /* Save changes in the context */
1921 context->txBufferAddress = buff;
1922 context->txBufferCounter = buffCounter;
1923
1924 /* Check if all bytes are sent */
1925 if (0u == buffCounter)
1926 {
1927 #if (CY_IP_MXSMIF_VERSION >= 4) /* DRIVERS-12031 */
1928 Cy_SMIF_SetTxFifoTriggerLevel(baseaddr, 0U);
1929 #endif
1930
1931 /* Disable the TR_TX_REQ interrupt */
1932 Cy_SMIF_SetInterruptMask(baseaddr, Cy_SMIF_GetInterruptMask(baseaddr) & ~SMIF_INTR_TR_TX_REQ_Msk);
1933
1934 context->transferStatus = (uint32_t) CY_SMIF_SEND_COMPLETE;
1935 if (NULL != context->txCompleteCb)
1936 {
1937 context->txCompleteCb((uint32_t) CY_SMIF_SEND_COMPLETE);
1938 }
1939 }
1940 }
1941
1942
1943 /*******************************************************************************
1944 * Function Name: Cy_SMIF_PopRxFifo
1945 ***************************************************************************//***
1946 *
1947 * \internal
1948 *
1949 * \param baseaddr
1950 * Holds the base address of the SMIF block registers.
1951 *
1952 * \param context
1953 * Passes a configuration structure that contains the transfer parameters of the
1954 * SMIF block.
1955 *
1956 * This function reads data from the RX FIFO SMIF buffer by 4, 2, or 1 bytes
1957 * based on the data availability in the RX FIFO and amount of bytes to be
1958 * received.
1959 *
1960 *******************************************************************************/
Cy_SMIF_PopRxFifo(SMIF_Type * baseaddr,cy_stc_smif_context_t * context)1961 __STATIC_INLINE void Cy_SMIF_PopRxFifo(SMIF_Type *baseaddr, cy_stc_smif_context_t *context)
1962 {
1963 /* The variable that shows which is smaller: the free FIFO size or amount of bytes to be received */
1964 uint32_t readBytes;
1965 uint32_t loadedFifoBytes;
1966 uint32_t buffCounter = context->rxBufferCounter;
1967 uint8_t *buff = (uint8_t*) context->rxBufferAddress;
1968
1969 loadedFifoBytes = Cy_SMIF_GetRxFifoStatus(baseaddr);
1970 readBytes = (loadedFifoBytes > buffCounter)? buffCounter: loadedFifoBytes;
1971
1972 /* Check that after a FIFO Read, no new data is available */
1973 while (0U != readBytes)
1974 {
1975 if (readBytes == CY_SMIF_EIGHT_BYTES)
1976 {
1977 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD4(baseaddr), &buff[0U], true);
1978 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD4(baseaddr), &buff[4U], true);
1979 }
1980 else if(readBytes == CY_SMIF_ONE_BYTE)
1981 {
1982 buff[0U] = (uint8_t)SMIF_RX_DATA_FIFO_RD1(baseaddr);
1983 }
1984 else if(readBytes == CY_SMIF_TWO_BYTES)
1985 {
1986 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD2(baseaddr), &buff[0U], false);
1987 }
1988 else if(readBytes == CY_SMIF_THREE_BYTES)
1989 {
1990 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD2(baseaddr), &buff[0U], false);
1991 buff[2U] = (uint8_t)SMIF_RX_DATA_FIFO_RD1(baseaddr);
1992 }
1993 else if(readBytes == CY_SMIF_FOUR_BYTES)
1994 {
1995 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD4(baseaddr), &buff[0U], true);
1996 }
1997 else if(readBytes == CY_SMIF_FIVE_BYTES)
1998 {
1999 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD4(baseaddr), &buff[0U], true);
2000 buff[4U] = (uint8_t)SMIF_RX_DATA_FIFO_RD1(baseaddr);
2001 }
2002 else if(readBytes == CY_SMIF_SIX_BYTES)
2003 {
2004 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD4(baseaddr), &buff[0U], true);
2005 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD2(baseaddr), &buff[4U], false);
2006 }
2007 else if(readBytes == CY_SMIF_SEVEN_BYTES)
2008 {
2009 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD4(baseaddr), &buff[0U], true);
2010 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD2(baseaddr), &buff[4U], false);
2011 buff[6U] = (uint8_t)SMIF_RX_DATA_FIFO_RD1(baseaddr);
2012 }
2013 else /* The IP block FIFO > 8*/
2014 {
2015 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD4(baseaddr), &buff[0U], true);
2016 Cy_SMIF_UnPackByteArray(SMIF_RX_DATA_FIFO_RD4(baseaddr), &buff[4U], true);
2017 readBytes = CY_SMIF_EIGHT_BYTES;
2018 }
2019
2020 buff = &buff[readBytes];
2021 buffCounter -= readBytes;
2022 /* Check if we already got new data in RX_FIFO */
2023 loadedFifoBytes = Cy_SMIF_GetRxFifoStatus(baseaddr);
2024 readBytes = (loadedFifoBytes > buffCounter)? buffCounter: loadedFifoBytes;
2025 }
2026
2027 /* Save changes in the context */
2028 context->rxBufferAddress = buff;
2029 context->rxBufferCounter = buffCounter;
2030
2031 /* Check if all bytes are received */
2032 if (0UL == buffCounter)
2033 {
2034 #if (CY_IP_MXSMIF_VERSION>=2)
2035 /* In case we have additional byte left out because of WORD based protocol, do a dummy read.*/
2036 if(Cy_SMIF_GetRxFifoStatus(baseaddr) == 1U)
2037 {
2038 (void)(uint8_t)SMIF_RX_DATA_FIFO_RD1(baseaddr);
2039 }
2040 #endif
2041 /* Disable the TR_RX_REQ interrupt */
2042 Cy_SMIF_SetInterruptMask(baseaddr, Cy_SMIF_GetInterruptMask(baseaddr) & ~SMIF_INTR_TR_RX_REQ_Msk);
2043 context->transferStatus = (uint32_t) CY_SMIF_RX_COMPLETE;
2044 if (NULL != context->rxCompleteCb)
2045 {
2046 context->rxCompleteCb((uint32_t) CY_SMIF_RX_COMPLETE);
2047 }
2048 }
2049
2050 context->rxBufferCounter = buffCounter;
2051 }
2052
2053
2054 /*******************************************************************************
2055 * Function Name: Cy_SMIF_PackBytesArray
2056 ***************************************************************************//***
2057 *
2058 * \internal
2059 *
2060 * This function packs 0-numBytes of the buff byte array into a 4-byte value.
2061 *
2062 * \param buff
2063 * The byte array to pack.
2064 *
2065 * \param fourBytes
2066 * - True: The pack is for a 32-bit value.
2067 * - False: The pack is for a 16-bit value.
2068 *
2069 * \return
2070 * The 4-byte value packed from the byte array.
2071 *
2072 *******************************************************************************/
Cy_SMIF_PackBytesArray(uint8_t const buff[],bool fourBytes)2073 __STATIC_INLINE uint32_t Cy_SMIF_PackBytesArray(uint8_t const buff[], bool fourBytes)
2074 {
2075 uint32_t result = 0UL;
2076
2077 result = ((uint32_t)buff[1UL] << 8UL) | (uint32_t)buff[0UL];
2078
2079 if(fourBytes)
2080 {
2081 result |= ((uint32_t)buff[3UL] << 24UL) | ((uint32_t)buff[2UL] << 16UL);
2082 }
2083
2084 return result;
2085 }
2086
2087
2088 /*******************************************************************************
2089 * Function Name: Cy_SMIF_UnPackByteArray
2090 ***************************************************************************//***
2091 *
2092 * \internal
2093 *
2094 * This function unpacks 0-numBytes from a 4-byte value into the byte array outBuff.
2095 *
2096 * \param smifReg
2097 * The 4-byte value to unpack.
2098 *
2099 * \param outBuff
2100 * The byte array to fill.
2101 *
2102 * \param fourBytes
2103 * - The True unpack is for a 32-bit value.
2104 * - The False unpack is for a 16-bit value.
2105 *
2106 *******************************************************************************/
Cy_SMIF_UnPackByteArray(uint32_t inValue,uint8_t outBuff[],bool fourBytes)2107 __STATIC_INLINE void Cy_SMIF_UnPackByteArray(uint32_t inValue, uint8_t outBuff[], bool fourBytes)
2108 {
2109 outBuff[0UL] = (uint8_t)(inValue & 0xFFUL);
2110 outBuff[1UL] = (uint8_t)((inValue >> 8UL ) & 0xFFUL);
2111
2112 if(fourBytes)
2113 {
2114 outBuff[2UL] = (uint8_t)((inValue >> 16UL) & 0xFFUL);
2115 outBuff[3UL] = (uint8_t)((inValue >> 24UL) & 0xFFUL);
2116 }
2117 }
2118
2119
2120 /*******************************************************************************
2121 * Function Name: Cy_SMIF_TimeoutRun
2122 ****************************************************************************//**
2123 *
2124 * \internal
2125 *
2126 * This function checks if the timeout is expired. Use the Cy_SysLib_DelayUs() function for
2127 * implementation.
2128 *
2129 * \param timeoutUnits
2130 * The pointer to the timeout. The timeout measured in microseconds is multiplied by
2131 * CY_SMIF_WAIT_1_UNIT.
2132 *
2133 * \return
2134 * A timeout status:
2135 * - \ref CY_SMIF_SUCCESS - The timeout has not expired or input timeoutUnits is 0.
2136 * - \ref CY_SMIF_EXCEED_TIMEOUT - The timeout has expired.
2137 *
2138 *******************************************************************************/
Cy_SMIF_TimeoutRun(uint32_t * timeoutUnits)2139 __STATIC_INLINE cy_en_smif_status_t Cy_SMIF_TimeoutRun(uint32_t *timeoutUnits)
2140 {
2141 cy_en_smif_status_t status = CY_SMIF_SUCCESS;
2142 if (*timeoutUnits > 0u)
2143 {
2144 Cy_SysLib_DelayUs(CY_SMIF_WAIT_1_UNIT);
2145 --(*timeoutUnits);
2146 status = (0u == (*timeoutUnits))? CY_SMIF_EXCEED_TIMEOUT: CY_SMIF_SUCCESS;
2147 }
2148 return status;
2149 }
2150
2151
2152 /*******************************************************************************
2153 * Function Name: Cy_SMIF_GetDeviceBySlot
2154 ****************************************************************************//**
2155 *
2156 * \internal
2157 * This function returns the address of the SMIF device registers structure by the slave
2158 * slot number.
2159 *
2160 * \param base
2161 * Holds the base address of the SMIF block registers.
2162 *
2163 * \param slaveSelect
2164 * The slave device ID. This number is either CY_SMIF_SLAVE_SELECT_0 or
2165 * CY_SMIF_SLAVE_SELECT_1 or CY_SMIF_SLAVE_SELECT_2 or CY_SMIF_SLAVE_SELECT_3
2166 * (\ref cy_en_smif_slave_select_t). It defines the slave-select line to use
2167 * during the transmission.
2168 *
2169 *******************************************************************************/
Cy_SMIF_GetDeviceBySlot(SMIF_Type * base,cy_en_smif_slave_select_t slaveSelect)2170 __STATIC_INLINE SMIF_DEVICE_Type volatile * Cy_SMIF_GetDeviceBySlot(SMIF_Type *base,
2171 cy_en_smif_slave_select_t slaveSelect)
2172 {
2173 SMIF_DEVICE_Type volatile *device;
2174 /* Connect the slave to its data lines */
2175 switch (slaveSelect)
2176 {
2177 case CY_SMIF_SLAVE_SELECT_0:
2178 device = &(SMIF_DEVICE_IDX(base, 0));
2179 break;
2180 case CY_SMIF_SLAVE_SELECT_1:
2181 device = &(SMIF_DEVICE_IDX(base, 1));
2182 break;
2183 case CY_SMIF_SLAVE_SELECT_2:
2184 device = &(SMIF_DEVICE_IDX(base, 2));
2185 break;
2186 case CY_SMIF_SLAVE_SELECT_3:
2187 device = &(SMIF_DEVICE_IDX(base, 3));
2188 break;
2189 default:
2190 /* A user error */
2191 device = NULL;
2192 break;
2193 }
2194
2195 return device;
2196 }
2197 /** \endcond */
2198 /** \} group_smif_low_level_functions */
2199
2200 #if defined(__cplusplus)
2201 }
2202 #endif
2203
2204 #endif /* CY_IP_MXSMIF */
2205
2206 #endif /* (CY_SMIF_H) */
2207
2208 /** \} group_smif */
2209
2210
2211 /* [] END OF FILE */
2212