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