1 /***************************************************************************//**
2 * \file cy_smif_sfdp.c
3 * \version 2.60
4 *
5 * \brief
6 * This file provides the source code for SFDP enumeration in SMIF driver.
7 *
8 * Note:
9 *
10 ********************************************************************************
11 * \copyright
12 * Copyright 2022 Cypress Semiconductor Corporation
13 * SPDX-License-Identifier: Apache-2.0
14 *
15 * Licensed under the Apache License, Version 2.0 (the "License");
16 * you may not use this file except in compliance with the License.
17 * You may obtain a copy of the License at
18 *
19 * http://www.apache.org/licenses/LICENSE-2.0
20 *
21 * Unless required by applicable law or agreed to in writing, software
22 * distributed under the License is distributed on an "AS IS" BASIS,
23 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24 * See the License for the specific language governing permissions and
25 * limitations under the License.
26 *******************************************************************************/
27
28 #include "cy_device.h"
29
30 #if defined (CY_IP_MXSMIF)
31
32 #include "cy_smif_memslot.h"
33
34 #if defined(__cplusplus)
35 extern "C" {
36 #endif
37
38 /** \cond INTERNAL */
39 /***************************************
40 * Internal Constants
41 ***************************************/
42
43 #define READ_ENHANCED_MODE_DISABLED (0xFFU)
44 #define BITS_IN_BYTE (8U)
45 #define BYTES_IN_DWORD (4U)
46 #define FOUR_BYTE_ADDRESS (4U) /* 4 byte addressing mode */
47 #define BITS_IN_BYTE_ABOVE_4GB (3U) /* Density of memory above 4GBit stored as poser of 2 */
48 #define PARAM_HEADERS_NUM (CY_SMIF_SFDP_BFPT_BYTE_06)
49 #define FIRST_HEADER_OFFSET (0x08U) /* The offset of the 1-st Parameter Header */
50 #define PARAM_ID_MSB_REL_OFFSET (0x07U) /* The relative offset of Parameter ID MSB
51 * in the SFDP Header table
52 */
53 #define PARAM_MINOR_REV_REL_OFFSET (0x01U) /* The relative offset of Parameter Minor Revision
54 * in the SFDP Header table
55 */
56 #define PARAM_MAJOR_REV_REL_OFFSET (0x02U) /* The relative offset of Parameter Major Revision
57 * in the SFDP Header table
58 */
59 #define PARAM_TABLE_PRT_OFFSET (0x04UL) /* The relative offset of Parameter Table Pointer Byte 1 */
60 #define PARAM_TABLE_LENGTH_OFFSET (0X03U) /* The offset of Parameter Table Length in the Header Table */
61 #define PARAM_HEADER_NUM (6U) /* The supported number of the parameter headers */
62 #define HEADER_LENGTH (0x8U) /* The length of the SFDP header */
63 #define HEADERS_LENGTH (HEADER_LENGTH + \
64 (CY_SMIF_SFDP_PARAM_HEADER_LENGTH * PARAM_HEADER_NUM))
65 #define TYPE_STEP (2UL) /* The Erase Type step in the Basic Flash Parameter Table */
66 #define INSTRUCTION_NOT_SUPPORTED (0XFFU) /* The code for the not supported instruction */
67 #define BASIC_SPI_ID (0XFF00UL) /* The JEDEC SFDP Basic SPI Flash Parameter ID */
68 #define SECTOR_MAP_ID (0xFF81UL) /* The JEDEC SFDP Sector Map ID */
69 #define SECTOR_MAP_DESCRIPTOR_MASK (0x2U) /* The mask for the type bit of the Sector Map descriptor */
70 #define SECTOR_MAP_COMAND_DESCRIPTOR_TYPE (0U) /* Code for the command descriptor type */
71 #define SECTOR_MAP_REGION_SIZE_MULTIPLIER (256UL) /* The multiplier for region size units */
72 #define FOUR_BYTE_ADDR_ID (0XFF84UL) /* The 4-byte Address Instruction Table is assigned the ID MSB of FFh */
73 #define FOUR_BYTE_ADDR_ERASE_TYPE_1 (0X4UL) /* The Erase Type 1 offset in 4-byte Address Instruction Table */
74 #define FOUR_BYTE_ADDR_ERASE_TYPE_4 (0X7UL) /* The Erase Type 4 offset in 4-byte Address Instruction Table */
75 #define ERASE_T_COUNT_Pos (0UL) /* Erase Type X Erase, Typical time: count (Bits 4:0) */
76 #define ERASE_T_COUNT_Msk (0x1FUL) /* Erase Type X Erase, Typical time: count (Bitfield-Mask) */
77 #define ERASE_T_UNITS_Pos (5UL) /* Erase Type X Erase, Typical time: units (Bits 6:5) */
78 #define ERASE_T_UNITS_Msk (0x60UL) /* Erase Type X Erase, Typical time: units (Bitfield-Mask) */
79 #define ERASE_T_COUNT_OFFSET (0x04U) /* The offset of the Erase count 10th DWORD */
80 #define ERASE_T_LENGTH (0x07U) /* The Erase Type Typical time length */
81 #define SCCR_MAP_SPI_ID (0xFF87U) /* SCCR Map for SPI Memory Devices MSB */
82 #define XSPI_PROFILE_1_0_ID (0xFF05UL) /* eXtended Serial Peripheral Interface (xSPI) Profile 1.0 */
83 #define CMD_SEQ_FOR_ODDR_ID (0xFF0AUL) /* Command Sequences to change to Octal DDR (8D-8D-8D) mode */
84 #define COMMAND_IS_NOT_FOUND (0x0U)
85 #define PARAMETER_IS_NOT_FOUND (0x0U)
86
87 #define SMIF_TRANSFER_TIMEOUT (1000UL) /* The timeout (microseconds) to use in polling of
88 * the transfer status of the SMIF block
89 */
90 #define SUPPORT_ERASE_COMMAND_Pos (1UL) /* The position of the Support for Erase Commands
91 * in byte 1 of the JEDEC 4-byte Address Instruction Table
92 */
93 #define SUPPORT_ERASE_COMMAND_Msk (0x0000001EUL) /* The mask of the Support for Erase Commands
94 * in the JEDEC 4-byte Address Instruction Table
95 */
96 #define SUPPORT_FAST_READ_1S_1S_1S_CMD_Pos (1UL) /* The position of the Support for Fast Read Command 1S-1S-1S
97 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
98 */
99 #define SUPPORT_FAST_READ_1S_1S_1S_CMD_Msk (0x00000002UL) /* The mask of the Support for Fast Read Command 1S-1S-1S
100 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
101 */
102 #define SUPPORT_FAST_READ_1S_1S_2S_CMD_Pos (2UL) /* The position of the Support for Fast Read Command 1S-1S-2S
103 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
104 */
105 #define SUPPORT_FAST_READ_1S_1S_2S_CMD_Msk (0x00000004UL) /* The mask of the Support for Fast Read Command 1S-1S-2S
106 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
107 */
108 #define SUPPORT_FAST_READ_1S_2S_2S_CMD_Pos (3UL) /* The position of the Support for Fast Read Command 1S-2S-2S
109 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
110 */
111 #define SUPPORT_FAST_READ_1S_2S_2S_CMD_Msk (0x00000008UL) /* The mask of the Support for Fast Read Command 1S-2S-2S
112 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
113 */
114 #define SUPPORT_FAST_READ_1S_1S_4S_CMD_Pos (4UL) /* The position of the Support for Fast Read Command 1S-1S-4S
115 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
116 */
117 #define SUPPORT_FAST_READ_1S_1S_4S_CMD_Msk (0x00000010UL) /* The mask of the Support for Fast Read Command 1S-1S-4S
118 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
119 */
120 #define SUPPORT_FAST_READ_1S_4S_4S_CMD_Pos (5UL) /* The position of the Support for Fast Read Command 1S-4S-4S
121 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
122 */
123 #define SUPPORT_FAST_READ_1S_4S_4S_CMD_Msk (0x00000020UL) /* The mask of the Support for Fast Read Command 1S-4S-4S
124 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
125 */
126 #define SUPPORT_PP_1S_1S_1S_CMD_Pos (6UL) /* The position of the Support for Page Program Command 1S-1S-1S
127 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
128 */
129 #define SUPPORT_PP_1S_1S_1S_CMD_Msk (0x00000040UL) /* The mask of the Support for Page Program Command 1S-1S-1S
130 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
131 */
132 #define SUPPORT_PP_1S_1S_4S_CMD_Pos (7UL) /* The position of the Support for Page Program Command 1S-1S-4S
133 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
134 */
135 #define SUPPORT_PP_1S_1S_4S_CMD_Msk (0x00000080UL) /* The mask of the Support for Page Program Command 1S-1S-4S
136 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
137 */
138 #define SUPPORT_PP_1S_4S_4S_CMD_Pos (8UL) /* The position of the Support for Page Program Command 1S-4S-4S
139 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
140 */
141 #define SUPPORT_PP_1S_4S_4S_CMD_Msk (0x00000100UL) /* The mask of the Support for Page Program Command 1S-4S-4S
142 * in the JEDEC 4-byte Address Instruction Table, DWORD 1
143 */
144 #define SUPPORT_FAST_READ_1S_1S_8S_CMD_Pos (20UL) /* The position of the Support for Fast Read Command 1S-1S-8S */
145 #define SUPPORT_FAST_READ_1S_1S_8S_CMD_Msk (0x00100000UL) /* The mask of the Support for Fast Read Command 1S-1S-8S */
146 #define SUPPORT_FAST_READ_1S_8S_8S_CMD_Pos (21UL) /* The position of the Support for Fast Read Command 1S-8S-8S */
147 #define SUPPORT_FAST_READ_1S_8S_8S_CMD_Msk (0x00200000UL) /* The mask of the Support for Fast Read Command 1S-8S-8S */
148 #define SUPPORT_FAST_READ_1S_8D_8D_CMD_Pos (22UL) /* The position of the Support for Fast Read Command 1S-8D-8D */
149 #define SUPPORT_FAST_READ_1S_8D_8D_CMD_Msk (0x00400000UL) /* The mask of the Support for Fast Read Command 1S-8D-8D */
150 #define SUPPORT_PP_1S_1S_8S_CMD_Pos (23UL) /* The position of the Support for Page Program Command 1S-1S-8S */
151 #define SUPPORT_PP_1S_1S_8S_CMD_Msk (0x00400000UL) /* The mask of the Support for Page Program Command 1S-1S-8S */
152 #define SUPPORT_PP_1S_8S_8S_CMD_Pos (24UL) /* The position of the Support for Page Program Command 1S-8S-8S */
153 #define SUPPORT_PP_1S_8S_8S_CMD_Msk (0x00400000UL) /* The mask of the Support for Page Program Command 1S-8S-8S */
154
155 #define FOUR_BYTE_ADDRESS_TABLE_BYTE_0 (0U) /* Byte 0x00 of the JEDEC 4-byte Address Instruction Table */
156 #define FOUR_BYTE_ADDRESS_TABLE_BYTE_1 (1U) /* Byte 0x01 of the JEDEC 4-byte Address Instruction Table */
157 #define ERASE_TYPE_COUNT (4U) /* The number of Erase Types */
158
159 #define MEMORY_SIZE_16MB (0x1000000U)
160
161 #define CY_SMIF_CHECK_DEVICE_MEMBERS(device) ((NULL != device->writeEnCmd) || \
162 (NULL != device->writeDisCmd) || \
163 (NULL != device->writeDisCmd)|| \
164 (NULL != device->eraseCmd)|| \
165 (NULL != device->chipEraseCmd)|| \
166 (NULL != device->programCmd)|| \
167 (NULL != device->readStsRegWipCmd))
168
169 /***************************************
170 * Internal enums
171 ***************************************/
172 /** Specifies protocol mode. */
173 typedef enum
174 {
175 PROTOCOL_MODE_1S_1S_1S = 1U, /**< One DQ signal used during command transfer,
176 * address transfer, and data transfer. All phases are SDR.
177 */
178 PROTOCOL_MODE_1S_1S_2S = 2U, /**< One DQ signal used during command transfer, and address transfer,
179 * two DQ signals used during data transfer. All phases are SDR.
180 */
181 PROTOCOL_MODE_1S_2S_2S = 3U, /**< One DQ signal used during command transfer, two DQ signals used
182 * during address transfer, and data transfer. All phases are SDR.
183 */
184 PROTOCOL_MODE_1S_1S_4S = 4U, /**< One DQ signal used during command and address transfer,
185 * four DQ signals used during data transfer. All phases are SDR.
186 */
187 PROTOCOL_MODE_1S_4S_4S = 5U, /**< One DQ signal used during command transfer, four DQ signals used
188 * during address transfer, and data transfer. All phases are SDR.
189 */
190 #if (CY_IP_MXSMIF_VERSION>=2)
191 PROTOCOL_MODE_1S_4D_4D = 6U, /**< One DQ signal used during command transfer in single data rate,
192 * four DQ signals used during address transfer and data transfer in
193 * double data rate.
194 */
195 PROTOCOL_MODE_1S_1S_8S = 7U, /**< One DQ signal used during command and addresstransfer in single data rate,
196 * eight DQ signals used during data transfer in
197 * single data rate.
198 */
199 PROTOCOL_MODE_1S_8S_8S = 8U, /**< One DQ signal used during command transfer in single data rate,
200 * eighth DQ signals used during address transfer and data transfer in
201 * single data rate.
202 */
203 PROTOCOL_MODE_8D_8D_8D = 9U, /**< eight DQ signal used during command, address and data transfer in
204 * double data rate.
205 */
206 #endif /* CY_IP_MXSMIF_VERSION */
207 PROTOCOL_MODE_WRONG = 0xFFU /**< Unknown or unsupported mode */
208 } cy_en_smif_protocol_mode_t;
209 /** \endcond */
210
211
212 /***************************************
213 * Internal Structures
214 ***************************************/
215
216 /**
217 * This internal structure is used to store data for erase types.
218 */
219 typedef struct
220 {
221 uint8_t eraseCmd; /**< The instruction used for erase transaction */
222 uint32_t eraseSize; /**< The number of bytes to be erased at one erase transaction */
223 uint32_t eraseTime; /**< The maximum erase time for one erase transaction */
224 } cy_stc_smif_erase_type_t;
225
226
227 /***************************************
228 * Internal Function Prototypes
229 ***************************************/
230 static cy_en_smif_status_t SfdpReadBuffer(SMIF_Type *base,
231 cy_stc_smif_mem_cmd_t const *cmdSfdp,
232 uint8_t const sfdpAddress[],
233 cy_en_smif_slave_select_t slaveSelect,
234 uint32_t size,
235 uint8_t sfdpBuffer[],
236 cy_stc_smif_context_t *context);
237 static uint32_t SfdpFindParameterHeader(uint32_t id, uint8_t const sfdpBuffer[]);
238 static void SfdpFindParameterTableAddress(uint32_t id,
239 uint8_t const sfdpBuffer[],
240 uint8_t address[],
241 uint8_t *tableLength);
242 static uint32_t SfdpGetNumOfAddrBytes(uint8_t const sfdpBuffer[], uint32_t memorySize);
243 static uint32_t SfdpGetMemoryDensity(uint8_t const sfdpBuffer[]);
244 static void SfdpGetReadCmd_1_4_4(uint8_t const sfdpBuffer[],
245 cy_stc_smif_mem_cmd_t* cmdRead);
246 static void SfdpGetReadCmd_1_1_4(uint8_t const sfdpBuffer[],
247 cy_stc_smif_mem_cmd_t* cmdRead);
248 static void SfdpGetReadCmd_1_2_2(uint8_t const sfdpBuffer[],
249 cy_stc_smif_mem_cmd_t* cmdRead);
250 static void SfdpGetReadCmd_1_1_2(uint8_t const sfdpBuffer[],
251 cy_stc_smif_mem_cmd_t* cmdRead);
252 static void SfdpGetReadCmd_1_1_1(uint8_t const sfdpBuffer[],
253 cy_stc_smif_mem_cmd_t* cmdRead);
254 static cy_en_smif_protocol_mode_t SfdpGetReadCmdParams(uint8_t const sfdpBuffer[],
255 cy_en_smif_data_select_t dataSelect,
256 cy_en_smif_txfr_width_t maxDataWidth,
257 cy_stc_smif_mem_cmd_t* cmdRead);
258 static void SfdpGetReadFourBytesCmd(uint8_t const sfdpBuffer[],
259 cy_en_smif_protocol_mode_t protocolMode,
260 cy_stc_smif_mem_cmd_t* cmdRead);
261 static uint32_t SfdpGetPageSize(uint8_t const sfdpBuffer[]);
262 static uint32_t SfdpGetEraseTime(uint32_t const eraseOffset, uint8_t const sfdpBuffer[], cy_stc_smif_erase_type_t eraseType[]);
263 static uint32_t SfdpGetChipEraseTime(uint8_t const sfdpBuffer[]);
264 static uint32_t SfdpGetPageProgramTime(uint8_t const sfdpBuffer[]);
265 static void SfdpSetWriteEnableCommand(cy_stc_smif_mem_cmd_t* cmdWriteEnable);
266 static void SfdpSetWriteDisableCommand(cy_stc_smif_mem_cmd_t* cmdWriteDisable);
267 static void SfdpSetProgramCommand_1_1_1(cy_stc_smif_mem_cmd_t* cmdProgram);
268 static void SfdpSetProgramCommandFourBytes_1_1_1(cy_stc_smif_mem_cmd_t* cmdProgram);
269 static void SfdpSetProgramCommandFourBytes_1_1_4(cy_stc_smif_mem_cmd_t* cmdProgram);
270 static void SfdpSetProgramCommandFourBytes_1_4_4(cy_stc_smif_mem_cmd_t* cmdProgram);
271 static void SfdpGetProgramFourBytesCmd(uint8_t const sfdpBuffer[],
272 cy_en_smif_protocol_mode_t protocolMode,
273 cy_stc_smif_mem_cmd_t* cmdProgram);
274 static void SfdpSetChipEraseCommand(cy_stc_smif_mem_cmd_t* cmdChipErase);
275 static uint32_t SfdpGetSectorEraseCommand(cy_stc_smif_mem_device_cfg_t *device,
276 uint8_t const sfdpBuffer[],
277 cy_stc_smif_erase_type_t eraseTypeStc[]);
278 static cy_en_smif_status_t SfdpEnterFourByteAddressing(SMIF_Type *base, uint8_t entryMethodByte,
279 cy_stc_smif_mem_device_cfg_t *device,
280 cy_en_smif_slave_select_t slaveSelect,
281 cy_stc_smif_context_t const *context);
282 static void SfdpGetEraseSizeAndCmd(uint8_t const sfdpBuffer[], cy_stc_smif_erase_type_t eraseType[]);
283 static cy_en_smif_status_t SfdpPopulateRegionInfo(SMIF_Type *base, uint8_t const sectorMapBuff[],
284 uint32_t const buffLength, cy_stc_smif_mem_device_cfg_t *device,
285 cy_en_smif_slave_select_t slaveSelect, const cy_stc_smif_context_t *context,
286 cy_stc_smif_erase_type_t eraseType[]);
287 static void SfdpSetWipStatusRegisterCommand(cy_stc_smif_mem_cmd_t* readStsRegWipCmd);
288 #if (CY_IP_MXSMIF_VERSION>=2) && defined (SMIF_OCTAL_SFDP_SUPPORT)
289 static cy_en_smif_status_t Cy_SMIF_MemCmdWriteRegister(SMIF_Type *base,
290 cy_en_smif_slave_select_t slaveSelect,
291 cy_stc_smif_mem_cmd_t *writeEnCmd,
292 cy_stc_smif_mem_cmd_t *writeCmd,
293 uint8_t const cmdParam[],
294 uint32_t paramSize,
295 cy_stc_smif_context_t const *context);
296 #endif
297 #if (CY_IP_MXSMIF_VERSION>=2) && defined (SMIF_OCTAL_SFDP_SUPPORT)
298 /*******************************************************************************
299 * Function Name: Cy_SMIF_MemCmdWriteRegister
300 ****************************************************************************//**
301 *
302 * This function writes the configuration register. This is a blocking function, it will
303 * block the execution flow until the command transmission is completed.
304 *
305 * \note This function uses the low-level Cy_SMIF_TransmitCommand() API.
306 * The Cy_SMIF_TransmitCommand() API works in a blocking mode. In the dual quad mode,
307 * this API is called for each memory.
308 *
309 * \param base
310 * Holds the base address of the SMIF block registers.
311 *
312 * \param slaveSelect
313 * The device to which the command is sent.
314 *
315 * \param writeEnCmd
316 * Write Enable command for issuing before actual write to configuration register.
317 *
318 * \param writeCmd
319 * The command to write into the configuration register.
320 *
321 * \param cmdParam
322 * command parameters include configuration register address and value to be written.
323 *
324 * \param paramSize
325 * command parameter size.
326 *
327 * \param context
328 * This is the pointer to the context structure \ref cy_stc_smif_context_t
329 * allocated by the user. The structure is used during the SMIF
330 * operation for internal configuration and data retention. The user must not
331 * modify anything in this structure.
332 *
333 * \return A status of the command transmission.
334 * - \ref CY_SMIF_SUCCESS
335 * - \ref CY_SMIF_EXCEED_TIMEOUT
336 *
337 *******************************************************************************/
Cy_SMIF_MemCmdWriteRegister(SMIF_Type * base,cy_en_smif_slave_select_t slaveSelect,cy_stc_smif_mem_cmd_t * writeEnCmd,cy_stc_smif_mem_cmd_t * writeCmd,uint8_t const cmdParam[],uint32_t paramSize,cy_stc_smif_context_t const * context)338 static cy_en_smif_status_t Cy_SMIF_MemCmdWriteRegister(SMIF_Type *base,
339 cy_en_smif_slave_select_t slaveSelect,
340 cy_stc_smif_mem_cmd_t *writeEnCmd,
341 cy_stc_smif_mem_cmd_t *writeCmd,
342 uint8_t const cmdParam[],
343 uint32_t paramSize,
344 cy_stc_smif_context_t const *context)
345 {
346 cy_en_smif_status_t result = CY_SMIF_CMD_NOT_FOUND;
347
348 /* The Write Enable */
349 result = Cy_SMIF_TransmitCommand( base, (uint8_t) writeEnCmd->command,
350 writeEnCmd->cmdWidth,
351 NULL,
352 CY_SMIF_CMD_WITHOUT_PARAM,
353 CY_SMIF_WIDTH_NA,
354 slaveSelect,
355 CY_SMIF_TX_LAST_BYTE,
356 context);
357
358 /* The Write value */
359 if (CY_SMIF_SUCCESS == result)
360 {
361 result = Cy_SMIF_TransmitCommand( base, (uint8_t) writeCmd->command, writeCmd->cmdWidth,
362 cmdParam, paramSize, writeCmd->addrWidth,
363 slaveSelect, CY_SMIF_TX_LAST_BYTE, context);
364 }
365 return(result);
366 }
367 #endif
368 /*******************************************************************************
369 * Function Name: SfdpReadBuffer
370 ****************************************************************************//**
371 *
372 * This function reads the tables in the SDFP database into the buffer.
373 *
374 * \note This function is a blocking function and blocks until the structure data
375 * is read and returned. This function uses \ref Cy_SMIF_TransmitCommand()
376 *
377 * \param *base
378 * Holds the base address of the SMIF block registers.
379 *
380 * \param *cmdSfdp
381 * The command structure to store the Read/Write command
382 * configuration.
383 *
384 * \param sfdpAddress
385 * The pointer to an array with the address bytes
386 * associated with the memory command.
387 *
388 * \param slaveSelect
389 * Denotes the number of the slave device to which the transfer is made.
390 * (0, 1, 2 or 4 - the bit defines which slave to enable). The two-bit enable
391 * is possible only for the double quad SPI mode.
392 *
393 * \param size
394 * The size of data to be received. Must be > 0 and not greater than 65536.
395 *
396 * \param sfdpBuffer
397 * The pointer to an array with the SDFP buffer.
398 *
399 * \param context
400 * This is the pointer to the context structure \ref cy_stc_smif_context_t
401 * allocated by the user. The structure is used during the SMIF
402 * operation for internal configuration and data retention. The user must not
403 * modify anything in this structure.
404 *
405 * \return A status of the transmission.
406 * - \ref CY_SMIF_SUCCESS
407 * - \ref CY_SMIF_CMD_FIFO_FULL
408 * - \ref CY_SMIF_NO_SFDP_SUPPORT
409 * - \ref CY_SMIF_EXCEED_TIMEOUT
410 *
411 *******************************************************************************/
SfdpReadBuffer(SMIF_Type * base,cy_stc_smif_mem_cmd_t const * cmdSfdp,uint8_t const sfdpAddress[],cy_en_smif_slave_select_t slaveSelect,uint32_t size,uint8_t sfdpBuffer[],cy_stc_smif_context_t * context)412 static cy_en_smif_status_t SfdpReadBuffer(SMIF_Type *base,
413 cy_stc_smif_mem_cmd_t const *cmdSfdp,
414 uint8_t const sfdpAddress[],
415 cy_en_smif_slave_select_t slaveSelect,
416 uint32_t size,
417 uint8_t sfdpBuffer[],
418 cy_stc_smif_context_t *context)
419 {
420 cy_en_smif_status_t result = CY_SMIF_NO_SFDP_SUPPORT;
421
422 #if (CY_IP_MXSMIF_VERSION == 1U)
423 result = Cy_SMIF_TransmitCommand( base, (uint8_t)cmdSfdp->command,
424 cmdSfdp->cmdWidth, sfdpAddress, CY_SMIF_SFDP_ADDRESS_LENGTH,
425 cmdSfdp->addrWidth, slaveSelect, CY_SMIF_TX_NOT_LAST_BYTE,
426 context);
427
428 if(CY_SMIF_SUCCESS == result)
429 {
430 result = Cy_SMIF_SendDummyCycles(base, cmdSfdp->dummyCycles);
431
432 if(CY_SMIF_SUCCESS == result)
433 {
434 result = Cy_SMIF_ReceiveDataBlocking(base,
435 sfdpBuffer,
436 size,
437 cmdSfdp->dataWidth,
438 context);
439 }
440 }
441 #else
442 bool is2byte_command = ((cmdSfdp->cmdWidth == CY_SMIF_WIDTH_OCTAL) && (cmdSfdp->cmdRate == CY_SMIF_DDR));
443 uint8_t sfdpAddr_4byte[4];
444
445 sfdpAddr_4byte[0] = 0U;
446
447 for (int i = 0; i<3; i++)
448 {
449 sfdpAddr_4byte[i+1] = sfdpAddress[i];
450 }
451
452 result = Cy_SMIF_TransmitCommand_Ext(base,
453 (uint16_t)(cmdSfdp->command | (uint16_t)(cmdSfdp->commandH << 8U)),
454 is2byte_command, cmdSfdp->cmdWidth, cmdSfdp->cmdRate,
455 is2byte_command? sfdpAddr_4byte : sfdpAddress,
456 is2byte_command? CY_SMIF_SFDP_ADDRESS_LENGTH + 1U: CY_SMIF_SFDP_ADDRESS_LENGTH,
457 cmdSfdp->addrWidth, cmdSfdp->addrRate, slaveSelect,
458 CY_SMIF_TX_NOT_LAST_BYTE, context);
459
460 if(CY_SMIF_SUCCESS == result)
461 {
462 result = Cy_SMIF_SendDummyCycles_Ext(base, cmdSfdp->addrWidth, cmdSfdp->addrRate, cmdSfdp->dummyCycles);
463
464 if(CY_SMIF_SUCCESS == result)
465 {
466 result = Cy_SMIF_ReceiveDataBlocking_Ext(base, sfdpBuffer, size,
467 cmdSfdp->dataWidth, cmdSfdp->dataRate,
468 context);
469 }
470 }
471
472 #endif
473 return(result);
474 }
475
476
477 /*******************************************************************************
478 * Function Name: SfdpFindParameterHeader
479 ****************************************************************************//**
480 *
481 * Finds the Parameter Header offset from the JEDEC basic flash parameter table.
482 *
483 * \param id
484 * The parameter ID.
485 *
486 * \param sfdpBuffer
487 * The pointer to an array with the SDFP buffer.
488 *
489 * \return The relative parameter header offset in bytes.
490 * Returns 0 when the parameter header is not found.
491 *
492 *******************************************************************************/
SfdpFindParameterHeader(uint32_t id,uint8_t const sfdpBuffer[])493 static uint32_t SfdpFindParameterHeader(uint32_t id, uint8_t const sfdpBuffer[])
494 {
495 uint32_t headerOffset = PARAMETER_IS_NOT_FOUND;
496 uint32_t maxMinorRevison = 0UL;
497 uint32_t sfdpAddress = FIRST_HEADER_OFFSET; /* Begin from 1st Parameter Header */
498
499 while (sfdpAddress <= (((uint32_t)sfdpBuffer[PARAM_HEADERS_NUM] *
500 HEADER_LENGTH) +
501 FIRST_HEADER_OFFSET))
502 {
503 /* Check parameter ID */
504 if (((id & PARAM_ID_LSB_MASK) == sfdpBuffer[sfdpAddress]) && /* Parameter ID LSB */
505 (((id >> PARAM_ID_MSB_OFFSET) & PARAM_ID_LSB_MASK) ==
506 sfdpBuffer[sfdpAddress + /* Parameter ID MSB */
507 PARAM_ID_MSB_REL_OFFSET]))
508 {
509 /* Check parameter major and minor revisions */
510 if ((sfdpBuffer[sfdpAddress + PARAM_MINOR_REV_REL_OFFSET] >= maxMinorRevison) &&
511 (sfdpBuffer[sfdpAddress + PARAM_MAJOR_REV_REL_OFFSET] == CY_SMIF_SFDP_MAJOR_REV_1))
512 {
513 /* Get the maximum minor revision */
514 maxMinorRevison = sfdpBuffer[sfdpAddress + PARAM_MINOR_REV_REL_OFFSET];
515
516 /* Save the the Parameter Header offset with the maximum minor revision */
517 headerOffset = sfdpAddress;
518 }
519 }
520
521 sfdpAddress += HEADER_LENGTH;
522 }
523
524 return(headerOffset);
525 }
526
527
528 /*******************************************************************************
529 * Function Name: SfdpFindParameterTableAddress
530 ****************************************************************************//**
531 *
532 * Reads the address and length of the Parameter Table from
533 * the JEDEC basic flash parameter table. If not found, tableLength set to 0.
534 *
535 * \param id
536 * The parameter ID.
537 *
538 * \param sfdpBuffer
539 * The pointer to an array with the SDFP buffer.
540 *
541 * \param address
542 * The Parameter Table address.
543 *
544 * \param *tableLength
545 * The Parameter Table length.
546 *
547 *******************************************************************************/
SfdpFindParameterTableAddress(uint32_t id,uint8_t const sfdpBuffer[],uint8_t address[],uint8_t * tableLength)548 static void SfdpFindParameterTableAddress(uint32_t id,
549 uint8_t const sfdpBuffer[],
550 uint8_t address[],
551 uint8_t *tableLength)
552 {
553 uint32_t headerOffset;
554
555 headerOffset = SfdpFindParameterHeader(id, sfdpBuffer);
556
557 if (PARAMETER_IS_NOT_FOUND != headerOffset)
558 {
559 /* The Parameter Table address */
560 address[2] = sfdpBuffer[headerOffset +
561 PARAM_TABLE_PRT_OFFSET];
562 address[1] = sfdpBuffer[headerOffset +
563 PARAM_TABLE_PRT_OFFSET + 1UL];
564 address[0] = sfdpBuffer[headerOffset +
565 PARAM_TABLE_PRT_OFFSET + 2UL];
566
567 /* The Parameter Table length */
568 *tableLength = (uint8_t)sfdpBuffer[headerOffset + PARAM_TABLE_LENGTH_OFFSET] *
569 BYTES_IN_DWORD;
570 }
571 else
572 {
573 *tableLength = 0U;
574 }
575 }
576
577
578 /*******************************************************************************
579 * Function Name: SfdpGetNumOfAddrBytes
580 ****************************************************************************//**
581 *
582 * Reads the number of address bytes from the JEDEC basic flash parameter table.
583 *
584 * \note 4-byte addressing mode is set when the memory device supports
585 * 3- or 4-byte addressing mode and memory density is greater than 16 MB.
586 * Otherwise, use 3-byte addresing mode.
587 *
588 * \param sfdpBuffer
589 * The pointer to an array with the SDFP buffer.
590 *
591 * \param memorySize
592 * size of the memory device in bytes.
593 *
594 * \return The number of address bytes used by the memory slave device.
595 *
596 *******************************************************************************/
SfdpGetNumOfAddrBytes(uint8_t const sfdpBuffer[],uint32_t memorySize)597 static uint32_t SfdpGetNumOfAddrBytes(uint8_t const sfdpBuffer[], uint32_t memorySize)
598 {
599 uint32_t addrBytesNum = 0UL;
600 uint32_t sfdpAddrCode = _FLD2VAL(CY_SMIF_SFDP_ADDRESS_BYTES,
601 (uint32_t)sfdpBuffer
602 [CY_SMIF_SFDP_BFPT_BYTE_02]);
603 switch(sfdpAddrCode)
604 {
605 case CY_SMIF_SFDP_THREE_BYTES_ADDR_CODE:
606 addrBytesNum = CY_SMIF_THREE_BYTES_ADDR;
607 break;
608 case CY_SMIF_SFDP_THREE_OR_FOUR_BYTES_ADDR_CODE:
609 if (memorySize > MEMORY_SIZE_16MB)
610 {
611 addrBytesNum = CY_SMIF_FOUR_BYTES_ADDR;
612 }
613 else
614 {
615 addrBytesNum = CY_SMIF_THREE_BYTES_ADDR;
616 }
617 break;
618 case CY_SMIF_SFDP_FOUR_BYTES_ADDR_CODE:
619 addrBytesNum = CY_SMIF_FOUR_BYTES_ADDR;
620 break;
621 default:
622 /* Invalid Address code */
623 break;
624 }
625
626 return(addrBytesNum);
627 }
628
629
630 /*******************************************************************************
631 * Function Name: SfdpGetMemoryDensity
632 ****************************************************************************//**
633 *
634 * Reads the Memory Density from the JEDEC basic flash parameter table.
635 *
636 * \param sfdpBuffer
637 * The pointer to an array with the SDFP buffer.
638 *
639 * \return The external memory size:
640 * For densities of 2 gigabits or less - the size in bytes;
641 * For densities 4 gigabits and above - bit-31 is set to 1b to define that
642 * this memory is 4 gigabits and above; and other 30:0 bits define N where
643 * the density is computed as 2^N bytes.
644 * For example, 0x80000021 corresponds to 2^30 = 1 gigabyte.
645 *
646 *******************************************************************************/
SfdpGetMemoryDensity(uint8_t const sfdpBuffer[])647 static uint32_t SfdpGetMemoryDensity(uint8_t const sfdpBuffer[])
648 {
649 uint32_t memorySize;
650 uint32_t locSize = Cy_SMIF_PackBytesArray(&sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_04], true);
651
652 if (0UL == (locSize & CY_SMIF_SFDP_SIZE_ABOVE_4GB_Msk))
653 {
654 memorySize = (locSize + 1UL)/BITS_IN_BYTE;
655 }
656 else
657 {
658 memorySize = (locSize - BITS_IN_BYTE_ABOVE_4GB) |
659 CY_SMIF_SFDP_SIZE_ABOVE_4GB_Msk;
660 }
661
662 return(memorySize);
663 }
664
665 #if (CY_IP_MXSMIF_VERSION>=2) && defined (SMIF_OCTAL_SFDP_SUPPORT)
666 /*******************************************************************************
667 * Function Name: SfdpGetReadCmd_1_8_8
668 ****************************************************************************//**
669 *
670 * Reads the FAST_READ_1_8_8 read command parameters from the JEDEC basic flash
671 * parameter table.
672 *
673 * \param sfdpBuffer
674 * The pointer to an array with the SDFP buffer.
675 *
676 * \param cmdRead
677 * The pointer to the read command parameters structure.
678 *
679 *******************************************************************************/
SfdpGetReadCmd_1_8_8(uint8_t const sfdpBuffer[],cy_stc_smif_mem_cmd_t * cmdRead)680 static void SfdpGetReadCmd_1_8_8(uint8_t const sfdpBuffer[],
681 cy_stc_smif_mem_cmd_t* cmdRead)
682 {
683 /* 8-bit command. 8 x I/O Read command */
684 cmdRead->command = sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_41];
685
686 /* command presence - 1 byte transfer */
687 cmdRead->cmdPresence = CY_SMIF_PRESENT_1BYTE;
688
689 /* The command transfer width */
690 cmdRead->cmdWidth = CY_SMIF_WIDTH_SINGLE;
691
692 /* The address transfer width */
693 cmdRead->addrWidth = CY_SMIF_WIDTH_OCTAL;
694
695 /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
696 if (0U == (_FLD2VAL(CY_SMIF_SFDP_1_8_8_MODE_CYCLES,
697 (uint32_t) sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_40])))
698 {
699 cmdRead->mode = CY_SMIF_NO_COMMAND_OR_MODE;
700 }
701 else
702 {
703 cmdRead->mode = READ_ENHANCED_MODE_DISABLED;
704 cmdRead->modeWidth = CY_SMIF_WIDTH_OCTAL;
705 cmdRead->modePresence = CY_SMIF_PRESENT_1BYTE;
706 }
707
708 /* The dummy cycles number. A zero value suggests no dummy cycles */
709 cmdRead->dummyCycles = _FLD2VAL(CY_SMIF_SFDP_1_8_8_DUMMY_CYCLES,
710 (uint32_t) sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_40]);
711
712 /* dummy cycles present - 1 byte transfer */
713 if(cmdRead->dummyCycles > 0U)
714 {
715 cmdRead->dummyCyclesPresence = CY_SMIF_PRESENT_1BYTE;
716 }
717
718 /* The data transfer width */
719 cmdRead->dataWidth = CY_SMIF_WIDTH_OCTAL;
720 }
721
722 /*******************************************************************************
723 * Function Name: SfdpGetReadCmd_1_1_8
724 ****************************************************************************//**
725 *
726 * Reads the FAST_READ_1_1_8 read command parameters from the JEDEC basic flash
727 * parameter table.
728 *
729 * \param sfdpBuffer
730 * The pointer to an array with the SDFP buffer.
731 *
732 * \param cmdRead
733 * The pointer to the read command parameters structure.
734 *
735 *******************************************************************************/
SfdpGetReadCmd_1_1_8(uint8_t const sfdpBuffer[],cy_stc_smif_mem_cmd_t * cmdRead)736 static void SfdpGetReadCmd_1_1_8(uint8_t const sfdpBuffer[],
737 cy_stc_smif_mem_cmd_t* cmdRead)
738 {
739 /* 8-bit command. 8 x I/O Read command */
740 cmdRead->command = sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_43];
741
742 /* command presence - 1 byte transfer */
743 cmdRead->cmdPresence = CY_SMIF_PRESENT_1BYTE;
744
745 /* The command transfer width */
746 cmdRead->cmdWidth = CY_SMIF_WIDTH_SINGLE;
747
748 /* The address transfer width */
749 cmdRead->addrWidth = CY_SMIF_WIDTH_OCTAL;
750
751 /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
752 if (0U == (_FLD2VAL(CY_SMIF_SFDP_1_1_8_MODE_CYCLES,
753 (uint32_t) sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_42])))
754 {
755 cmdRead->mode = CY_SMIF_NO_COMMAND_OR_MODE;
756 }
757 else
758 {
759 cmdRead->mode = READ_ENHANCED_MODE_DISABLED;
760 cmdRead->modeWidth = CY_SMIF_WIDTH_OCTAL;
761 cmdRead->modePresence = CY_SMIF_PRESENT_1BYTE;
762 }
763
764 /* The dummy cycles number. A zero value suggests no dummy cycles */
765 cmdRead->dummyCycles = _FLD2VAL(CY_SMIF_SFDP_1_1_8_DUMMY_CYCLES,
766 (uint32_t)sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_42]);
767
768 /* dummy cycles present - 1 byte transfer */
769 if(cmdRead->dummyCycles > 0U)
770 {
771 cmdRead->dummyCyclesPresence = CY_SMIF_PRESENT_1BYTE;
772 }
773
774 /* The data transfer width */
775 cmdRead->dataWidth = CY_SMIF_WIDTH_OCTAL;
776 }
777 #endif
778 /* IP version 5 DDR support will be enabled for actual silicon */
779 #if ((CY_IP_MXSMIF_VERSION>=2) && (CY_IP_MXSMIF_VERSION !=5))
780 /*******************************************************************************
781 * Function Name: SfdpGetReadCmd_1S_4D_4D
782 ****************************************************************************//**
783 *
784 * Reads the FAST_READ_1S_4D_4D read command parameters from the JEDEC basic flash
785 * parameter table.
786 *
787 * \param sfdpBuffer
788 * The pointer to an array with the SDFP buffer.
789 *
790 * \param cmdRead
791 * The pointer to the read command parameters structure.
792 *
793 * \note
794 * This API is available for CAT1B, CAT1C and CAT1D devices.
795 *
796 *******************************************************************************/
SfdpGetReadCmd_1S_4D_4D(uint8_t const sfdpBuffer[],cy_stc_smif_mem_cmd_t * cmdRead)797 static void SfdpGetReadCmd_1S_4D_4D(uint8_t const sfdpBuffer[],
798 cy_stc_smif_mem_cmd_t* cmdRead)
799 {
800 /* 8-bit command. 4 x I/O Read command */
801 cmdRead->command = CY_SMIF_FAST_READ_4_BYTES_CMD_1S_4D_4D;
802
803 /* command transfer rate */
804 cmdRead->cmdRate = CY_SMIF_SDR;
805
806 /* command presence - 1 byte transfer */
807 cmdRead->cmdPresence = CY_SMIF_PRESENT_1BYTE;
808
809 /* The command transfer width */
810 cmdRead->cmdWidth = CY_SMIF_WIDTH_SINGLE;
811
812 /* The address transfer width */
813 cmdRead->addrWidth = CY_SMIF_WIDTH_QUAD;
814 cmdRead->addrRate = CY_SMIF_DDR;
815
816 /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
817 if (0U == (_FLD2VAL(CY_SMIF_SFDP_1_4_4_MODE_CYCLES,
818 (uint32_t) sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_08])))
819 {
820 cmdRead->mode = CY_SMIF_NO_COMMAND_OR_MODE;
821 }
822 else
823 {
824 cmdRead->mode = READ_ENHANCED_MODE_DISABLED;
825 cmdRead->modeWidth = CY_SMIF_WIDTH_QUAD;
826 cmdRead->modeRate = CY_SMIF_DDR;
827 cmdRead->modePresence = CY_SMIF_PRESENT_1BYTE;
828 }
829
830 /* The dummy cycles number. A zero value suggests no dummy cycles */
831 cmdRead->dummyCycles = _FLD2VAL(CY_SMIF_SFDP_1_4_4_DUMMY_CYCLES,
832 (uint32_t) sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_08]);
833
834 /* dummy cycles present - 1 byte transfer */
835 cmdRead->dummyCyclesPresence = CY_SMIF_PRESENT_1BYTE;
836
837 /* The data transfer width */
838 cmdRead->dataWidth = CY_SMIF_WIDTH_QUAD;
839
840 /* The data rate - DDR */
841 cmdRead->dataRate = CY_SMIF_DDR;
842
843
844 }
845 #endif /* CY_IP_MXSMIF_VERSION */
846
847 /*******************************************************************************
848 * Function Name: SfdpGetReadCmd_1_4_4
849 ****************************************************************************//**
850 *
851 * Reads the FAST_READ_1_4_4 read command parameters from the JEDEC basic flash
852 * parameter table.
853 *
854 * \param sfdpBuffer
855 * The pointer to an array with the SDFP buffer.
856 *
857 * \param cmdRead
858 * The pointer to the read command parameters structure.
859 *
860 *******************************************************************************/
SfdpGetReadCmd_1_4_4(uint8_t const sfdpBuffer[],cy_stc_smif_mem_cmd_t * cmdRead)861 static void SfdpGetReadCmd_1_4_4(uint8_t const sfdpBuffer[],
862 cy_stc_smif_mem_cmd_t* cmdRead)
863 {
864 /* 8-bit command. 4 x I/O Read command */
865 cmdRead->command = sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_09];
866
867 #if (CY_IP_MXSMIF_VERSION>=2)
868 /* command presence - 1 byte transfer */
869 cmdRead->cmdPresence = CY_SMIF_PRESENT_1BYTE;
870 #endif /* CY_IP_MXSMIF_VERSION */
871
872 /* The command transfer width */
873 cmdRead->cmdWidth = CY_SMIF_WIDTH_SINGLE;
874
875 /* The address transfer width */
876 cmdRead->addrWidth = CY_SMIF_WIDTH_QUAD;
877
878 /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
879 if (0U == (_FLD2VAL(CY_SMIF_SFDP_1_4_4_MODE_CYCLES,
880 (uint32_t) sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_08])))
881 {
882 cmdRead->mode = CY_SMIF_NO_COMMAND_OR_MODE;
883 }
884 else
885 {
886 cmdRead->mode = READ_ENHANCED_MODE_DISABLED;
887 cmdRead->modeWidth = CY_SMIF_WIDTH_QUAD;
888 #if (CY_IP_MXSMIF_VERSION>=2)
889 cmdRead->modePresence = CY_SMIF_PRESENT_1BYTE;
890 #endif /* CY_IP_MXSMIF_VERSION */
891 }
892
893 /* The dummy cycles number. A zero value suggests no dummy cycles */
894 cmdRead->dummyCycles = _FLD2VAL(CY_SMIF_SFDP_1_4_4_DUMMY_CYCLES,
895 (uint32_t) sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_08]);
896
897 #if (CY_IP_MXSMIF_VERSION>=2)
898 /* dummy cycles present - 1 byte transfer */
899 if(cmdRead->dummyCycles > 0UL)
900 {
901 cmdRead->dummyCyclesPresence = CY_SMIF_PRESENT_1BYTE;
902 }
903 #endif /* CY_IP_MXSMIF_VERSION */
904
905 /* The data transfer width */
906 cmdRead->dataWidth = CY_SMIF_WIDTH_QUAD;
907 }
908
909
910 /*******************************************************************************
911 * Function Name: SfdpGetReadCmd_1_1_4
912 ****************************************************************************//**
913 *
914 * Reads the FAST_READ_1_1_4 read command parameters from the JEDEC basic flash
915 * parameter table.
916 *
917 * \param sfdpBuffer
918 * The pointer to an array with the SDFP buffer.
919 *
920 * \param cmdRead
921 * The pointer to the read command parameters structure.
922 *
923 *******************************************************************************/
SfdpGetReadCmd_1_1_4(uint8_t const sfdpBuffer[],cy_stc_smif_mem_cmd_t * cmdRead)924 static void SfdpGetReadCmd_1_1_4(uint8_t const sfdpBuffer[],
925 cy_stc_smif_mem_cmd_t* cmdRead)
926 {
927 /* 8-bit command. 4 x I/O Read command */
928 cmdRead->command = sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_0B];
929
930 /* The command transfer width */
931 cmdRead->cmdWidth = CY_SMIF_WIDTH_SINGLE;
932
933 /* The address transfer width */
934 cmdRead->addrWidth = CY_SMIF_WIDTH_SINGLE;
935
936 /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
937 if ((0U == _FLD2VAL(CY_SMIF_SFDP_1_1_4_MODE_CYCLES, (uint32_t) sfdpBuffer
938 [CY_SMIF_SFDP_BFPT_BYTE_0A])))
939 {
940 cmdRead->mode = CY_SMIF_NO_COMMAND_OR_MODE;
941 }
942 else
943 {
944 cmdRead->mode = READ_ENHANCED_MODE_DISABLED;
945 cmdRead->modeWidth = CY_SMIF_WIDTH_SINGLE;
946 #if (CY_IP_MXSMIF_VERSION>=2)
947 cmdRead->modePresence = CY_SMIF_PRESENT_1BYTE;
948 #endif /* CY_IP_MXSMIF_VERSION */
949 }
950
951 /* The dummy cycles number. A zero value suggests no dummy cycles */
952 cmdRead->dummyCycles = _FLD2VAL(CY_SMIF_SFDP_1_1_4_DUMMY_CYCLES,
953 (uint32_t)sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_0A]);
954
955 #if (CY_IP_MXSMIF_VERSION>=2)
956 /* dummy cycles present - 1 byte transfer */
957 if(cmdRead->dummyCycles > 0UL)
958 {
959 cmdRead->dummyCyclesPresence = CY_SMIF_PRESENT_1BYTE;
960 }
961 #endif /* CY_IP_MXSMIF_VERSION */
962
963 /* The data transfer width */
964 cmdRead->dataWidth = CY_SMIF_WIDTH_QUAD;
965 }
966
967
968 /*******************************************************************************
969 * Function Name: SfdpGetReadCmd_1_2_2
970 ****************************************************************************//**
971 *
972 * Reads the FAST_READ_1_2_2 read command parameters from the JEDEC basic flash
973 * parameter table.
974 *
975 * \param sfdpBuffer
976 * The pointer to an array with the SDFP buffer.
977 *
978 * \param cmdRead
979 * The pointer to the read command parameters structure.
980 *
981 *******************************************************************************/
SfdpGetReadCmd_1_2_2(uint8_t const sfdpBuffer[],cy_stc_smif_mem_cmd_t * cmdRead)982 static void SfdpGetReadCmd_1_2_2(uint8_t const sfdpBuffer[],
983 cy_stc_smif_mem_cmd_t* cmdRead)
984 {
985 /* 8-bit command. 2 x I/O Read command */
986 cmdRead->command = sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_0F];
987
988 /* The command transfer width */
989 cmdRead->cmdWidth = CY_SMIF_WIDTH_SINGLE;
990
991 /* The address transfer width */
992 cmdRead->addrWidth = CY_SMIF_WIDTH_DUAL;
993
994 /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
995 if (0U == _FLD2VAL(CY_SMIF_SFDP_1_2_2_MODE_CYCLES, (uint32_t)
996 sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_0E]))
997 {
998 cmdRead->mode = CY_SMIF_NO_COMMAND_OR_MODE;
999 }
1000 else
1001 {
1002 cmdRead->mode = READ_ENHANCED_MODE_DISABLED;
1003 cmdRead->modeWidth = CY_SMIF_WIDTH_DUAL;
1004 #if (CY_IP_MXSMIF_VERSION>=2)
1005 cmdRead->modePresence = CY_SMIF_PRESENT_1BYTE;
1006 #endif /* CY_IP_MXSMIF_VERSION */
1007 }
1008
1009 /* The dummy cycles number. A zero value suggests no dummy cycles. */
1010 cmdRead->dummyCycles = _FLD2VAL(CY_SMIF_SFDP_1_2_2_DUMMY_CYCLES,
1011 (uint32_t) sfdpBuffer [CY_SMIF_SFDP_BFPT_BYTE_0E]);
1012
1013 #if (CY_IP_MXSMIF_VERSION>=2)
1014 /* dummy cycles present - 1 byte transfer */
1015 if(cmdRead->dummyCycles > 0UL)
1016 {
1017 cmdRead->dummyCyclesPresence = CY_SMIF_PRESENT_1BYTE;
1018 }
1019 #endif /* CY_IP_MXSMIF_VERSION */
1020
1021 /* The data transfer width */
1022 cmdRead->dataWidth = CY_SMIF_WIDTH_DUAL;
1023 }
1024
1025
1026 /*******************************************************************************
1027 * Function Name: SfdpGetReadCmd_1_1_2
1028 ****************************************************************************//**
1029 *
1030 * Reads the FAST_READ_1_1_2 read command parameters from the JEDEC basic flash
1031 * parameter table.
1032 *
1033 * \param sfdpBuffer
1034 * The pointer to an array with the SDFP buffer.
1035 *
1036 * \param cmdRead
1037 * The pointer to the read command parameters structure.
1038 *
1039 *******************************************************************************/
SfdpGetReadCmd_1_1_2(uint8_t const sfdpBuffer[],cy_stc_smif_mem_cmd_t * cmdRead)1040 static void SfdpGetReadCmd_1_1_2(uint8_t const sfdpBuffer[],
1041 cy_stc_smif_mem_cmd_t* cmdRead)
1042 {
1043 /* 8-bit command. 2 x I/O Read command */
1044 cmdRead->command = sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_0D];
1045
1046 /* The command transfer width */
1047 cmdRead->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1048
1049 /* The address transfer width */
1050 cmdRead->addrWidth = CY_SMIF_WIDTH_SINGLE;
1051
1052 /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
1053 if (0U == (_FLD2VAL(CY_SMIF_SFDP_1_1_2_MODE_CYCLES, (uint32_t)
1054 sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_0C])))
1055 {
1056 cmdRead->mode = CY_SMIF_NO_COMMAND_OR_MODE;
1057 }
1058 else
1059 {
1060 cmdRead->mode = READ_ENHANCED_MODE_DISABLED;
1061 cmdRead->modeWidth = CY_SMIF_WIDTH_SINGLE;
1062 #if (CY_IP_MXSMIF_VERSION>=2)
1063 cmdRead->modePresence = CY_SMIF_PRESENT_1BYTE;
1064 #endif /* CY_IP_MXSMIF_VERSION */
1065 }
1066
1067 /* The dummy cycles number. A zero value suggests no dummy cycles. */
1068 cmdRead->dummyCycles = _FLD2VAL(CY_SMIF_SFDP_1_1_2_DUMMY_CYCLES,
1069 (uint32_t)sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_0C]);
1070
1071 #if (CY_IP_MXSMIF_VERSION>=2)
1072 /* dummy cycles present - 1 byte transfer */
1073 if(cmdRead->dummyCycles > 0UL)
1074 {
1075 cmdRead->dummyCyclesPresence = CY_SMIF_PRESENT_1BYTE;
1076 }
1077 #endif /* CY_IP_MXSMIF_VERSION */
1078
1079 /* The data transfer width */
1080 cmdRead->dataWidth = CY_SMIF_WIDTH_DUAL;
1081 }
1082
1083
1084 /*******************************************************************************
1085 * Function Name: SfdpGetReadCmd_1_1_1
1086 ****************************************************************************//**
1087 *
1088 * Reads the FAST_READ_1_1_1 read command parameters from the JEDEC basic flash
1089 * parameter table.
1090 *
1091 * \param sfdpBuffer
1092 * The pointer to an array with the SDFP buffer.
1093 *
1094 * \param cmdRead
1095 * The pointer to the read command parameters structure.
1096 *
1097 *******************************************************************************/
SfdpGetReadCmd_1_1_1(uint8_t const sfdpBuffer[],cy_stc_smif_mem_cmd_t * cmdRead)1098 static void SfdpGetReadCmd_1_1_1(uint8_t const sfdpBuffer[],
1099 cy_stc_smif_mem_cmd_t* cmdRead)
1100 {
1101 (void)sfdpBuffer; /* Suppress warning */
1102
1103 /* 8-bit command. 1 x I/O Read command */
1104 cmdRead->command = CY_SMIF_SINGLE_READ_CMD;
1105
1106 /* The command transfer width */
1107 cmdRead->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1108 #if (CY_IP_MXSMIF_VERSION>=2)
1109 /* command presence - 1 byte transfer */
1110 cmdRead->cmdPresence = CY_SMIF_PRESENT_1BYTE;
1111 #endif /* CY_IP_MXSMIF_VERSION */
1112
1113 /* The address transfer width */
1114 cmdRead->addrWidth = CY_SMIF_WIDTH_SINGLE;
1115
1116 /* The 8 bit-mode byte. This value is 0xFFFFFFFF when there is no mode present */
1117 cmdRead->mode = CY_SMIF_NO_COMMAND_OR_MODE;
1118
1119 /* The dummy cycles number. A zero value suggests no dummy cycles. */
1120 cmdRead->dummyCycles = 0UL;
1121
1122 /* The data transfer width */
1123 cmdRead->dataWidth = CY_SMIF_WIDTH_SINGLE;
1124 }
1125
1126
1127 /*******************************************************************************
1128 * Function Name: zz
1129 ****************************************************************************//**
1130 *
1131 * Reads the read command parameters from the JEDEC basic flash parameter table.
1132 *
1133 * \param sfdpBuffer
1134 * The pointer to an array with the SDFP buffer.
1135 *
1136 * \param dataSelect
1137 * The data line selection options for a slave device.
1138 *
1139 * \param maxDataWidth
1140 * Maximum data width available on the physical interface.
1141 *
1142 * \param cmdRead
1143 * The pointer to the read command parameters structure.
1144 *
1145 * \return Protocol Mode.
1146 *
1147 *******************************************************************************/
SfdpGetReadCmdParams(uint8_t const sfdpBuffer[],cy_en_smif_data_select_t dataSelect,cy_en_smif_txfr_width_t maxDataWidth,cy_stc_smif_mem_cmd_t * cmdRead)1148 static cy_en_smif_protocol_mode_t SfdpGetReadCmdParams(uint8_t const sfdpBuffer[],
1149 cy_en_smif_data_select_t dataSelect,
1150 cy_en_smif_txfr_width_t maxDataWidth,
1151 cy_stc_smif_mem_cmd_t* cmdRead)
1152 {
1153 cy_en_smif_protocol_mode_t protocolMode = PROTOCOL_MODE_WRONG;
1154 uint32_t sfdpDataIndex = CY_SMIF_SFDP_BFPT_BYTE_02;
1155 bool quadEnabled = ((CY_SMIF_DATA_SEL1 != dataSelect) &&
1156 (CY_SMIF_DATA_SEL3 != dataSelect) &&
1157 (maxDataWidth >= CY_SMIF_WIDTH_QUAD));
1158
1159 if (quadEnabled)
1160 {
1161 if (_FLD2BOOL(CY_SMIF_SFDP_FAST_READ_1_4_4,
1162 ((uint32_t) sfdpBuffer[sfdpDataIndex])))
1163 {
1164 /* IP version 5 DDR support will be enabled for actual silicon */
1165 #if ((CY_IP_MXSMIF_VERSION>=2) && (CY_IP_MXSMIF_VERSION !=5))
1166 if(_FLD2BOOL(CY_SMIF_SFDP_DTR_SUPPORT, (uint32_t) sfdpBuffer[sfdpDataIndex]))
1167 {
1168 SfdpGetReadCmd_1S_4D_4D(sfdpBuffer, cmdRead);
1169 protocolMode = PROTOCOL_MODE_1S_4D_4D;
1170 }
1171 else
1172 {
1173 SfdpGetReadCmd_1_4_4(sfdpBuffer, cmdRead);
1174 protocolMode = PROTOCOL_MODE_1S_4S_4S;
1175 }
1176 #else
1177 SfdpGetReadCmd_1_4_4(sfdpBuffer, cmdRead);
1178 protocolMode = PROTOCOL_MODE_1S_4S_4S;
1179 #endif /* CY_IP_MXSMIF_VERSION */
1180 }
1181 else if (_FLD2BOOL(CY_SMIF_SFDP_FAST_READ_1_1_4,
1182 ((uint32_t)sfdpBuffer[sfdpDataIndex])))
1183 {
1184 SfdpGetReadCmd_1_1_4(sfdpBuffer, cmdRead);
1185 protocolMode = PROTOCOL_MODE_1S_1S_4S;
1186 }
1187 else
1188 {
1189 /* Wrong mode */
1190 CY_ASSERT_L2(true);
1191 protocolMode = PROTOCOL_MODE_WRONG;
1192 }
1193 }
1194 else
1195 {
1196 if ((_FLD2BOOL(CY_SMIF_SFDP_FAST_READ_1_2_2,
1197 (uint32_t)sfdpBuffer[sfdpDataIndex])) &&
1198 (maxDataWidth >= CY_SMIF_WIDTH_DUAL))
1199 {
1200 SfdpGetReadCmd_1_2_2(sfdpBuffer, cmdRead);
1201 protocolMode = PROTOCOL_MODE_1S_2S_2S;
1202 }
1203 else
1204 {
1205 if (_FLD2BOOL(CY_SMIF_SFDP_FAST_READ_1_1_2,
1206 (uint32_t)sfdpBuffer[sfdpDataIndex]) &&
1207 (maxDataWidth >= CY_SMIF_WIDTH_DUAL))
1208 {
1209 SfdpGetReadCmd_1_1_2(sfdpBuffer, cmdRead);
1210 protocolMode = PROTOCOL_MODE_1S_1S_2S;
1211 }
1212 else
1213 {
1214 SfdpGetReadCmd_1_1_1(sfdpBuffer, cmdRead);
1215 protocolMode = PROTOCOL_MODE_1S_1S_1S;
1216 }
1217 }
1218 }
1219
1220 return protocolMode;
1221 }
1222 #if (CY_IP_MXSMIF_VERSION>=2) && defined (SMIF_OCTAL_SFDP_SUPPORT)
SfdpSetVariableLatencyCmd(SMIF_Type * base,cy_stc_smif_mem_device_cfg_t * device,cy_en_smif_slave_select_t slaveSelect,uint8_t * sccrMapAddr,cy_stc_smif_context_t * context)1223 static void SfdpSetVariableLatencyCmd(SMIF_Type *base,
1224 cy_stc_smif_mem_device_cfg_t *device,
1225 cy_en_smif_slave_select_t slaveSelect,
1226 uint8_t *sccrMapAddr,
1227 cy_stc_smif_context_t *context)
1228 {
1229 cy_en_smif_status_t result = CY_SMIF_CMD_NOT_FOUND;
1230 cy_stc_smif_mem_cmd_t *cmdReadLatency = device->readLatencyCmd;
1231 cy_stc_smif_mem_cmd_t *cmdWriteLatency = device->writeLatencyCmd;
1232 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.8', 1, 'uint8_t to uin32_t type conversion intentional.')
1233
1234 if ((sccrMapAddr != NULL) && (cmdReadLatency != NULL) && (cmdWriteLatency != NULL))
1235 {
1236 /* SCCR Map 9th DWORD Variable Dummy Cycle Settings */
1237
1238 uint8_t sccrMapDWord9Value[4];
1239 uint8_t sccrMapDW9_Address[4];
1240
1241 /* Initialize DWords */
1242 for (uint32_t i = 0U; i < 4U; i++)
1243 {
1244 sccrMapDWord9Value[i] = 0U;
1245 sccrMapDW9_Address[i] = 0U;
1246 }
1247
1248 ValueToByteArray(ByteArrayToValue(sccrMapAddr, CY_SMIF_SFDP_ADDRESS_LENGTH) + 32U, sccrMapDW9_Address, 0U, CY_SMIF_SFDP_ADDRESS_LENGTH);
1249
1250 /* Get the JEDEC SCCR Map Table content into sfdpBuffer[] */
1251 result = SfdpReadBuffer(base, device->readSfdpCmd, sccrMapDW9_Address, slaveSelect,
1252 4U, sccrMapDWord9Value, context);
1253
1254 /* Check if variable latency is supported */
1255 if ((result == CY_SMIF_SUCCESS) && ((sccrMapDWord9Value[3] & 0x80U) == 0x80U))
1256 {
1257 uint32_t latencyMaskoffset = (uint32_t) (sccrMapDWord9Value[3] & 0x7U);
1258 uint8_t latencyBits = (uint8_t) (((sccrMapDWord9Value[3] >> 5U) & 0x3U));
1259
1260 cmdReadLatency->command = sccrMapDWord9Value[1];
1261 cmdWriteLatency->command = sccrMapDWord9Value[0];
1262
1263 if ((sccrMapDWord9Value[3] & 0x8U) == 0x0U)
1264 {
1265 device->latencyCyclesRegAddr = sccrMapDWord9Value[2];
1266 }
1267 else
1268 {
1269 device->latencyCyclesRegAddr = CY_SMIF_NO_COMMAND_OR_MODE;
1270 }
1271
1272 device->latencyCyclesMask = (uint32_t)((~(0xFFU << (latencyBits + 2U))) << latencyMaskoffset);
1273
1274 }
1275 else
1276 {
1277 /* Variable Latency not supported */
1278 cmdReadLatency->command = CY_SMIF_NO_COMMAND_OR_MODE;
1279 cmdWriteLatency->command = CY_SMIF_NO_COMMAND_OR_MODE;
1280 }
1281 }
1282 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 10.8')
1283 }
1284 #endif
1285 /*******************************************************************************
1286 * Function Name: SfdpGetReadFourBytesCmd
1287 ****************************************************************************//**
1288 *
1289 * Reads the read command instruction from the 4-byte Address Instruction Table.
1290 *
1291 * \param sfdpBuffer
1292 * The pointer to an array with the SDFP buffer with the 4-byte Address
1293 * Instruction Table.
1294 *
1295 * \param protocolMode
1296 * Protocol Mode.
1297 *
1298 * \param cmdRead
1299 * The pointer to the read command parameters structure.
1300 *
1301 *******************************************************************************/
SfdpGetReadFourBytesCmd(uint8_t const sfdpBuffer[],cy_en_smif_protocol_mode_t protocolMode,cy_stc_smif_mem_cmd_t * cmdRead)1302 static void SfdpGetReadFourBytesCmd(uint8_t const sfdpBuffer[],
1303 cy_en_smif_protocol_mode_t protocolMode,
1304 cy_stc_smif_mem_cmd_t* cmdRead)
1305 {
1306 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 11.3', 7, \
1307 'Pointer type conversion is intentional.')
1308 /* Get the mask which contains the Support for Fast Read Commands
1309 * from 4-byte Address Instruction Table, DWORD 1
1310 */
1311 uint32_t sfdpForBytesTableDword1 = ((uint32_t*)sfdpBuffer)[FOUR_BYTE_ADDRESS_TABLE_BYTE_0];
1312
1313 switch (protocolMode)
1314 {
1315 case PROTOCOL_MODE_1S_4S_4S:
1316 if (_FLD2BOOL(SUPPORT_FAST_READ_1S_4S_4S_CMD, sfdpForBytesTableDword1))
1317 {
1318 cmdRead->command = CY_SMIF_FAST_READ_4_BYTES_CMD_1S_4S_4S;
1319 }
1320 break;
1321 case PROTOCOL_MODE_1S_1S_4S:
1322 if (_FLD2BOOL(SUPPORT_FAST_READ_1S_1S_4S_CMD, sfdpForBytesTableDword1))
1323 {
1324 cmdRead->command = CY_SMIF_FAST_READ_4_BYTES_CMD_1S_1S_4S;
1325 }
1326 break;
1327 case PROTOCOL_MODE_1S_2S_2S:
1328 if (_FLD2BOOL(SUPPORT_FAST_READ_1S_2S_2S_CMD, sfdpForBytesTableDword1))
1329 {
1330 cmdRead->command = CY_SMIF_FAST_READ_4_BYTES_CMD_1S_2S_2S;
1331 }
1332 break;
1333 case PROTOCOL_MODE_1S_1S_2S:
1334 if (_FLD2BOOL(SUPPORT_FAST_READ_1S_1S_2S_CMD, sfdpForBytesTableDword1))
1335 {
1336 cmdRead->command = CY_SMIF_FAST_READ_4_BYTES_CMD_1S_1S_2S;
1337 }
1338 break;
1339 case PROTOCOL_MODE_1S_1S_1S:
1340 if (_FLD2BOOL(SUPPORT_FAST_READ_1S_1S_1S_CMD, sfdpForBytesTableDword1))
1341 {
1342 cmdRead->command = CY_SMIF_FAST_READ_4_BYTES_CMD_1S_1S_1S;
1343 }
1344 break;
1345 default:
1346 /* There are no instructions for 4-byte mode. Use instruction for 3-byte mode */
1347 break;
1348 }
1349 }
1350
1351
1352 /*******************************************************************************
1353 * Function Name: SfdpGetPageSize
1354 ****************************************************************************//**
1355 *
1356 * Reads the page size from the JEDEC basic flash parameter table.
1357 *
1358 * \param sfdpBuffer
1359 * The pointer to an array with the SDFP buffer.
1360 *
1361 * \return The page size in bytes.
1362 *
1363 *******************************************************************************/
SfdpGetPageSize(uint8_t const sfdpBuffer[])1364 static uint32_t SfdpGetPageSize(uint8_t const sfdpBuffer[])
1365 {
1366 uint32_t size;
1367
1368 /* The page size */
1369 size = 0x01UL << _FLD2VAL(CY_SMIF_SFDP_PAGE_SIZE,
1370 (uint32_t) sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_28]);
1371
1372 return(size);
1373 }
1374
1375
1376 /*******************************************************************************
1377 * Function Name: SfdpGetEraseTime
1378 ****************************************************************************//**
1379 *
1380 * Calculates erase time.
1381 *
1382 * \param eraseOffset
1383 * The offset of the Sector Erase command in the SFDP buffer.
1384 *
1385 * \param sfdpBuffer
1386 * The pointer to an array with the SDFP buffer.
1387 *
1388 * \param eraseType
1389 * The pointer to an array with the erase time in us for different erase types.
1390 *
1391 * \return Default erase time in us.
1392 *
1393 *******************************************************************************/
SfdpGetEraseTime(uint32_t const eraseOffset,uint8_t const sfdpBuffer[],cy_stc_smif_erase_type_t eraseType[])1394 static uint32_t SfdpGetEraseTime(uint32_t const eraseOffset, uint8_t const sfdpBuffer[], cy_stc_smif_erase_type_t eraseType[])
1395 {
1396 /* Get the value of 10th DWORD from the JEDEC basic flash parameter table */
1397 uint32_t readEraseTime = ((uint32_t*)sfdpBuffer)[CY_SMIF_JEDEC_BFPT_10TH_DWORD];
1398
1399 uint32_t eraseTimeDefaultIndex = (((eraseOffset - CY_SMIF_SFDP_BFPT_BYTE_1D) + TYPE_STEP) / TYPE_STEP);
1400 uint32_t eraseMul = _FLD2VAL(CY_SMIF_SFDP_ERASE_MUL_COUNT, readEraseTime);
1401 uint32_t eraseUnits = 0UL;
1402 uint32_t eraseCount = 0UL;
1403 uint32_t eraseMs = 0UL;
1404 uint32_t eraseTypeTypicalTime;
1405
1406 for (uint32_t idx = 0UL; idx < ERASE_TYPE_COUNT; idx++)
1407 {
1408 eraseTypeTypicalTime = (readEraseTime >> (idx * ERASE_T_LENGTH))>> ERASE_T_COUNT_OFFSET;
1409 eraseUnits = _FLD2VAL(ERASE_T_UNITS, eraseTypeTypicalTime);
1410 eraseCount = _FLD2VAL(ERASE_T_COUNT, eraseTypeTypicalTime);
1411
1412 if (eraseUnits == CY_SMIF_SFDP_UNIT_0)
1413 {
1414 eraseMs = CY_SMIF_SFDP_ERASE_TIME_1MS;
1415 }
1416 else if (eraseUnits == CY_SMIF_SFDP_UNIT_1)
1417 {
1418 eraseMs = CY_SMIF_SFDP_ERASE_TIME_16MS;
1419 }
1420 else if (eraseUnits == CY_SMIF_SFDP_UNIT_2)
1421 {
1422 eraseMs = CY_SMIF_SFDP_ERASE_TIME_128MS;
1423 }
1424 else if (eraseUnits == CY_SMIF_SFDP_UNIT_3)
1425 {
1426 eraseMs = CY_SMIF_SFDP_ERASE_TIME_1S;
1427 }
1428 else
1429 {
1430 /* An unsupported SFDP value */
1431 }
1432
1433 /* Convert typical time to max time */
1434 eraseType[idx].eraseTime = ((eraseCount + 1UL) * eraseMs) * (2UL * (eraseMul + 1UL));
1435 }
1436
1437 return(eraseType[eraseTimeDefaultIndex - 1UL].eraseTime);
1438 }
1439
1440
1441 /*******************************************************************************
1442 * Function Name: SfdpGetChipEraseTime
1443 ****************************************************************************//**
1444 *
1445 * Calculates chip erase time.
1446 *
1447 * \param sfdpBuffer
1448 * The pointer to an array with the SDFP buffer.
1449 *
1450 * \return Chip erase time in us.
1451 *
1452 *******************************************************************************/
SfdpGetChipEraseTime(uint8_t const sfdpBuffer[])1453 static uint32_t SfdpGetChipEraseTime(uint8_t const sfdpBuffer[])
1454 {
1455 /* Get the value of 10th DWORD from the JEDEC basic flash parameter table */
1456 uint32_t readEraseTime = ((uint32_t*)sfdpBuffer)[CY_SMIF_JEDEC_BFPT_10TH_DWORD];
1457
1458 /* Get the value of 11th DWORD from the JEDEC basic flash parameter table */
1459 uint32_t chipEraseProgTime = ((uint32_t*)sfdpBuffer)[CY_SMIF_JEDEC_BFPT_11TH_DWORD];
1460
1461 uint32_t chipEraseTimeMax;
1462 uint32_t chipEraseUnits = _FLD2VAL(CY_SMIF_SFDP_CHIP_ERASE_UNITS, chipEraseProgTime);
1463 uint32_t chipEraseCount = _FLD2VAL(CY_SMIF_SFDP_CHIP_ERASE_COUNT, chipEraseProgTime);
1464 uint32_t chipEraseMs = 0UL;
1465 uint32_t eraseMul = _FLD2VAL(CY_SMIF_SFDP_ERASE_MUL_COUNT, readEraseTime);
1466
1467 if (chipEraseUnits == CY_SMIF_SFDP_UNIT_0)
1468 {
1469 chipEraseMs = CY_SMIF_SFDP_CHIP_ERASE_TIME_16MS;
1470 }
1471 else if (chipEraseUnits == CY_SMIF_SFDP_UNIT_1)
1472 {
1473 chipEraseMs = CY_SMIF_SFDP_CHIP_ERASE_TIME_256MS;
1474 }
1475 else if (chipEraseUnits == CY_SMIF_SFDP_UNIT_2)
1476 {
1477 chipEraseMs = CY_SMIF_SFDP_CHIP_ERASE_TIME_4S;
1478 }
1479 else if (chipEraseUnits == CY_SMIF_SFDP_UNIT_3)
1480 {
1481 chipEraseMs = CY_SMIF_SFDP_CHIP_ERASE_TIME_64S;
1482 }
1483 else
1484 {
1485 /* An unsupported SFDP value */
1486 }
1487
1488 /* Convert typical time to max time */
1489 chipEraseTimeMax = ((chipEraseCount + 1UL)*chipEraseMs) * (2UL *(eraseMul + 1UL));
1490
1491 return(chipEraseTimeMax);
1492 }
1493
1494
1495 /*******************************************************************************
1496 * Function Name: SfdpGetPageProgramTime
1497 ****************************************************************************//**
1498 *
1499 * Calculates page program time.
1500 *
1501 * \param sfdpBuffer
1502 * The pointer to an array with the SDFP buffer.
1503 *
1504 * \return Page program time in us.
1505 *
1506 *******************************************************************************/
SfdpGetPageProgramTime(uint8_t const sfdpBuffer[])1507 static uint32_t SfdpGetPageProgramTime(uint8_t const sfdpBuffer[])
1508 {
1509 /* Get the value of 11th DWORD from the JEDEC basic flash parameter table */
1510 uint32_t chipEraseProgTime = ((uint32_t*)sfdpBuffer)[CY_SMIF_JEDEC_BFPT_11TH_DWORD];
1511 uint32_t programTimeMax;
1512 uint32_t programTimeUnits = _FLD2VAL(CY_SMIF_SFDP_PAGE_PROG_UNITS, chipEraseProgTime);
1513 uint32_t programTimeCount = _FLD2VAL(CY_SMIF_SFDP_PAGE_PROG_COUNT, chipEraseProgTime);
1514 uint32_t progMul = _FLD2VAL(CY_SMIF_SFDP_PROG_MUL_COUNT, chipEraseProgTime);
1515 uint32_t progUs;
1516
1517 if (CY_SMIF_SFDP_UNIT_0 == programTimeUnits)
1518 {
1519 progUs = CY_SMIF_SFDP_PROG_TIME_8US;
1520 }
1521 else
1522 {
1523 progUs = CY_SMIF_SFDP_PROG_TIME_64US;
1524 }
1525
1526 /* Convert typical time to max time */
1527 programTimeMax = ((programTimeCount + 1UL) * progUs) * (2UL * (progMul + 1UL));
1528
1529 return(programTimeMax);
1530 }
1531
1532
1533 /*******************************************************************************
1534 * Function Name: SfdpSetWriteEnableCommand
1535 ****************************************************************************//**
1536 *
1537 * Sets the Write Enable command and the width of the command transfer.
1538 *
1539 * \param cmdWriteEnable
1540 * The pointer to the Write Enable command parameters structure.
1541 *
1542 *******************************************************************************/
SfdpSetWriteEnableCommand(cy_stc_smif_mem_cmd_t * cmdWriteEnable)1543 static void SfdpSetWriteEnableCommand(cy_stc_smif_mem_cmd_t* cmdWriteEnable)
1544 {
1545 /* 8-bit command. Write Enable */
1546 cmdWriteEnable->command = CY_SMIF_WRITE_ENABLE_CMD;
1547
1548 /* The width of the command transfer */
1549 cmdWriteEnable->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1550
1551 #if (CY_IP_MXSMIF_VERSION>=2)
1552 cmdWriteEnable->cmdPresence = CY_SMIF_PRESENT_1BYTE;
1553 #endif /* CY_IP_MXSMIF_VERSION */
1554 }
1555
1556
1557 /*******************************************************************************
1558 * Function Name: SfdpSetWriteDisableCommand
1559 ****************************************************************************//**
1560 *
1561 * Sets the Write Disable command and the width of the command transfer.
1562 *
1563 * \param cmdWriteDisable
1564 * The pointer to the Write Disable command parameters structure.
1565 *
1566 *******************************************************************************/
SfdpSetWriteDisableCommand(cy_stc_smif_mem_cmd_t * cmdWriteDisable)1567 static void SfdpSetWriteDisableCommand(cy_stc_smif_mem_cmd_t* cmdWriteDisable)
1568 {
1569 /* The 8-bit command. Write Disable */
1570 cmdWriteDisable->command = CY_SMIF_WRITE_DISABLE_CMD;
1571
1572 /* The width of the command transfer */
1573 cmdWriteDisable->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1574 }
1575
1576
1577 /*******************************************************************************
1578 * Function Name: SfdpSetProgramCommand_1_1_1
1579 ****************************************************************************//**
1580 *
1581 * Sets the Program command parameters for 1S-1S-1S Protocol mode and
1582 * 3-byte addressing mode.
1583 *
1584 * \param cmdProgram
1585 * The pointer to the Program command parameters structure.
1586 *
1587 *******************************************************************************/
SfdpSetProgramCommand_1_1_1(cy_stc_smif_mem_cmd_t * cmdProgram)1588 static void SfdpSetProgramCommand_1_1_1(cy_stc_smif_mem_cmd_t* cmdProgram)
1589 {
1590 /* 8-bit command. 1 x I/O Program command */
1591 cmdProgram->command = CY_SMIF_SINGLE_PROGRAM_CMD;
1592 #if (CY_IP_MXSMIF_VERSION>=2)
1593 /* command presence - 1 byte */
1594 cmdProgram->cmdPresence = CY_SMIF_PRESENT_1BYTE;
1595 #endif /* CY_IP_MXSMIF_VERSION */
1596 /* The command transfer width */
1597 cmdProgram->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1598 /* The address transfer width */
1599 cmdProgram->addrWidth = CY_SMIF_WIDTH_SINGLE;
1600 /* 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
1601 cmdProgram->mode = CY_SMIF_NO_COMMAND_OR_MODE;
1602 /* The width of the mode command transfer */
1603 cmdProgram->modeWidth = CY_SMIF_WIDTH_SINGLE;
1604 /* The dummy cycles number. A zero value suggests no dummy cycles */
1605 cmdProgram->dummyCycles = 0UL;
1606 /* The data transfer width */
1607 cmdProgram->dataWidth = CY_SMIF_WIDTH_SINGLE;
1608 }
1609
1610
1611 /*******************************************************************************
1612 * Function Name: SfdpSetProgramCommandFourBytes_1_1_1
1613 ****************************************************************************//**
1614 *
1615 * Sets the Program command parameters for 1S-1S-1S Protocol mode and
1616 * 4-byte addressing mode.
1617 *
1618 * \param cmdProgram
1619 * The pointer to the Program command parameters structure.
1620 *
1621 *******************************************************************************/
SfdpSetProgramCommandFourBytes_1_1_1(cy_stc_smif_mem_cmd_t * cmdProgram)1622 static void SfdpSetProgramCommandFourBytes_1_1_1(cy_stc_smif_mem_cmd_t* cmdProgram)
1623 {
1624 /* 8-bit command. 1 x I/O Program command */
1625 cmdProgram->command = CY_SMIF_PAGE_PROGRAM_4_BYTES_CMD_1S_1S_1S;
1626 #if (CY_IP_MXSMIF_VERSION>=2)
1627 /* command presence - 1 byte */
1628 cmdProgram->cmdPresence = CY_SMIF_PRESENT_1BYTE;
1629 #endif /* CY_IP_MXSMIF_VERSION */
1630 /* The command transfer width */
1631 cmdProgram->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1632 /* The address transfer width */
1633 cmdProgram->addrWidth = CY_SMIF_WIDTH_SINGLE;
1634 /* 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
1635 cmdProgram->mode = CY_SMIF_NO_COMMAND_OR_MODE;
1636 /* The width of the mode command transfer */
1637 cmdProgram->modeWidth = CY_SMIF_WIDTH_SINGLE;
1638 /* The dummy cycles number. A zero value suggests no dummy cycles */
1639 cmdProgram->dummyCycles = 0UL;
1640 /* The data transfer width */
1641 cmdProgram->dataWidth = CY_SMIF_WIDTH_SINGLE;
1642 }
1643
1644
1645 /*******************************************************************************
1646 * Function Name: SfdpSetProgramCommandFourBytes_1_1_4
1647 ****************************************************************************//**
1648 *
1649 * Sets the Program command parameters for 1S-1S-4S Protocol mode and
1650 * 4-byte addressing mode.
1651 *
1652 * \param cmdProgram
1653 * The pointer to the Program command parameters structure.
1654 *
1655 *******************************************************************************/
SfdpSetProgramCommandFourBytes_1_1_4(cy_stc_smif_mem_cmd_t * cmdProgram)1656 static void SfdpSetProgramCommandFourBytes_1_1_4(cy_stc_smif_mem_cmd_t* cmdProgram)
1657 {
1658 /* 8-bit command. 1 x I/O Program command */
1659 cmdProgram->command = CY_SMIF_PAGE_PROGRAM_4_BYTES_CMD_1S_1S_4S;
1660 #if (CY_IP_MXSMIF_VERSION>=2)
1661 /* command presence - 1 byte */
1662 cmdProgram->cmdPresence = CY_SMIF_PRESENT_1BYTE;
1663 #endif /* CY_IP_MXSMIF_VERSION */
1664 /* The command transfer width */
1665 cmdProgram->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1666 /* The address transfer width */
1667 cmdProgram->addrWidth = CY_SMIF_WIDTH_SINGLE;
1668 /* 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
1669 cmdProgram->mode = CY_SMIF_NO_COMMAND_OR_MODE;
1670 /* The width of the mode command transfer */
1671 cmdProgram->modeWidth = CY_SMIF_WIDTH_SINGLE;
1672 /* The dummy cycles number. A zero value suggests no dummy cycles */
1673 cmdProgram->dummyCycles = 0UL;
1674 /* The data transfer width */
1675 cmdProgram->dataWidth = CY_SMIF_WIDTH_QUAD;
1676 }
1677
1678
1679 /*******************************************************************************
1680 * Function Name: SfdpSetProgramCommandFourBytes_1_4_4
1681 ****************************************************************************//**
1682 *
1683 * Sets the Program command parameters for 1S-4S-4S Protocol mode and
1684 * 4-byte addressing mode.
1685 *
1686 * \param cmdProgram
1687 * The pointer to the Program command parameters structure.
1688 *
1689 *******************************************************************************/
SfdpSetProgramCommandFourBytes_1_4_4(cy_stc_smif_mem_cmd_t * cmdProgram)1690 static void SfdpSetProgramCommandFourBytes_1_4_4(cy_stc_smif_mem_cmd_t* cmdProgram)
1691 {
1692 /* 8-bit command. 1 x I/O Program command */
1693 cmdProgram->command = CY_SMIF_PAGE_PROGRAM_4_BYTES_CMD_1S_4S_4S;
1694 #if (CY_IP_MXSMIF_VERSION>=2)
1695 cmdProgram->cmdPresence = CY_SMIF_PRESENT_1BYTE;
1696 #endif /* CY_IP_MXSMIF_VERSION */
1697 /* The command transfer width */
1698 cmdProgram->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1699 /* The address transfer width */
1700 cmdProgram->addrWidth = CY_SMIF_WIDTH_QUAD;
1701 /* 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
1702 cmdProgram->mode = CY_SMIF_NO_COMMAND_OR_MODE;
1703 /* The width of the mode command transfer */
1704 cmdProgram->modeWidth = CY_SMIF_WIDTH_QUAD;
1705 /* The dummy cycles number. A zero value suggests no dummy cycles */
1706 cmdProgram->dummyCycles = 0UL;
1707 /* The data transfer width */
1708 cmdProgram->dataWidth = CY_SMIF_WIDTH_QUAD;
1709 }
1710
1711 /*******************************************************************************
1712 * Function Name: SfdpGetProgramFourBytesCmd
1713 ****************************************************************************//**
1714 *
1715 * Sets the Page Program command instruction for 4-byte addressing mode.
1716 *
1717 * \note When the Program command is not found for 4 byte addressing mode
1718 * the Program command instruction is set for 1S-1S-1S Protocol mode and
1719 * 3-byte addressing mode.
1720 *
1721 * \param sfdpBuffer
1722 * The pointer to an array with the SDFP buffer with the 4-byte Address
1723 * Instruction table.
1724 *
1725 * \param protocolMode
1726 * Protocol Mode.
1727 *
1728 * \param cmdProgram
1729 * The pointer to the Program command parameters structure.
1730 *
1731 *******************************************************************************/
SfdpGetProgramFourBytesCmd(uint8_t const sfdpBuffer[],cy_en_smif_protocol_mode_t protocolMode,cy_stc_smif_mem_cmd_t * cmdProgram)1732 static void SfdpGetProgramFourBytesCmd(uint8_t const sfdpBuffer[],
1733 cy_en_smif_protocol_mode_t protocolMode,
1734 cy_stc_smif_mem_cmd_t* cmdProgram)
1735 {
1736 /* Get the mask which contains the Support for Page Program Commands
1737 * from 4-byte Address Instruction Table, DWORD 1
1738 */
1739 uint32_t sfdpForBytesTableDword1 = ((uint32_t*)sfdpBuffer)[FOUR_BYTE_ADDRESS_TABLE_BYTE_0];
1740
1741 switch (protocolMode)
1742 {
1743 case PROTOCOL_MODE_1S_4S_4S:
1744 #if (CY_IP_MXSMIF_VERSION>=2)
1745 case PROTOCOL_MODE_1S_4D_4D:
1746 #endif /* CY_IP_MXSMIF_VERSION */
1747 if (_FLD2BOOL(SUPPORT_PP_1S_4S_4S_CMD, sfdpForBytesTableDword1))
1748 {
1749 SfdpSetProgramCommandFourBytes_1_4_4(cmdProgram);
1750 }
1751 else if (_FLD2BOOL(SUPPORT_PP_1S_1S_4S_CMD, sfdpForBytesTableDword1))
1752 {
1753 SfdpSetProgramCommandFourBytes_1_1_4(cmdProgram);
1754 }
1755 else if (_FLD2BOOL(SUPPORT_PP_1S_1S_1S_CMD, sfdpForBytesTableDword1))
1756 {
1757 SfdpSetProgramCommandFourBytes_1_1_1(cmdProgram);
1758 }
1759 else
1760 {
1761 /* There are no instructions for 4-byte mode. Use the instruction for 3-byte mode */
1762 SfdpSetProgramCommand_1_1_1(cmdProgram);
1763 }
1764 break;
1765 case PROTOCOL_MODE_1S_1S_4S:
1766 if (_FLD2BOOL(SUPPORT_PP_1S_1S_4S_CMD, sfdpForBytesTableDword1))
1767 {
1768 SfdpSetProgramCommandFourBytes_1_1_4(cmdProgram);
1769 }
1770 else if (_FLD2BOOL(SUPPORT_PP_1S_1S_1S_CMD, sfdpForBytesTableDword1))
1771 {
1772 SfdpSetProgramCommandFourBytes_1_1_1(cmdProgram);
1773 }
1774 else
1775 {
1776 /* There are no instructions for 4-byte mode. Use the instruction for 3-byte mode */
1777 SfdpSetProgramCommand_1_1_1(cmdProgram);
1778 }
1779 break;
1780 case PROTOCOL_MODE_1S_2S_2S:
1781 case PROTOCOL_MODE_1S_1S_2S:
1782 case PROTOCOL_MODE_1S_1S_1S:
1783 if (_FLD2BOOL(SUPPORT_PP_1S_1S_1S_CMD, sfdpForBytesTableDword1))
1784 {
1785 SfdpSetProgramCommandFourBytes_1_1_1(cmdProgram);
1786 }
1787 else
1788 {
1789 /* There are no instructions for 4-byte mode. Use the instruction for 3-byte mode */
1790 SfdpSetProgramCommand_1_1_1(cmdProgram);
1791 }
1792 break;
1793 default:
1794 /* Wrong mode */
1795 CY_ASSERT_L2(true);
1796 break;
1797 }
1798 }
1799
1800
1801 /*******************************************************************************
1802 * Function Name: SfdpSetWipStatusRegisterCommand
1803 ****************************************************************************//**
1804 *
1805 * Sets the WIP-containing status register command and
1806 * the width of the command transfer.
1807 *
1808 * \param readStsRegWipCmd
1809 * The pointer to the WIP-containing status register command parameters structure.
1810 *
1811 *******************************************************************************/
SfdpSetWipStatusRegisterCommand(cy_stc_smif_mem_cmd_t * readStsRegWipCmd)1812 static void SfdpSetWipStatusRegisterCommand(cy_stc_smif_mem_cmd_t* readStsRegWipCmd)
1813 {
1814 /* 8-bit command. WIP RDSR */
1815 readStsRegWipCmd->command = CY_SMIF_READ_STATUS_REG1_CMD;
1816 /* The command transfer width */
1817 readStsRegWipCmd->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1818 }
1819
1820
1821 /*******************************************************************************
1822 * Function Name: SfdpSetChipEraseCommand
1823 ****************************************************************************//**
1824 *
1825 * Sets the Chip Erase command and the width of the command transfer.
1826 *
1827 * \param cmdChipErase
1828 * The pointer to the Chip Erase command parameters structure.
1829 *
1830 *******************************************************************************/
SfdpSetChipEraseCommand(cy_stc_smif_mem_cmd_t * cmdChipErase)1831 static void SfdpSetChipEraseCommand(cy_stc_smif_mem_cmd_t* cmdChipErase)
1832 {
1833 /* 8-bit command. Chip Erase */
1834 cmdChipErase->command = CY_SMIF_CHIP_ERASE_CMD;
1835 /* The width of the command transfer */
1836 cmdChipErase->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1837 }
1838
1839
1840 /*******************************************************************************
1841 * Function Name: SfdpGetSectorEraseCommand
1842 ****************************************************************************//**
1843 *
1844 * Sets the Sector Erase command and the width of the command transfer.
1845 *
1846 * \note When the Erase command is not found the width of the command
1847 * transfer (cmdWidth) is set to CY_SMIF_WIDTH_NA.
1848 *
1849 * \param device
1850 * The device structure instance declared by the user. This is where the detected
1851 * parameters are stored and returned.
1852 *
1853 * \param sfdpBuffer
1854 * The pointer to an array with the SDFP buffer.
1855 *
1856 * \param eraseTypeStc
1857 * The pointer to an array with the erase commands for different erase types.
1858 *
1859 * \return The offset of the Sector Erase command in the SFDP buffer.
1860 * Returns 0 when the Sector Erase command is not found.
1861 *
1862 *******************************************************************************/
SfdpGetSectorEraseCommand(cy_stc_smif_mem_device_cfg_t * device,uint8_t const sfdpBuffer[],cy_stc_smif_erase_type_t eraseTypeStc[])1863 static uint32_t SfdpGetSectorEraseCommand(cy_stc_smif_mem_device_cfg_t *device,
1864 uint8_t const sfdpBuffer[],
1865 cy_stc_smif_erase_type_t eraseTypeStc[])
1866 {
1867 uint32_t eraseOffset;
1868 if (FOUR_BYTE_ADDRESS == device->numOfAddrBytes)
1869 {
1870 uint32_t eraseType; /* Erase Type decreased to 1 */
1871 uint32_t eraseTypeMask;
1872
1873 eraseOffset = COMMAND_IS_NOT_FOUND;
1874 device->eraseCmd->command = CY_SMIF_NO_COMMAND_OR_MODE;
1875
1876 /* Get the mask which contains the Support for Erase Commands (Types 1-4)
1877 * from 4-byte Address Instruction Table, DWORD 1
1878 */
1879 eraseTypeMask = _FLD2VAL(SUPPORT_ERASE_COMMAND, (uint32_t)sfdpBuffer[FOUR_BYTE_ADDRESS_TABLE_BYTE_1]);
1880
1881 /* Find Erase Type (decreased to 1) */
1882 for (eraseType = 0UL; eraseType <= ERASE_TYPE_COUNT; eraseType++)
1883 {
1884 if ((1UL << eraseType) == (eraseTypeMask & (1UL << eraseType)))
1885 {
1886 /* Erase Type found */
1887 break;
1888 }
1889 }
1890
1891 if (eraseType < ERASE_TYPE_COUNT)
1892 {
1893 /* Calculate the offset for the sector Erase command in the 4-byte Address Instruction Table, DWORD 2 */
1894 eraseOffset = FOUR_BYTE_ADDR_ERASE_TYPE_1 + eraseType;
1895
1896 /* Update all erase commands for 4-bytes */
1897 for(uint32_t i = 0UL; i< ERASE_TYPE_COUNT; i++)
1898 {
1899 eraseTypeStc[i].eraseCmd = sfdpBuffer[FOUR_BYTE_ADDR_ERASE_TYPE_1 + i];
1900 }
1901 /* Get the sector Erase command
1902 * from the 4-byte Address Instruction Table, DWORD 2
1903 */
1904 device->eraseCmd->command = sfdpBuffer[eraseOffset];
1905 #if (CY_IP_MXSMIF_VERSION>=2)
1906 device->eraseCmd->cmdPresence = CY_SMIF_PRESENT_1BYTE;
1907 #endif /* CY_IP_MXSMIF_VERSION */
1908
1909 /* Recalculate eraseOffset for the 3-byte Address Instruction Table
1910 * to find the device->eraseSize and device->eraseTime parameters based on Erase Type.
1911 */
1912 eraseOffset = CY_SMIF_SFDP_BFPT_BYTE_1D + (eraseType * TYPE_STEP);
1913 }
1914 }
1915 else
1916 {
1917 eraseOffset = CY_SMIF_SFDP_BFPT_BYTE_1D;
1918 while (INSTRUCTION_NOT_SUPPORTED == sfdpBuffer[eraseOffset])
1919 {
1920 if (eraseOffset >= CY_SMIF_SFDP_BFPT_BYTE_23)
1921 {
1922 /* The Sector Erase command is not found */
1923 eraseOffset = COMMAND_IS_NOT_FOUND;
1924 break;
1925 }
1926 eraseOffset += TYPE_STEP; /* Check the next Erase Type */
1927 }
1928
1929 if (COMMAND_IS_NOT_FOUND != eraseOffset)
1930 {
1931 /* Get the sector Erase command from the JEDEC basic flash parameter table */
1932 device->eraseCmd->command = sfdpBuffer[eraseOffset];
1933 #if (CY_IP_MXSMIF_VERSION>=2)
1934 device->eraseCmd->cmdPresence = CY_SMIF_PRESENT_1BYTE;
1935 #endif /* CY_IP_MXSMIF_VERSION */
1936 }
1937 }
1938
1939 if (COMMAND_IS_NOT_FOUND != eraseOffset)
1940 {
1941 /* The command transfer width */
1942 device->eraseCmd->cmdWidth = CY_SMIF_WIDTH_SINGLE;
1943
1944 /* The address transfer width */
1945 device->eraseCmd->addrWidth = CY_SMIF_WIDTH_SINGLE;
1946 }
1947 else
1948 {
1949 device->eraseCmd->cmdWidth = CY_SMIF_WIDTH_NA;
1950 }
1951
1952 return(eraseOffset);
1953 }
1954
1955 /*******************************************************************************
1956 * Function Name: SfdpEnterFourByteAddressing
1957 ****************************************************************************//**
1958 *
1959 * This function sets 4-byte address mode for a memory device as defined in
1960 * 16th DWORD of JEDEC Basic Flash Parameter Table.
1961 *
1962 * \note The entry methods which do not support the required
1963 * operation of writing into the register.
1964 *
1965 * \param base
1966 * Holds the base address of the SMIF block registers.
1967 *
1968 * \param entryMethodByte
1969 * The byte which defines the supported method to enter 4-byte addressing mode.
1970 *
1971 * \param device
1972 * The device structure instance declared by the user. This is where the detected
1973 * parameters are stored and returned.
1974 *
1975 * \param slaveSelect
1976 * The slave select line for the device.
1977 *
1978 * \param context
1979 * This is the pointer to the context structure \ref cy_stc_smif_context_t
1980 * allocated by the user. The structure is used during the SMIF
1981 * operation for internal configuration and data retention. The user must not
1982 * modify anything in this structure.
1983 *
1984 * \return A status of 4-byte addressing mode command transmit.
1985 * - \ref CY_SMIF_SUCCESS
1986 * - \ref CY_SMIF_EXCEED_TIMEOUT
1987 * - \ref CY_SMIF_CMD_NOT_FOUND
1988 *******************************************************************************/
SfdpEnterFourByteAddressing(SMIF_Type * base,uint8_t entryMethodByte,cy_stc_smif_mem_device_cfg_t * device,cy_en_smif_slave_select_t slaveSelect,cy_stc_smif_context_t const * context)1989 static cy_en_smif_status_t SfdpEnterFourByteAddressing(SMIF_Type *base, uint8_t entryMethodByte,
1990 cy_stc_smif_mem_device_cfg_t *device,
1991 cy_en_smif_slave_select_t slaveSelect,
1992 cy_stc_smif_context_t const *context)
1993 {
1994 cy_en_smif_status_t result = CY_SMIF_CMD_NOT_FOUND;
1995
1996 if ((entryMethodByte & CY_SMIF_SFDP_ENTER_4_BYTE_METHOD_SUPPORTED_MASK) != 0U)
1997 {
1998 /* Supports one of the 4-byte Entry methods */
1999 result = CY_SMIF_SUCCESS;
2000
2001 if ((entryMethodByte & CY_SMIF_SFDP_ENTER_4_BYTE_METHOD_WR_EN_B7) != 0U)
2002 {
2003 /* To enter a 4-byte addressing write enable is required */
2004 cy_stc_smif_mem_cmd_t* writeEn = device->writeEnCmd;
2005
2006 if(NULL != writeEn)
2007 {
2008 result = Cy_SMIF_TransmitCommand(base,
2009 (uint8_t) writeEn->command,
2010 writeEn->cmdWidth,
2011 NULL,
2012 CY_SMIF_CMD_WITHOUT_PARAM,
2013 CY_SMIF_WIDTH_NA,
2014 slaveSelect,
2015 CY_SMIF_TX_LAST_BYTE,
2016 context);
2017 }
2018 }
2019
2020 if ( (((entryMethodByte & CY_SMIF_SFDP_ENTER_4_BYTE_METHOD_B7) != 0U) ||
2021 ((entryMethodByte & CY_SMIF_SFDP_ENTER_4_BYTE_METHOD_WR_EN_B7) != 0U)) &&
2022 (result == CY_SMIF_SUCCESS))
2023 {
2024 /* To enter a 4-byte addressing B7 instruction is required */
2025 result = Cy_SMIF_TransmitCommand(base,
2026 CY_SMIF_SFDP_ENTER_4_BYTE_METHOD_B7_CMD,
2027 CY_SMIF_WIDTH_SINGLE,
2028 NULL,
2029 CY_SMIF_CMD_WITHOUT_PARAM,
2030 CY_SMIF_WIDTH_NA,
2031 slaveSelect,
2032 CY_SMIF_TX_LAST_BYTE,
2033 context);
2034 }
2035 }
2036 return result;
2037 }
2038
2039
2040 /*******************************************************************************
2041 * Function Name: SfdpGetEraseSizeAndCmd
2042 ****************************************************************************//**
2043 *
2044 * Fills arrays with an erase size and cmd for all erase types.
2045 *
2046 * \param sfdpBuffer
2047 * The pointer to an array with the Basic Flash Parameter table buffer.
2048 *
2049 * \param eraseType
2050 * The pointer to an array with the erase commands and erase size for all erase types.
2051 *
2052 *******************************************************************************/
SfdpGetEraseSizeAndCmd(uint8_t const sfdpBuffer[],cy_stc_smif_erase_type_t eraseType[])2053 static void SfdpGetEraseSizeAndCmd(uint8_t const sfdpBuffer[],
2054 cy_stc_smif_erase_type_t eraseType[])
2055 {
2056 uint32_t idx = 0UL;
2057 for (uint32_t currET = 0UL; currET < ERASE_TYPE_COUNT; currET++)
2058 {
2059 /* The erase size in the SFDP buffer defined as power of two */
2060 eraseType[currET].eraseSize = 1UL << sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_1C + idx];
2061 eraseType[currET].eraseCmd = sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_1D + idx];
2062 idx += TYPE_STEP;
2063 }
2064 }
2065
2066
2067 /*******************************************************************************
2068 * Function Name: SfdpPopulateRegionInfo
2069 ****************************************************************************//**
2070 *
2071 * Reads the current configuration for regions and populates regionInfo
2072 * structures.
2073 *
2074 * \param base
2075 * Holds the base address of the SMIF block registers.
2076 *
2077 * \param sectorMapBuff
2078 * The pointer to an array with the Sector Map Parameter Table buffer.
2079 *
2080 * \param buffLength
2081 * Length of the Sector Map Parameter Table buffer.
2082
2083 * \param device
2084 * The device structure instance declared by the user. This is where the detected
2085 * parameters are stored and returned.
2086 *
2087 * \param slaveSelect
2088 * The slave select line for the device.
2089 *
2090 * \param context
2091 * This is the pointer to the context structure \ref cy_stc_smif_context_t
2092 * allocated by the user. The structure is used during the SMIF
2093 * operation for internal configuration and data retention. The user must not
2094 * modify anything in this structure.
2095 *
2096 * \param eraseType
2097 * The pointer to an array with the erase size, erase command and erase time for all erase types.
2098 *
2099 * \return A status of the Sector Map Parameter Table parsing.
2100 * - \ref CY_SMIF_SUCCESS
2101 * - \ref CY_SMIF_SFDP_CORRUPTED_TABLE
2102 * - \ref CY_SMIF_NOT_HYBRID_MEM
2103 *
2104 *******************************************************************************/
SfdpPopulateRegionInfo(SMIF_Type * base,uint8_t const sectorMapBuff[],uint32_t const buffLength,cy_stc_smif_mem_device_cfg_t * device,cy_en_smif_slave_select_t slaveSelect,const cy_stc_smif_context_t * context,cy_stc_smif_erase_type_t eraseType[])2105 static cy_en_smif_status_t SfdpPopulateRegionInfo(SMIF_Type *base,
2106 uint8_t const sectorMapBuff[],
2107 uint32_t const buffLength,
2108 cy_stc_smif_mem_device_cfg_t *device,
2109 cy_en_smif_slave_select_t slaveSelect,
2110 const cy_stc_smif_context_t *context,
2111 cy_stc_smif_erase_type_t eraseType[])
2112 {
2113 uint8_t currCmd;
2114 uint8_t dummyCycles;
2115 uint8_t regMask;
2116 uint8_t regValue;
2117 uint8_t currRegisterAddr[ERASE_TYPE_COUNT];
2118 uint8_t regionInfoIdx = 0U;
2119 uint32_t currTableIdx = 0UL;
2120 uint32_t addrBytesNum = 0UL;
2121 uint32_t addrCode = 0UL;
2122 cy_en_smif_status_t result = CY_SMIF_NOT_HYBRID_MEM;
2123
2124 /* Initialize register address */
2125 for (uint32_t i = 0U; i < ERASE_TYPE_COUNT; i++)
2126 {
2127 currRegisterAddr[i] = 0U;
2128 }
2129
2130 /* Loop across all command descriptors to find current configuration */
2131 while(SECTOR_MAP_COMAND_DESCRIPTOR_TYPE == (sectorMapBuff[currTableIdx] & SECTOR_MAP_DESCRIPTOR_MASK))
2132 {
2133 currCmd = sectorMapBuff[currTableIdx + CY_SMIF_SFDP_SECTOR_MAP_CMD_OFFSET];
2134 regMask = sectorMapBuff[currTableIdx + CY_SMIF_SFDP_SECTOR_MAP_REG_MSK_OFFSET];
2135 regValue = 0U;
2136
2137 /* Get the address length for configuration detection */
2138 addrCode = _FLD2VAL(CY_SMIF_SFDP_SECTOR_MAP_ADDR_BYTES, sectorMapBuff[currTableIdx + CY_SMIF_SFDP_SECTOR_MAP_ADDR_LEN_OFFSET]);
2139 switch(addrCode)
2140 {
2141 case CY_SMIF_SFDP_THREE_BYTES_ADDR_CODE:
2142 /* No address cycle */
2143 addrBytesNum = 0UL;
2144 break;
2145 case CY_SMIF_SFDP_THREE_OR_FOUR_BYTES_ADDR_CODE:
2146 addrBytesNum = CY_SMIF_THREE_BYTES_ADDR;
2147 break;
2148 case CY_SMIF_SFDP_FOUR_BYTES_ADDR_CODE:
2149 addrBytesNum = CY_SMIF_FOUR_BYTES_ADDR;
2150 break;
2151 default:
2152 /* Use the current settings */
2153 addrBytesNum = device->numOfAddrBytes;
2154 break;
2155 }
2156
2157 /* Get the control register address */
2158 for(uint8_t i = 0U; i < addrBytesNum; i++)
2159 {
2160 /* Offset for control register in SFDP has little-endian byte order, need to swap it */
2161 currRegisterAddr[i] = sectorMapBuff[(currTableIdx + CY_SMIF_SFDP_SECTOR_MAP_REG_ADDR_OFFSET + addrBytesNum) - i - 1UL];
2162 }
2163
2164 /* Get the number of latency cycles required for configuration detection command */
2165 dummyCycles = (uint8_t) _FLD2VAL(CY_SMIF_SFDP_SECTOR_MAP_DUMMY_CYCLES, sectorMapBuff[currTableIdx + CY_SMIF_SFDP_SECTOR_MAP_ADDR_LEN_OFFSET]);
2166
2167 /* If variable latency is detected use 8 cycles as serial flash repeats RX data in case 0 dummy cycles required */
2168 if (dummyCycles == 0xFU)
2169 {
2170 dummyCycles = 8U;
2171 }
2172
2173 /* Read the value of the register for the current configuration detection */
2174 result = ReadAnyReg(base, slaveSelect, ®Value, currCmd, dummyCycles, &currRegisterAddr[0], addrBytesNum, context);
2175
2176 if (CY_SMIF_SUCCESS == result)
2177 {
2178 /* Set the bit of the region idx to 1 if the config matches */
2179 regionInfoIdx = ((uint8_t)(regionInfoIdx << 1U)) | (((regValue & regMask) == 0U)?(0U):(1U));
2180 }
2181
2182 currTableIdx += HEADER_LENGTH;
2183 if (currTableIdx > buffLength)
2184 {
2185 result = CY_SMIF_SFDP_CORRUPTED_TABLE;
2186 break;
2187 }
2188 }
2189
2190 if (CY_SMIF_SUCCESS == result)
2191 {
2192 /* Find the matching configuration map descriptor */
2193 while(regionInfoIdx != sectorMapBuff[currTableIdx + 1UL])
2194 {
2195 /* Increment the table index to the next map */
2196 currTableIdx += (sectorMapBuff[currTableIdx + CY_SMIF_SFDP_SECTOR_MAP_CONFIG_ID_OFFSET] + 2UL) * BYTES_IN_DWORD;
2197 if (currTableIdx > buffLength)
2198 {
2199 result = CY_SMIF_SFDP_CORRUPTED_TABLE;
2200 break;
2201 }
2202 }
2203 }
2204
2205 if (CY_SMIF_SUCCESS == result)
2206 {
2207 /* Populate region data from the sector map */
2208 uint8_t numOfRegions = sectorMapBuff[currTableIdx + CY_SMIF_SFDP_SECTOR_MAP_REGION_COUNT_OFFSET] + 1U;
2209 device->hybridRegionCount = (uint32_t) numOfRegions;
2210
2211 if(numOfRegions <= 1U)
2212 {
2213 result = CY_SMIF_NOT_HYBRID_MEM;
2214 }
2215 else
2216 {
2217 uint8_t eraseTypeCode;
2218 uint32_t currRegionAddr = 0UL;
2219 uint32_t regionSize = 0UL;
2220 uint8_t supportedEraseType;
2221 uint8_t eraseTypeMask;
2222 cy_stc_smif_hybrid_region_info_t *currRegionPtr;
2223 for(uint8_t currRegion = 0U; currRegion< numOfRegions; currRegion++)
2224 {
2225 currRegionAddr = currRegionAddr + regionSize;
2226 currTableIdx += BYTES_IN_DWORD;
2227
2228 supportedEraseType = 0U;
2229 eraseTypeMask = 1U;
2230 eraseTypeCode = sectorMapBuff[currTableIdx] & CY_SMIF_SFDP_SECTOR_MAP_SUPPORTED_ET_MASK;
2231 while(0U == (eraseTypeCode & eraseTypeMask))
2232 {
2233 /* Erase type number defined as a bit position */
2234 eraseTypeMask = eraseTypeMask << 1;
2235 supportedEraseType++;
2236 if(supportedEraseType > ERASE_TYPE_COUNT)
2237 {
2238 result = CY_SMIF_SFDP_CORRUPTED_TABLE;
2239 break;
2240 }
2241 }
2242
2243 /* The region size as a zero-based count of 256 byte units */
2244 regionSize = ((*( (uint32_t*) §orMapBuff[currTableIdx]) >> BITS_IN_BYTE) + 1UL) * SECTOR_MAP_REGION_SIZE_MULTIPLIER;
2245 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 11.3')
2246 currRegionPtr = device->hybridRegionInfo[currRegion];
2247
2248 currRegionPtr->regionAddress = currRegionAddr;
2249 currRegionPtr->eraseCmd = (uint32_t)eraseType[supportedEraseType].eraseCmd;
2250 currRegionPtr->eraseTime = eraseType[supportedEraseType].eraseTime;
2251 if(regionSize < eraseType[supportedEraseType].eraseSize)
2252 {
2253 /* One region with a single sector */
2254 currRegionPtr->eraseSize = regionSize;
2255 currRegionPtr->sectorsCount = 1UL;
2256 }
2257 else
2258 {
2259 currRegionPtr->eraseSize = eraseType[supportedEraseType].eraseSize;
2260 currRegionPtr->sectorsCount = regionSize / eraseType[supportedEraseType].eraseSize;
2261 }
2262 }
2263 }
2264 }
2265 return result;
2266 }
2267
2268 #if (CY_IP_MXSMIF_VERSION>=2) && defined(SMIF_OCTAL_SFDP_SUPPORT)
GetOctalSDRParams(SMIF_Type * base,uint8_t sfdpBuffer[],cy_stc_smif_mem_device_cfg_t * device,cy_en_smif_slave_select_t slaveSelect,uint32_t sfdpForBytesTableDword1,uint8_t * sccrMapAddr,uint8_t sccrMapTableLength,cy_stc_smif_context_t * context)2269 static cy_en_smif_protocol_mode_t GetOctalSDRParams(SMIF_Type *base,
2270 uint8_t sfdpBuffer[],
2271 cy_stc_smif_mem_device_cfg_t *device,
2272 cy_en_smif_slave_select_t slaveSelect,
2273 uint32_t sfdpForBytesTableDword1,
2274 uint8_t *sccrMapAddr,
2275 uint8_t sccrMapTableLength,
2276 cy_stc_smif_context_t *context)
2277 {
2278 cy_en_smif_protocol_mode_t protocol = PROTOCOL_MODE_WRONG;
2279 cy_en_smif_status_t result = CY_SMIF_NO_OE_BIT;
2280 cy_stc_smif_mem_cmd_t *cmdSfdp = device->readSfdpCmd;
2281 cy_stc_smif_mem_cmd_t *cmdRead = device->readCmd;
2282
2283 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 11.3', 'Pointer type conversion is intentional.');
2284
2285 if (_FLD2BOOL(SUPPORT_FAST_READ_1S_8S_8S_CMD,
2286 sfdpForBytesTableDword1))
2287 {
2288 SfdpGetReadCmd_1_8_8(sfdpBuffer, cmdRead);
2289 protocol = PROTOCOL_MODE_1S_8S_8S;
2290 }
2291 else if (_FLD2BOOL(SUPPORT_FAST_READ_1S_1S_8S_CMD,
2292 sfdpForBytesTableDword1))
2293 {
2294 SfdpGetReadCmd_1_1_8(sfdpBuffer, cmdRead);
2295 protocol = PROTOCOL_MODE_1S_1S_8S;
2296 }
2297 else
2298 {
2299 /* Do Nothing */
2300 }
2301
2302 if (protocol != PROTOCOL_MODE_WRONG)
2303 {
2304 /* Get Octal Enable commands and mask */
2305 uint8_t sccrMapAddrBuffer[CY_SMIF_SFDP_LENGTH];
2306
2307 /* Get the JEDEC SCCR Map Table content into sfdpBuffer[] */
2308 result = SfdpReadBuffer(base, cmdSfdp, sccrMapAddr, slaveSelect,
2309 sccrMapTableLength, sccrMapAddrBuffer, context);
2310
2311 if (result == CY_SMIF_SUCCESS)
2312 {
2313 /* Get the mask which contains the Support for Fast Read Commands
2314 * from SCCR Map Table, DWORD 16
2315 */
2316 CY_MISRA_DEVIATE_LINE('MISRA C-2012 Rule 11.3', 'Pointer type conversion is intentional.');
2317 uint32_t sccrMapAddrBufferDword16 = (*(uint32_t*)&sccrMapAddrBuffer[CY_SMIF_SFDP_SCCR_MAP_BYTE_3B]);
2318
2319 /* Read DWORD-16 to fill read and write Octal Enable commands */
2320 if (_FLD2BOOL(CY_SMIF_SFDP_OCTAL_ENABLE_BIT_SUPPORT, sccrMapAddrBufferDword16))
2321 {
2322 device->stsRegOctalEnableMask = _FLD2VAL(CY_SMIF_SFDP_OCTAL_ENABLE_BIT, sccrMapAddrBufferDword16);
2323 device->writeStsRegOeCmd->command = _FLD2VAL(CY_SMIF_SFDP_OCTAL_ENABLE_WRITE_CMD, sccrMapAddrBufferDword16);
2324 device->readStsRegOeCmd->command = _FLD2VAL(CY_SMIF_SFDP_OCTAL_ENABLE_READ_CMD, sccrMapAddrBufferDword16);
2325
2326 if (_FLD2BOOL(CY_SMIF_SFDP_OCTAL_ENABLE_USE_ADDRESS, sccrMapAddrBufferDword16))
2327 {
2328 device->octalEnableRegAddr = _FLD2VAL(CY_SMIF_SFDP_OCTAL_ENABLE_REG_ADDR, sccrMapAddrBufferDword16);
2329 }
2330 else
2331 {
2332 device->octalEnableRegAddr = CY_SMIF_NO_COMMAND_OR_MODE;
2333 }
2334 device->writeStsRegOeCmd->cmdPresence = CY_SMIF_PRESENT_1BYTE;
2335 device->readStsRegOeCmd->cmdPresence = CY_SMIF_PRESENT_1BYTE;
2336 }
2337 }
2338 }
2339
2340 return protocol;
2341 }
GetOctalDDRParams(SMIF_Type * base,cy_stc_smif_mem_device_cfg_t * device,cy_en_smif_slave_select_t slaveSelect,uint8_t * cmdSeqODDRAddr,uint8_t cmdSeqODDRTableLength,uint8_t * xSPiProfile1Addr,uint8_t xSPIProfile1TableLength,uint8_t * sccrMapAddr,uint8_t sccrMapTableLength,cy_stc_smif_context_t * context)2342 static cy_en_smif_protocol_mode_t GetOctalDDRParams(SMIF_Type *base,
2343 cy_stc_smif_mem_device_cfg_t *device,
2344 cy_en_smif_slave_select_t slaveSelect,
2345 uint8_t* cmdSeqODDRAddr,
2346 uint8_t cmdSeqODDRTableLength,
2347 uint8_t* xSPiProfile1Addr,
2348 uint8_t xSPIProfile1TableLength,
2349 uint8_t* sccrMapAddr,
2350 uint8_t sccrMapTableLength,
2351 cy_stc_smif_context_t *context)
2352 {
2353 uint8_t xSPiProfile1AddrBuffer[CY_SMIF_SFDP_LENGTH];
2354 cy_en_smif_status_t result = CY_SMIF_NO_OE_BIT;
2355 cy_stc_smif_mem_cmd_t *cmdSfdp = device->readSfdpCmd;
2356 cy_stc_smif_mem_cmd_t *cmdRead = device->readCmd;
2357 cy_en_smif_protocol_mode_t pMode = PROTOCOL_MODE_WRONG;
2358 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.8', 5, 'uint8_t to uin32_t type conversion intentional.')
2359
2360 /* Initialize SFDP Buffer */
2361 for (uint32_t i = 0U; i < CY_SMIF_SFDP_LENGTH; i++)
2362 {
2363 xSPiProfile1AddrBuffer[i] = 0U;
2364 }
2365
2366 /* Get the JEDEC xSPI Profile 1.0 content into xSPiProfile1AddrBuffer[] */
2367 result = SfdpReadBuffer(base, cmdSfdp, xSPiProfile1Addr, slaveSelect,
2368 xSPIProfile1TableLength, xSPiProfile1AddrBuffer, context);
2369
2370 if (CY_SMIF_SUCCESS == result)
2371 {
2372 /* If found Octal DDR read is supported */
2373 if (xSPiProfile1AddrBuffer[XSPI_PROFILE_1_TABLE_BYTE_1] != 0U)
2374 {
2375 cmdRead->command = xSPiProfile1AddrBuffer[XSPI_PROFILE_1_TABLE_BYTE_1];
2376 cmdRead->commandH = cmdRead->command;
2377
2378 /* command presence - 2 byte transfer */
2379 cmdRead->cmdPresence = CY_SMIF_PRESENT_2BYTE;
2380
2381 /* The command transfer width */
2382 cmdRead->cmdWidth = CY_SMIF_WIDTH_OCTAL;
2383
2384 /* DDR rate for all phases */
2385 cmdRead->cmdRate = CY_SMIF_DDR;
2386 cmdRead->dataRate = CY_SMIF_DDR;
2387 cmdRead->modeRate = CY_SMIF_DDR;
2388 cmdRead->addrRate = CY_SMIF_DDR;
2389
2390 /* The address transfer width */
2391 cmdRead->addrWidth = CY_SMIF_WIDTH_OCTAL;
2392
2393 /* The 8-bit mode byte. This value is 0xFFFFFFFF when there is no mode present */
2394 cmdRead->mode = CY_SMIF_NO_COMMAND_OR_MODE;
2395
2396 /* Variable latency configuration command */
2397 if (sccrMapTableLength > 0U)
2398 {
2399 SfdpSetVariableLatencyCmd(base, device, slaveSelect, sccrMapAddr, context);
2400 }
2401
2402 if ((device->writeLatencyCmd->command != CY_SMIF_NO_COMMAND_OR_MODE))
2403 {
2404 uint8_t cfr_reg_address[5U];
2405 uint8_t cfr_value = 0;
2406
2407 /* Initialize DWords */
2408 for (uint8_t i = 0U; i < 5U; i++)
2409 {
2410 cfr_reg_address[i] = 0U;
2411 }
2412
2413 switch (device->freq_of_operation)
2414 {
2415 case CY_SMIF_100MHZ_OPERATION:
2416 /* DWORD-5, Bits 11:7 should be > 0 to confirm if 100 MHz is supported or not */
2417 if ( ((xSPiProfile1AddrBuffer[16] & 0x80U) | ((xSPiProfile1AddrBuffer[17] & 0x0FU) << 1U)) > 0U)
2418 {
2419 cmdRead->dummyCycles = (uint32_t) ((xSPiProfile1AddrBuffer[16] & 0x80U) | ((xSPiProfile1AddrBuffer[17] & 0x0FU) << 1U));
2420
2421 /* DWORD-5 Bits 6:2 */
2422 cfr_value = (xSPiProfile1AddrBuffer[16] & 0x7CU);
2423 }
2424
2425 break;
2426 case CY_SMIF_133MHZ_OPERATION:
2427 /* DWORD-5, Bits 21:17 should be > 0 to confirm if 133 MHz is supported or not */
2428 if ((xSPiProfile1AddrBuffer[17] & 0x3EU) > 0U)
2429 {
2430 cmdRead->dummyCycles = (uint32_t) (xSPiProfile1AddrBuffer[17] & 0x3EU);
2431
2432 /* DWORD-5, Bits 21:17 */
2433 cfr_value = ((xSPiProfile1AddrBuffer[17] & 0xF0U) << 1U) | (xSPiProfile1AddrBuffer[18] & 0x1U);
2434 }
2435 break;
2436 case CY_SMIF_166MHZ_OPERATION:
2437 /* DWORD-5, Bits 31:27 should be > 0 to confirm if 133 MHz is supported or not */
2438 if ((xSPiProfile1AddrBuffer[19] & 0xE0U) > 0U)
2439 {
2440 cmdRead->dummyCycles = (uint32_t) xSPiProfile1AddrBuffer[19] & 0xE0U;
2441
2442 /* DWORD -5 Bits 26:22 */
2443 cfr_value = ((xSPiProfile1AddrBuffer[19] & 0x07U) << 2U) | (xSPiProfile1AddrBuffer[18] & 0xC0U);
2444 }
2445 break;
2446 case CY_SMIF_200MHZ_OPERATION:
2447 /* DWORD-4, Bits 11:7 should be > 0 to confirm if 133 MHz is supported or not */
2448 if ( ((xSPiProfile1AddrBuffer[12] & 0x80U) | ((xSPiProfile1AddrBuffer[13] & 0x0FU) << 1U)) > 0U)
2449 {
2450 cmdRead->dummyCycles = (uint32_t) ((xSPiProfile1AddrBuffer[12] & 0x80U) | ((xSPiProfile1AddrBuffer[13] & 0x0FU) << 1U));
2451
2452 /* DWORD-4 Bits 6:2 */
2453 cfr_value = (xSPiProfile1AddrBuffer[12] & 0x7CU);
2454 }
2455 break;
2456 default:
2457 /* Do Nothing */
2458 break;
2459 }
2460
2461 if (cfr_value > 0U)
2462 {
2463 ValueToByteArray(device->latencyCyclesRegAddr, cfr_reg_address, 0, 4U);
2464 cfr_reg_address[4] = cfr_value;
2465
2466 result = Cy_SMIF_MemCmdWriteRegister(base,
2467 slaveSelect,
2468 device->writeEnCmd,
2469 device->writeLatencyCmd,
2470 cfr_reg_address,
2471 5U,
2472 context);
2473 }
2474
2475 }
2476 else
2477 {
2478 cmdRead->dummyCycles = 8U; /* Default value */
2479 }
2480
2481 /* dummy cycles present - 2 byte transfer */
2482 if(cmdRead->dummyCycles > 0UL)
2483 {
2484 cmdRead->dummyCyclesPresence = CY_SMIF_PRESENT_2BYTE;
2485 }
2486
2487 /* The data transfer width */
2488 cmdRead->dataWidth = CY_SMIF_WIDTH_OCTAL;
2489
2490 pMode = PROTOCOL_MODE_8D_8D_8D;
2491
2492 /* Fill command sequence to switch to Octal DDR mode */
2493 uint8_t cmdSeqODDRAddrBuffer[CY_SMIF_SFDP_LENGTH];
2494
2495 /* Initialize SFDP Buffer */
2496 for (uint32_t i = 0U; i < CY_SMIF_SFDP_LENGTH; i++)
2497 {
2498 cmdSeqODDRAddrBuffer[i] = 0U;
2499 }
2500
2501 if (result == CY_SMIF_SUCCESS)
2502 {
2503 /* Get the command sequence to change to Octal DDR mode content into cmdSeqODDRAddrBuffer[] */
2504 result = SfdpReadBuffer(base, cmdSfdp, cmdSeqODDRAddr, slaveSelect,
2505 cmdSeqODDRTableLength, cmdSeqODDRAddrBuffer, context);
2506 }
2507
2508 if (result == CY_SMIF_SUCCESS)
2509 {
2510 cy_stc_smif_octal_ddr_en_seq_t* oDDREnSeq = device->octalDDREnableSeq;
2511
2512 oDDREnSeq->cmdSeq1Len = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD1_LEN_BYTE_OFFSET];
2513 oDDREnSeq->cmdSeq2Len = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD2_LEN_BYTE_OFFSET];
2514 if (oDDREnSeq->cmdSeq1Len > 0U && oDDREnSeq->cmdSeq1Len < CY_SMIF_SFDP_ODDR_CMD_SEQ_MAX_LEN)
2515 {
2516 oDDREnSeq->cmdSeq1[0] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD1_LEN_BYTE_OFFSET - 1U];
2517 oDDREnSeq->cmdSeq1[1] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD1_LEN_BYTE_OFFSET - 2U];
2518 oDDREnSeq->cmdSeq1[2] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD1_LEN_BYTE_OFFSET - 3U];
2519 oDDREnSeq->cmdSeq1[3] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD1_LEN_BYTE_OFFSET + 4U];
2520 oDDREnSeq->cmdSeq1[4] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD1_LEN_BYTE_OFFSET + 3U];
2521 oDDREnSeq->cmdSeq1[5] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD1_LEN_BYTE_OFFSET + 2U];
2522 oDDREnSeq->cmdSeq1[6] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD1_LEN_BYTE_OFFSET + 1U];
2523 }
2524 if (oDDREnSeq->cmdSeq2Len > 0U && oDDREnSeq->cmdSeq2Len < CY_SMIF_SFDP_ODDR_CMD_SEQ_MAX_LEN)
2525 {
2526 oDDREnSeq->cmdSeq2[0] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD2_LEN_BYTE_OFFSET - 1U];
2527 oDDREnSeq->cmdSeq2[1] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD2_LEN_BYTE_OFFSET - 2U];
2528 oDDREnSeq->cmdSeq2[2] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD2_LEN_BYTE_OFFSET - 3U];
2529 oDDREnSeq->cmdSeq2[3] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD2_LEN_BYTE_OFFSET + 4U];
2530 oDDREnSeq->cmdSeq2[4] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD2_LEN_BYTE_OFFSET + 3U];
2531 oDDREnSeq->cmdSeq2[5] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD2_LEN_BYTE_OFFSET + 2U];
2532 oDDREnSeq->cmdSeq2[6] = cmdSeqODDRAddrBuffer[CMD_SEQ_OCTAL_DDR_CMD2_LEN_BYTE_OFFSET + 1U];
2533 }
2534 }
2535 }
2536 }
2537 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 10.8')
2538 return pMode;
2539 }
2540 #endif
2541
2542 /*******************************************************************************
2543 * Function Name: Cy_SMIF_MemInitSfdpMode
2544 ****************************************************************************//**
2545 *
2546 * This function can be used for any preferred data width based command instruction set from SFDP Buffer.
2547 *
2548 * \param base
2549 * Holds the base address of the SMIF block registers.
2550 *
2551 * \param memCfg
2552 * The memory configuration structure that configures the SMIF memory device to
2553 * map into the device memory map. \ref cy_stc_smif_mem_config_t
2554 *
2555 * \param maxdataWidth
2556 * maximum data width available on physical interface.
2557 *
2558 * \param qer_id
2559 * Quad enable requirement ID specifically used for SFDP 1.0 compliant devices where
2560 * Quad mode is available for use, but SFDP basic flash parameter table does not specify
2561 * quad mode enable instruction. In other cases, this can be passed as CY_SMIF_SFDP_QER_0.
2562 *
2563 * \param context
2564 * This is the pointer to the context structure \ref cy_stc_smif_context_t
2565 * allocated by the user. The structure is used during the SMIF
2566 * operation for internal configuration and data retention. The user must not
2567 * modify anything in this structure.
2568 *
2569 * \return A status of the transmission.
2570 * - \ref CY_SMIF_SUCCESS
2571 * - \ref CY_SMIF_CMD_NOT_FOUND
2572 * - \ref CY_SMIF_SFDP_CORRUPTED_TABLE
2573 * - \ref CY_SMIF_EXCEED_TIMEOUT
2574 *
2575 * \snippet smif/snippet/main.c SMIF_INIT: SFDP
2576 *******************************************************************************/
2577
Cy_SMIF_MemInitSfdpMode(SMIF_Type * base,const cy_stc_smif_mem_config_t * memCfg,cy_en_smif_txfr_width_t maxdataWidth,cy_en_smif_qer_t qer_id,cy_stc_smif_context_t * context)2578 cy_en_smif_status_t Cy_SMIF_MemInitSfdpMode(SMIF_Type *base,
2579 const cy_stc_smif_mem_config_t *memCfg,
2580 cy_en_smif_txfr_width_t maxdataWidth,
2581 cy_en_smif_qer_t qer_id,
2582 cy_stc_smif_context_t *context)
2583 {
2584 /* Check the input parameters */
2585 CY_ASSERT_L1(NULL != memCfg);
2586 CY_ASSERT_L1(NULL != memCfg->deviceCfg);
2587
2588 uint8_t sfdpBuffer[CY_SMIF_SFDP_LENGTH];
2589 uint8_t sfdpAddress[CY_SMIF_SFDP_ADDRESS_LENGTH];
2590 uint8_t addr4ByteAddress[CY_SMIF_SFDP_ADDRESS_LENGTH];
2591 uint8_t sectorMapAddr[CY_SMIF_SFDP_ADDRESS_LENGTH];
2592 #if (CY_IP_MXSMIF_VERSION>=2) && defined (SMIF_OCTAL_SFDP_SUPPORT)
2593 uint8_t sccrMapAddr[CY_SMIF_SFDP_ADDRESS_LENGTH];
2594 uint8_t xSPiProfile1Addr[CY_SMIF_SFDP_ADDRESS_LENGTH];
2595 uint8_t cmdSeqODDRAddr[CY_SMIF_SFDP_ADDRESS_LENGTH];
2596 uint8_t cmdSeqODDRTableLength = 0U, sccrMapTableLength = 0U, xSPIProfile1TableLength = 0U;
2597 #endif
2598 cy_en_smif_status_t result = CY_SMIF_NO_SFDP_SUPPORT;
2599 cy_stc_smif_erase_type_t eraseType[ERASE_TYPE_COUNT];
2600 uint8_t basicSpiTableLength = 0U, addr4ByteTableLength = 0U, sectorMapTableLength = 0U;
2601 cy_stc_smif_mem_device_cfg_t *device = memCfg->deviceCfg;
2602 cy_en_smif_slave_select_t slaveSelect = memCfg->slaveSelect;
2603 cy_en_smif_data_select_t dataSelect = memCfg->dataSelect;
2604 cy_stc_smif_mem_cmd_t *cmdSfdp = device->readSfdpCmd;
2605
2606 /* Initialize the SFDP buffer */
2607 for (uint32_t i = 0U; i < CY_SMIF_SFDP_LENGTH; i++)
2608 {
2609 sfdpBuffer[i] = 0U;
2610 }
2611
2612 /* Initialize the SFDP Table addresses */
2613 for (uint8_t i = 0U; i < CY_SMIF_SFDP_ADDRESS_LENGTH; i++)
2614 {
2615 sfdpAddress[i] = 0U;
2616 addr4ByteAddress[i] = 0U;
2617 sectorMapAddr[i] = 0U;
2618 #if (CY_IP_MXSMIF_VERSION>=2) && defined (SMIF_OCTAL_SFDP_SUPPORT)
2619 sccrMapAddr[i] = 0U;
2620 xSPiProfile1Addr[i] = 0U;
2621 cmdSeqODDRAddr[i] = 0U;
2622 #endif
2623 }
2624 /* Slave slot initialization */
2625 Cy_SMIF_SetDataSelect(base, slaveSelect, dataSelect);
2626
2627 if (NULL != cmdSfdp)
2628 {
2629 /* Get the SDFP header and all parameter headers content into sfdpBuffer[] */
2630 result = SfdpReadBuffer(base, cmdSfdp, sfdpAddress, slaveSelect, HEADERS_LENGTH, sfdpBuffer, context);
2631 }
2632 else
2633 {
2634 result = CY_SMIF_NO_SFDP_SUPPORT;
2635 }
2636
2637 if((CY_SMIF_SUCCESS == result) &&
2638 (sfdpBuffer[CY_SMIF_SFDP_SIGNATURE_BYTE_00] == (uint8_t)'S') &&
2639 (sfdpBuffer[CY_SMIF_SFDP_SIGNATURE_BYTE_01] == (uint8_t)'F') &&
2640 (sfdpBuffer[CY_SMIF_SFDP_SIGNATURE_BYTE_02] == (uint8_t)'D') &&
2641 (sfdpBuffer[CY_SMIF_SFDP_SIGNATURE_BYTE_03] == (uint8_t)'P') &&
2642 (sfdpBuffer[CY_SMIF_SFDP_MAJOR_REV] == CY_SMIF_SFDP_MAJOR_REV_1))
2643 {
2644 uint8_t sfdp_minor_revision = sfdpBuffer[CY_SMIF_SFDP_MINOR_REV];
2645
2646 /* Find the JEDEC SFDP Basic SPI Flash Parameter Header */
2647 SfdpFindParameterTableAddress(BASIC_SPI_ID, sfdpBuffer, sfdpAddress, &basicSpiTableLength);
2648
2649 if (basicSpiTableLength > 0U)
2650 {
2651 SfdpFindParameterTableAddress(FOUR_BYTE_ADDR_ID, sfdpBuffer, addr4ByteAddress, &addr4ByteTableLength);
2652 SfdpFindParameterTableAddress(SECTOR_MAP_ID, sfdpBuffer, sectorMapAddr, §orMapTableLength);
2653
2654 #if (CY_IP_MXSMIF_VERSION>=2) && defined (SMIF_OCTAL_SFDP_SUPPORT)
2655 SfdpFindParameterTableAddress(SCCR_MAP_SPI_ID, sfdpBuffer, sccrMapAddr, &sccrMapTableLength);
2656 SfdpFindParameterTableAddress(XSPI_PROFILE_1_0_ID, sfdpBuffer, xSPiProfile1Addr, &xSPIProfile1TableLength);
2657 SfdpFindParameterTableAddress(CMD_SEQ_FOR_ODDR_ID, sfdpBuffer, cmdSeqODDRAddr, &cmdSeqODDRTableLength);
2658 #endif
2659 if (sectorMapTableLength == 0U)
2660 {
2661 device->hybridRegionCount = 0UL;
2662 device->hybridRegionInfo = NULL;
2663 result = CY_SMIF_SUCCESS; /* Not a Hybrid Memory */
2664 }
2665
2666 /* Check if any of the parameter table size is more than SFDP Buffer length reserved */
2667 if ((basicSpiTableLength > CY_SMIF_SFDP_LENGTH) ||
2668 (sectorMapTableLength > CY_SMIF_SFDP_LENGTH))
2669 {
2670 result = CY_SMIF_SFDP_BUFFER_INSUFFICIENT;
2671 }
2672 if (CY_SMIF_SUCCESS == result)
2673 {
2674 CY_ASSERT_L1(CY_SMIF_CHECK_DEVICE_MEMBERS(device));
2675
2676 /* Get the JEDEC basic flash parameter table content into sfdpBuffer[] */
2677 result = SfdpReadBuffer(base, cmdSfdp, sfdpAddress, slaveSelect, basicSpiTableLength, sfdpBuffer, context);
2678
2679 /* The erase size and erase time for all 4 erase types */
2680 SfdpGetEraseSizeAndCmd(sfdpBuffer, eraseType);
2681
2682 /* The external memory size */
2683 device->memSize = SfdpGetMemoryDensity(sfdpBuffer);
2684
2685 /* The number of address bytes used by the memory slave device */
2686 device->numOfAddrBytes = SfdpGetNumOfAddrBytes(sfdpBuffer, device->memSize);
2687
2688 /* The Write Enable command */
2689 SfdpSetWriteEnableCommand(device->writeEnCmd);
2690
2691 /* The Write Disable command */
2692 SfdpSetWriteDisableCommand(device->writeDisCmd);
2693
2694 /* The busy mask for the status registers */
2695 device->stsRegBusyMask = CY_SMIF_STATUS_REG_BUSY_MASK;
2696
2697 /* The command to read the WIP-containing status register */
2698 SfdpSetWipStatusRegisterCommand(device->readStsRegWipCmd);
2699
2700 if (maxdataWidth >= CY_SMIF_WIDTH_QUAD)
2701 {
2702 if(sfdp_minor_revision != CY_SMIF_SFDP_JEDEC_REV_0)
2703 {
2704 /* The command to write into the QE-containing status register */
2705 CY_MISRA_DEVIATE_BLOCK_START('MISRA C-2012 Rule 10.8', 1, 'integer to enum conversion intentional.')
2706 SfdpGetQuadEnableParameters(device,
2707 (cy_en_smif_qer_t)(_FLD2VAL(CY_SMIF_SFDP_QE_REQUIREMENTS,
2708 (uint32_t)sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_3A])));
2709 CY_MISRA_BLOCK_END('MISRA C-2012 Rule 10.8')
2710 }
2711 else
2712 {
2713 SfdpGetQuadEnableParameters(device, qer_id);
2714 }
2715 }
2716
2717 /* Chip Erase command */
2718 SfdpSetChipEraseCommand(device->chipEraseCmd);
2719
2720 /* The Read command for 3-byte addressing. The preference order quad > dual > single SPI */
2721 cy_stc_smif_mem_cmd_t *cmdRead = device->readCmd;
2722 cy_en_smif_protocol_mode_t pMode = PROTOCOL_MODE_WRONG;
2723
2724 if(sfdp_minor_revision != CY_SMIF_SFDP_JEDEC_REV_0)
2725 {
2726 /* The page size */
2727 device->programSize = SfdpGetPageSize(sfdpBuffer);
2728
2729 /* Chip Erase Time */
2730 device->chipEraseTime = SfdpGetChipEraseTime(sfdpBuffer);
2731
2732 /* Page Program Time */
2733 device->programTime = SfdpGetPageProgramTime(sfdpBuffer);
2734
2735 }
2736 else
2737 {
2738 /* The page size - Default value */
2739 device->programSize = CY_SMIF_SFDP_PAGE_SIZE_DEFAULT;
2740
2741 /* Chip Erase Time - Maximum value by default */
2742 device->chipEraseTime = CY_SMIF_SFDP_CHIP_ERASE_TIME_64S;
2743
2744 /* Page Program Time - Maximum value by default */
2745 device->programTime = CY_SMIF_SFDP_PROG_TIME_DEFAULT;
2746
2747 /* Enumerate Single SPI mode for SFDP 1.0 devices with QER 0 */
2748 if (qer_id == CY_SMIF_SFDP_QER_0)
2749 {
2750 maxdataWidth = CY_SMIF_WIDTH_SINGLE;
2751 }
2752 }
2753
2754 pMode = SfdpGetReadCmdParams(sfdpBuffer, dataSelect, maxdataWidth, cmdRead);
2755
2756 /* Read, Erase, and Program commands */
2757 uint32_t eraseTypeOffset = 1UL;
2758 if (FOUR_BYTE_ADDRESS == device->numOfAddrBytes)
2759 {
2760 /* Enter 4-byte addressing mode */
2761 result = SfdpEnterFourByteAddressing(base, sfdpBuffer[CY_SMIF_SFDP_BFPT_BYTE_3F], device, slaveSelect, context);
2762 uint8_t fourByteAddressBuffer[CY_SMIF_SFDP_LENGTH];
2763
2764 /* Initialize SFDP Buffer */
2765 for (uint32_t i = 0U; i < CY_SMIF_SFDP_LENGTH; i++)
2766 {
2767 fourByteAddressBuffer[i] = 0U;
2768 }
2769
2770 if (CY_SMIF_SUCCESS == result)
2771 {
2772 /* Get the JEDEC 4-byte Address Instruction Table content into sfdpBuffer[] */
2773 result = SfdpReadBuffer(base, cmdSfdp, addr4ByteAddress, slaveSelect,
2774 addr4ByteTableLength, fourByteAddressBuffer, context);
2775 }
2776 #if (CY_IP_MXSMIF_VERSION>=2) && defined (SMIF_OCTAL_SFDP_SUPPORT)
2777 /* Check if Octal mode related is supported first */
2778 if ((device->readStsRegOeCmd != NULL) && (device->writeStsRegOeCmd != NULL))
2779 {
2780 if ((CY_SMIF_SUCCESS == result) && (maxdataWidth == CY_SMIF_WIDTH_OCTAL))
2781 {
2782 cy_en_smif_protocol_mode_t octalProtocolMode = PROTOCOL_MODE_WRONG;
2783
2784 if ((cmdSeqODDRTableLength > 0U) && (xSPIProfile1TableLength > 0U) && (device->octalDDREnableSeq != NULL))
2785 {
2786 octalProtocolMode = GetOctalDDRParams(base, device, slaveSelect,
2787 cmdSeqODDRAddr, cmdSeqODDRTableLength,
2788 xSPiProfile1Addr, xSPIProfile1TableLength,
2789 sccrMapAddr, sccrMapTableLength,
2790 context);
2791 }
2792
2793 if(octalProtocolMode != PROTOCOL_MODE_8D_8D_8D) /* Check for Octal SDR if Octal DDR was not supported */
2794 {
2795 uint32_t octal_sdr_param = Cy_SMIF_PackBytesArray(fourByteAddressBuffer, true);
2796 octalProtocolMode = GetOctalSDRParams(base, sfdpBuffer, device, slaveSelect, octal_sdr_param,
2797 sccrMapAddr, sccrMapTableLength, context);
2798 }
2799
2800 if (octalProtocolMode != PROTOCOL_MODE_WRONG)
2801 {
2802 pMode = octalProtocolMode;
2803 }
2804 }
2805 else
2806 {
2807 device->writeStsRegOeCmd->command = CY_SMIF_NO_COMMAND_OR_MODE;
2808 device->readStsRegOeCmd->command = CY_SMIF_NO_COMMAND_OR_MODE;
2809 device->octalEnableRegAddr = CY_SMIF_NO_COMMAND_OR_MODE;
2810 device->stsRegOctalEnableMask = 0UL;
2811 device->writeStsRegOeCmd->cmdPresence = CY_SMIF_NOT_PRESENT;
2812 device->readStsRegOeCmd->cmdPresence = CY_SMIF_NOT_PRESENT;
2813 }
2814 }
2815 #endif
2816 if (CY_SMIF_SUCCESS == result)
2817 {
2818 /* Rewrite the Read command instruction for 4-byte addressing mode */
2819 SfdpGetReadFourBytesCmd(fourByteAddressBuffer, pMode, cmdRead);
2820
2821 /* Get the Program command instruction for 4-byte addressing mode */
2822 SfdpGetProgramFourBytesCmd(fourByteAddressBuffer, pMode, device->programCmd);
2823
2824 /* Find the sector Erase command type with 4-byte addressing */
2825 eraseTypeOffset = SfdpGetSectorEraseCommand(device, fourByteAddressBuffer, eraseType);
2826 }
2827 }
2828 else /* Four Byte addressing not supported by the part */
2829 {
2830 /* The program command for 3-byte addressing mode */
2831 SfdpSetProgramCommand_1_1_1(device->programCmd);
2832
2833 /* Find the sector Erase command type with 3-byte addressing */
2834 eraseTypeOffset = SfdpGetSectorEraseCommand(device, sfdpBuffer, eraseType);
2835 }
2836
2837 if (COMMAND_IS_NOT_FOUND != eraseTypeOffset)
2838 {
2839 /* The Erase sector size (from the JEDEC basic flash parameter table) */
2840 device->eraseSize = 0x01UL << sfdpBuffer[eraseTypeOffset - 1UL];
2841
2842 if(sfdp_minor_revision != CY_SMIF_SFDP_JEDEC_REV_0)
2843 {
2844 /* Erase Time Type (from the JEDEC basic flash parameter table) */
2845 device->eraseTime = SfdpGetEraseTime(eraseTypeOffset, sfdpBuffer, eraseType);
2846 }
2847 else
2848 {
2849 device->eraseTime = CY_SMIF_SFDP_ERASE_TIME_1S;
2850 }
2851 }
2852
2853 if (NULL != device->hybridRegionInfo)
2854 {
2855 /* Get the Sector Map Parameter Table into sfdpBuffer[] */
2856 result = SfdpReadBuffer(base, cmdSfdp, sectorMapAddr, slaveSelect,
2857 sectorMapTableLength, sfdpBuffer, context);
2858 if (CY_SMIF_SUCCESS == result)
2859 {
2860 result = SfdpPopulateRegionInfo(base, sfdpBuffer, sectorMapTableLength, device, slaveSelect, context, eraseType);
2861 if(result == CY_SMIF_NOT_HYBRID_MEM)
2862 {
2863 device->hybridRegionCount = 0UL;
2864 device->hybridRegionInfo = NULL;
2865 result = CY_SMIF_SUCCESS;
2866 }
2867 }
2868 }
2869 }
2870 }
2871 else
2872 {
2873 result = CY_SMIF_NO_SFDP_SUPPORT;
2874 }
2875 }
2876 else
2877 {
2878 result = CY_SMIF_NO_SFDP_SUPPORT;
2879 }
2880
2881 /* XIP and Device Register initialization */
2882 if ((CY_SMIF_SUCCESS == result) &&
2883 (0U != (memCfg->flags & CY_SMIF_FLAG_MEMORY_MAPPED)) &&
2884 (_FLD2VAL(SMIF_CTL_XIP_MODE, SMIF_CTL(base)) != 1U))
2885 {
2886 /* Check valid parameters for XIP */
2887 CY_ASSERT_L3(MEM_ADDR_VALID( memCfg->baseAddress, memCfg->memMappedSize));
2888 CY_ASSERT_L3(MEM_MAPPED_SIZE_VALID( memCfg->memMappedSize));
2889 SMIF_DEVICE_Type volatile * device_base = Cy_SMIF_GetDeviceBySlot(base, slaveSelect);
2890
2891 if (device_base != NULL)
2892 {
2893 XipRegInit(device_base, memCfg);
2894
2895 #if(CY_IP_MXSMIF_VERSION>=2)
2896 context->preXIPDataRate = memCfg->deviceCfg->readCmd->dataRate;
2897 #endif /* CY_IP_MXSMIF_VERSION */
2898 }
2899
2900 /* The device control register initialization */
2901 SMIF_DEVICE_CTL(device_base) = _VAL2FLD(SMIF_DEVICE_CTL_WR_EN, ((bool)(memCfg->flags & CY_SMIF_FLAG_WRITE_ENABLE))? 1U : 0U) |
2902 _VAL2FLD(SMIF_DEVICE_CTL_CRYPTO_EN, ((bool)(memCfg->flags & CY_SMIF_FLAG_CRYPTO_ENABLE))? 1U : 0U) |
2903 _VAL2FLD(SMIF_DEVICE_CTL_DATA_SEL, (uint32_t)memCfg->dataSelect) |
2904 #if(CY_IP_MXSMIF_VERSION>=2)
2905 _VAL2FLD(SMIF_DEVICE_CTL_MERGE_EN, ((bool)(memCfg->flags & CY_SMIF_FLAG_MERGE_ENABLE))? 1U : 0U) |
2906 _VAL2FLD(SMIF_DEVICE_CTL_MERGE_TIMEOUT, (uint32_t)memCfg->mergeTimeout) |
2907 #endif /* CY_IP_MXSMIF_VERSION */
2908 SMIF_DEVICE_CTL_ENABLED_Msk;
2909 }
2910
2911
2912 return(result);
2913 }
2914 /*******************************************************************************
2915 * Function Name: Cy_SMIF_MemSfdpDetect
2916 ****************************************************************************//**
2917 *
2918 * This function detects the device signature for SFDP devices.
2919 * Refer to the SFDP spec (JESD216B) for details.
2920 * The function asks the device using an SPI and then populates the relevant
2921 * parameters for \ref cy_stc_smif_mem_device_cfg_t.
2922 *
2923 * \note This function is a blocking function and blocks until the structure data
2924 * is read and returned. This function uses \ref Cy_SMIF_TransmitCommand()
2925 * If there is no support for SFDP in the memory device, the API returns an
2926 * error condition. The function requires:
2927 * - SMIF initialized and enabled to work in the normal mode;
2928 * - readSfdpCmd field of \ref cy_stc_smif_mem_device_cfg_t is enabled.
2929 *
2930 * \note The SFDP detect takes into account the types of the SPI supported by the
2931 * memory device and also the dataSelect option selected to choose which SPI mode
2932 * (SPI, DSPI, QSPI) to load into the structures. The algorithm prefers
2933 * QSPI>DSPI>SPI, provided there is support for it in the memory device and the
2934 * dataSelect selected by the user.
2935 *
2936 * \note 4-byte addressing mode is set when the memory device supports
2937 * 3- or 4-byte addressing mode.
2938 *
2939 * \note When the Erase command is not found the width of the command
2940 * transfer (cmdWidth) is set to CY_SMIF_WIDTH_NA. When the Program command
2941 * is not found for 4 byte addressing mode the Program command instruction
2942 * is set for 1S-1S-1S Protocol mode and 3-byte addressing mode.
2943 *
2944 * \param base
2945 * Holds the base address of the SMIF block registers.
2946 *
2947 * \param device
2948 * The device structure instance declared by the user. This is where the detected
2949 * parameters are stored and returned.
2950 *
2951 * \param slaveSelect
2952 * The slave select line for the device.
2953 *
2954 * \param dataSelect
2955 * The data line selection options for a slave device.
2956 *
2957 * \param context
2958 * This is the pointer to the context structure \ref cy_stc_smif_context_t
2959 * allocated by the user. The structure is used during the SMIF
2960 * operation for internal configuration and data retention. The user must not
2961 * modify anything in this structure.
2962 *
2963 * \return A status of the transmission.
2964 * - \ref CY_SMIF_SUCCESS
2965 * - \ref CY_SMIF_CMD_FIFO_FULL
2966 * - \ref CY_SMIF_NO_SFDP_SUPPORT
2967 * - \ref CY_SMIF_EXCEED_TIMEOUT
2968 *
2969 *******************************************************************************/
Cy_SMIF_MemSfdpDetect(SMIF_Type * base,cy_stc_smif_mem_device_cfg_t * device,cy_en_smif_slave_select_t slaveSelect,cy_en_smif_data_select_t dataSelect,cy_stc_smif_context_t * context)2970 cy_en_smif_status_t Cy_SMIF_MemSfdpDetect(SMIF_Type *base,
2971 cy_stc_smif_mem_device_cfg_t *device,
2972 cy_en_smif_slave_select_t slaveSelect,
2973 cy_en_smif_data_select_t dataSelect,
2974 cy_stc_smif_context_t *context)
2975 {
2976
2977 /* Check the input parameters */
2978 CY_ASSERT_L1(NULL != device);
2979
2980 cy_stc_smif_mem_config_t memSfdpDetect =
2981 {
2982 .slaveSelect = slaveSelect,
2983 .flags = 0,
2984 .dataSelect = dataSelect,
2985 .baseAddress = 0U,
2986 .memMappedSize = 0U,
2987 .dualQuadSlots = 0,
2988 .deviceCfg = device,
2989 #if (CY_IP_MXSMIF_VERSION >= 3)
2990 .mergeTimeout = CY_SMIF_MERGE_TIMEOUT_1_CYCLE
2991 #endif /* CY_IP_MXSMIF_VERSION */
2992 };
2993
2994 return Cy_SMIF_MemInitSfdpMode(base, &memSfdpDetect, CY_SMIF_WIDTH_OCTAL, CY_SMIF_SFDP_QER_0, context);
2995 }
2996
2997 #if defined(__cplusplus)
2998 }
2999 #endif
3000
3001 #endif /* CY_IP_MXSMIF */
3002
3003 /* [] END OF FILE */
3004