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