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