1 /*
2  * Copyright 2018-2021 NXP
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  */
7 
8 #ifndef __FSL_IAP_H_
9 #define __FSL_IAP_H_
10 
11 #include "fsl_common.h"
12 /*!
13  * @addtogroup IAP_driver
14  * @{
15  */
16 
17 /*! @file */
18 
19 /*******************************************************************************
20  * Definitions
21  ******************************************************************************/
22 /*! @name Driver version */
23 /*@{*/
24 /*! @brief IAP driver version 2.1.2. */
25 #define FSL_IAP_DRIVER_VERSION (MAKE_VERSION(2, 1, 2))
26 /*@}*/
27 
28 /*!
29  * @addtogroup iap_flexspi_driver
30  * @{
31  */
32 
33 /*! @brief FlexSPI LUT command */
34 
35 #define NOR_CMD_INDEX_READ        0 /*!< 0 */
36 #define NOR_CMD_INDEX_READSTATUS  1 /*!< 1 */
37 #define NOR_CMD_INDEX_WRITEENABLE 2 /*!< 2 */
38 #define NOR_CMD_INDEX_ERASESECTOR 3 /*!< 3 */
39 #define NOR_CMD_INDEX_PAGEPROGRAM 4 /*!< 4 */
40 #define NOR_CMD_INDEX_CHIPERASE   5 /*!< 5 */
41 #define NOR_CMD_INDEX_DUMMY       6 /*!< 6 */
42 #define NOR_CMD_INDEX_ERASEBLOCK  7 /*!< 7 */
43 
44 #define NOR_CMD_LUT_SEQ_IDX_READ       0 /*!< 0  READ LUT sequence id in lookupTable stored in config block */
45 #define NOR_CMD_LUT_SEQ_IDX_READSTATUS 1 /*!< 1  Read Status LUT sequence id in lookupTable stored in config block */
46 #define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \
47     2 /*!< 2  Read status DPI/QPI/OPI sequence id in lookupTable stored in config block */
48 #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE 3 /*!< 3  Write Enable sequence id in lookupTable stored in config block */
49 #define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \
50     4 /*!< 4  Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block */
51 #define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5  /*!< 5  Erase Sector sequence id in lookupTable stored in config block */
52 #define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK  8  /*!< 8 Erase Block sequence id in lookupTable stored in config block */
53 #define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM 9  /*!< 9  Program sequence id in lookupTable stored in config block */
54 #define NOR_CMD_LUT_SEQ_IDX_CHIPERASE   11 /*!< 11 Chip Erase sequence in lookupTable id stored in config block */
55 #define NOR_CMD_LUT_SEQ_IDX_READ_SFDP   13 /*!< 13 Read SFDP sequence in lookupTable id stored in config block */
56 #define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \
57     14 /*!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block */
58 #define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \
59     15 /*!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk */
60 
61 /*!
62  * @name FlexSPI status.
63  * @{
64  */
65 /*! @brief FlexSPI Driver status group. */
66 enum
67 {
68     kStatusGroup_FlexSPI    = 60,
69     kStatusGroup_FlexSPINOR = 201,
70 };
71 
72 /*! @brief FlexSPI Driver status. */
73 enum _flexspi_status
74 {
75     kStatus_FLEXSPI_Success         = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< API is executed successfully*/
76     kStatus_FLEXSPI_Fail            = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< API is executed fails*/
77     kStatus_FLEXSPI_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< Invalid argument*/
78     kStatus_FLEXSPI_SequenceExecutionTimeout =
79         MAKE_STATUS(kStatusGroup_FlexSPI, 0), /*!< The FlexSPI Sequence Execution timeout*/
80     kStatus_FLEXSPI_InvalidSequence = MAKE_STATUS(kStatusGroup_FlexSPI, 1), /*!< The FlexSPI LUT sequence invalid*/
81     kStatus_FLEXSPI_DeviceTimeout   = MAKE_STATUS(kStatusGroup_FlexSPI, 2), /*!< The FlexSPI device timeout*/
82     kStatus_FLEXSPINOR_ProgramFail =
83         MAKE_STATUS(kStatusGroup_FlexSPINOR, 0), /*!< Status for Page programming failure */
84     kStatus_FLEXSPINOR_EraseSectorFail =
85         MAKE_STATUS(kStatusGroup_FlexSPINOR, 1),                               /*!< Status for Sector Erase failure */
86     kStatus_FLEXSPINOR_EraseAllFail = MAKE_STATUS(kStatusGroup_FlexSPINOR, 2), /*!< Status for Chip Erase failure */
87     kStatus_FLEXSPINOR_WaitTimeout  = MAKE_STATUS(kStatusGroup_FlexSPINOR, 3), /*!< Status for timeout */
88     kStatus_FLEXSPINOR_NotSupported = MAKE_STATUS(kStatusGroup_FlexSPINOR, 4), /*  Status for PageSize overflow */
89     kStatus_FLEXSPINOR_WriteAlignmentError =
90         MAKE_STATUS(kStatusGroup_FlexSPINOR, 5), /*!< Status for Alignement error */
91     kStatus_FLEXSPINOR_CommandFailure =
92         MAKE_STATUS(kStatusGroup_FlexSPINOR, 6), /*!< Status for Erase/Program Verify Error */
93     kStatus_FLEXSPINOR_SFDP_NotFound = MAKE_STATUS(kStatusGroup_FlexSPINOR, 7), /*!< Status for SFDP read failure */
94     kStatus_FLEXSPINOR_Unsupported_SFDP_Version =
95         MAKE_STATUS(kStatusGroup_FlexSPINOR, 8), /*!< Status for Unrecognized SFDP version */
96     kStatus_FLEXSPINOR_Flash_NotFound =
97         MAKE_STATUS(kStatusGroup_FlexSPINOR, 9), /*!< Status for Flash detection failure */
98     kStatus_FLEXSPINOR_DTRRead_DummyProbeFailed =
99         MAKE_STATUS(kStatusGroup_FlexSPINOR, 10), /*!< Status for DDR Read dummy probe failure */
100 };
101 /*! @} */
102 
103 /*! @brief Flash Configuration Option0 device_type. */
104 enum
105 {
106     kSerialNorCfgOption_Tag                         = 0x0c,
107     kSerialNorCfgOption_DeviceType_ReadSFDP_SDR     = 0,
108     kSerialNorCfgOption_DeviceType_ReadSFDP_DDR     = 1,
109     kSerialNorCfgOption_DeviceType_HyperFLASH1V8    = 2,
110     kSerialNorCfgOption_DeviceType_HyperFLASH3V0    = 3,
111     kSerialNorCfgOption_DeviceType_MacronixOctalDDR = 4,
112     kSerialNorCfgOption_DeviceType_MacronixOctalSDR = 5, /* For RT600 devcies only. */
113     kSerialNorCfgOption_DeviceType_MicronOctalDDR   = 6,
114     kSerialNorCfgOption_DeviceType_MicronOctalSDR   = 7, /* For RT600 devcies only. */
115     kSerialNorCfgOption_DeviceType_AdestoOctalDDR   = 8,
116     kSerialNorCfgOption_DeviceType_AdestoOctalSDR   = 9, /* For RT600 devcies only. */
117 };
118 
119 /*! @brief Flash Configuration Option0 quad_mode_setting. */
120 enum
121 {
122     kSerialNorQuadMode_NotConfig            = 0,
123     kSerialNorQuadMode_StatusReg1_Bit6      = 1,
124     kSerialNorQuadMode_StatusReg2_Bit1      = 2,
125     kSerialNorQuadMode_StatusReg2_Bit7      = 3,
126     kSerialNorQuadMode_StatusReg2_Bit1_0x31 = 4,
127 };
128 
129 /*! @brief Flash Configuration Option0 misc_mode. */
130 enum
131 {
132     kSerialNorEnhanceMode_Disabled         = 0,
133     kSerialNorEnhanceMode_0_4_4_Mode       = 1,
134     kSerialNorEnhanceMode_0_8_8_Mode       = 2,
135     kSerialNorEnhanceMode_DataOrderSwapped = 3,
136     kSerialNorEnhanceMode_2ndPinMux        = 4,
137 };
138 
139 /*! @brief FLEXSPI_RESET_PIN boot configurations in OTP */
140 enum
141 {
142     kFlashResetLogic_Disabled     = 0,
143     kFlashResetLogic_ResetPin     = 1,
144     kFlashResetLogic_JedecHwReset = 2,
145 };
146 
147 /*! @brief Flash Configuration Option1 flash_connection. */
148 enum
149 {
150     kSerialNorConnection_SinglePortA,
151     kSerialNorConnection_Parallel,
152     kSerialNorConnection_SinglePortB,
153     kSerialNorConnection_BothPorts
154 };
155 
156 /*! @brief Serial NOR Configuration Option */
157 typedef struct _serial_nor_config_option
158 {
159     union
160     {
161         struct
162         {
163             uint32_t max_freq : 4;          /*!< Maximum supported Frequency */
164             uint32_t misc_mode : 4;         /*!< miscellaneous mode */
165             uint32_t quad_mode_setting : 4; /*!< Quad mode setting */
166             uint32_t cmd_pads : 4;          /*!< Command pads */
167             uint32_t query_pads : 4;        /*!< SFDP read pads */
168             uint32_t device_type : 4;       /*!< Device type */
169             uint32_t option_size : 4;       /*!< Option size, in terms of uint32_t, size = (option_size + 1) * 4 */
170             uint32_t tag : 4;               /*!< Tag, must be 0x0E */
171         } B;
172         uint32_t U;
173     } option0;
174 
175     union
176     {
177         struct
178         {
179             uint32_t dummy_cycles : 8;     /*!< Dummy cycles before read */
180             uint32_t status_override : 8;  /*!< Override status register value during device mode configuration */
181             uint32_t pinmux_group : 4;     /*!< The pinmux group selection */
182             uint32_t dqs_pinmux_group : 4; /*!< The DQS Pinmux Group Selection */
183             uint32_t drive_strength : 4;   /*!< The Drive Strength of FlexSPI Pads */
184             uint32_t flash_connection : 4; /*!< Flash connection option: 0 - Single Flash connected to port A, 1 - */
185             /*! Parallel mode, 2 - Single Flash connected to Port B */
186         } B;
187         uint32_t U;
188     } option1;
189 
190 } serial_nor_config_option_t;
191 
192 /*! @brief Flash Run Context */
193 typedef union
194 {
195     struct
196     {
197         uint8_t por_mode;
198         uint8_t current_mode;
199         uint8_t exit_no_cmd_sequence;
200         uint8_t restore_sequence;
201     } B;
202     uint32_t U;
203 } flash_run_context_t;
204 
205 /*!@brief Flash Device Mode Configuration Sequence */
206 enum
207 {
208     kRestoreSequence_None           = 0,
209     kRestoreSequence_HW_Reset       = 1,
210     kRestoreSequence_4QPI_FF        = 2,
211     kRestoreSequence_5QPI_FF        = 3,
212     kRestoreSequence_8QPI_FF        = 4,
213     kRestoreSequence_Send_F0        = 5,
214     kRestoreSequence_Send_66_99     = 6,
215     kRestoreSequence_Send_6699_9966 = 7,
216     kRestoreSequence_Send_06_FF     = 8, /*  Adesto EcoXIP */
217 };
218 
219 /*!@brief Flash Config Mode Definition */
220 enum
221 {
222     kFlashInstMode_ExtendedSpi = 0x00,
223     kFlashInstMode_0_4_4_SDR   = 0x01,
224     kFlashInstMode_0_4_4_DDR   = 0x02,
225     kFlashInstMode_QPI_SDR     = 0x41,
226     kFlashInstMode_QPI_DDR     = 0x42,
227     kFlashInstMode_OPI_SDR     = 0x81, /* For RT600 devices only. */
228     kFlashInstMode_OPI_DDR     = 0x82,
229 };
230 
231 /*!@brief Flash Device Type Definition */
232 enum
233 {
234     kFlexSpiDeviceType_SerialNOR    = 1,    /*!< Flash devices are Serial NOR */
235     kFlexSpiDeviceType_SerialNAND   = 2,    /*!< Flash devices are Serial NAND */
236     kFlexSpiDeviceType_SerialRAM    = 3,    /*!< Flash devices are Serial RAM/HyperFLASH */
237     kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, /*!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND */
238     kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, /*!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs */
239 };
240 
241 /*!@brief Flash Pad Definitions */
242 enum
243 {
244     kSerialFlash_1Pad  = 1,
245     kSerialFlash_2Pads = 2,
246     kSerialFlash_4Pads = 4,
247     kSerialFlash_8Pads = 8,
248 };
249 
250 /*!@brief FlexSPI LUT Sequence structure */
251 typedef struct _lut_sequence
252 {
253     uint8_t seqNum; /*!< Sequence Number, valid number: 1-16 */
254     uint8_t seqId;  /*!< Sequence Index, valid number: 0-15 */
255     uint16_t reserved;
256 } flexspi_lut_seq_t;
257 
258 /*!@brief Flash Configuration Command Type */
259 enum
260 {
261     kDeviceConfigCmdType_Generic,    /*!< Generic command, for example: configure dummy cycles, drive strength, etc */
262     kDeviceConfigCmdType_QuadEnable, /*!< Quad Enable command */
263     kDeviceConfigCmdType_Spi2Xpi,    /*!< Switch from SPI to DPI/QPI/OPI mode */
264     kDeviceConfigCmdType_Xpi2Spi,    /*!< Switch from DPI/QPI/OPI to SPI mode */
265     kDeviceConfigCmdType_Spi2NoCmd,  /*!< Switch to 0-4-4/0-8-8 mode */
266     kDeviceConfigCmdType_Reset,      /*!< Reset device command */
267 };
268 
269 /*!@brief FlexSPI Dll Time Block */
270 typedef struct
271 {
272     uint8_t time_100ps;  /* Data valid time, in terms of 100ps */
273     uint8_t delay_cells; /* Data valid time, in terms of delay cells */
274 } flexspi_dll_time_t;
275 
276 /*!@brief FlexSPI Memory Configuration Block */
277 typedef struct _FlexSPIConfig
278 {
279     uint32_t tag;       /*!< [0x000-0x003] Tag, fixed value 0x42464346UL */
280     uint32_t version;   /*!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix */
281     uint32_t reserved0; /*!< [0x008-0x00b] Reserved for future use */
282     uint8_t readSampleClkSrc;   /*!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 */
283     uint8_t csHoldTime;         /*!< [0x00d-0x00d] CS hold time, default value: 3 */
284     uint8_t csSetupTime;        /*!< [0x00e-0x00e] CS setup time, default value: 3 */
285     uint8_t columnAddressWidth; /*!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For */
286     /*! Serial NAND, need to refer to datasheet */
287     uint8_t deviceModeCfgEnable; /*!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable */
288     uint8_t
289         deviceModeType; /*!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, */
290     /*! Generic configuration, etc. */
291     uint16_t waitTimeCfgCommands; /*!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for */
292     /*! DPI/QPI/OPI switch or reset command */
293     flexspi_lut_seq_t
294         deviceModeSeq; /*!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt */
295     /*! sequence number, [31:16] Reserved */
296     uint32_t deviceModeArg;    /*!< [0x018-0x01b] Argument/Parameter for device configuration */
297     uint8_t configCmdEnable;   /*!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable */
298     uint8_t configModeType[3]; /*!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe */
299     flexspi_lut_seq_t
300         configCmdSeqs[3]; /*!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq */
301     uint32_t reserved1;   /*!< [0x02c-0x02f] Reserved for future use */
302     uint32_t configCmdArgs[3]; /*!< [0x030-0x03b] Arguments/Parameters for device Configuration commands */
303     uint32_t reserved2;        /*!< [0x03c-0x03f] Reserved for future use */
304     uint32_t
305         controllerMiscOption; /*!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more */
306     /*! details */
307     uint8_t deviceType;    /*!< [0x044-0x044] Device Type:  See Flash Type Definition for more details */
308     uint8_t sflashPadType; /*!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal */
309     uint8_t serialClkFreq; /*!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot */
310     /*! Chapter for more details */
311     uint8_t
312         lutCustomSeqEnable; /*!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot */
313     /*! be done using 1 LUT sequence, currently, only applicable to HyperFLASH */
314     uint32_t reserved3[2];               /*!< [0x048-0x04f] Reserved for future use */
315     uint32_t sflashA1Size;               /*!< [0x050-0x053] Size of Flash connected to A1 */
316     uint32_t sflashA2Size;               /*!< [0x054-0x057] Size of Flash connected to A2 */
317     uint32_t sflashB1Size;               /*!< [0x058-0x05b] Size of Flash connected to B1 */
318     uint32_t sflashB2Size;               /*!< [0x05c-0x05f] Size of Flash connected to B2 */
319     uint32_t csPadSettingOverride;       /*!< [0x060-0x063] CS pad setting override value */
320     uint32_t sclkPadSettingOverride;     /*!< [0x064-0x067] SCK pad setting override value */
321     uint32_t dataPadSettingOverride;     /*!< [0x068-0x06b] data pad setting override value */
322     uint32_t dqsPadSettingOverride;      /*!< [0x06c-0x06f] DQS pad setting override value */
323     uint32_t timeoutInMs;                /*!< [0x070-0x073] Timeout threshold for read status command */
324     uint32_t commandInterval;            /*!< [0x074-0x077] CS deselect interval between two commands */
325     flexspi_dll_time_t dataValidTime[2]; /*!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B */
326     uint16_t busyOffset;                 /*!< [0x07c-0x07d] Busy offset, valid value: 0-31 */
327     uint16_t
328         busyBitPolarity; /*!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - */
329     /*! busy flag is 0 when flash device is busy */
330     uint32_t lookupTable[64];           /*!< [0x080-0x17f] Lookup table holds Flash command sequences */
331     flexspi_lut_seq_t lutCustomSeq[12]; /*!< [0x180-0x1af] Customizable LUT Sequences */
332     uint32_t reserved4[4];              /*!< [0x1b0-0x1bf] Reserved for future use */
333 } flexspi_mem_config_block_t;
334 
335 /*!@brief FlexSPI Operation Type */
336 typedef enum _FlexSPIOperationType
337 {
338     kFlexSpiOperation_Command = 0, /*!< FlexSPI operation: Only command, both TX and */
339     /*! RX buffer are ignored. */
340     kFlexSpiOperation_Config = 1, /*!< FlexSPI operation: Configure device mode, the */
341     /*! TX FIFO size is fixed in LUT. */
342     kFlexSpiOperation_Write = 2, /*!< FlexSPI operation: Write,  only TX buffer is */
343     /*! effective */
344     kFlexSpiOperation_Read = 3, /*!< FlexSPI operation: Read, only Rx Buffer is */
345     /*! effective. */
346     kFlexSpiOperation_End = kFlexSpiOperation_Read,
347 } flexspi_operation_t;
348 
349 /*!@brief FlexSPI Transfer Context */
350 typedef struct _FlexSpiXfer
351 {
352     flexspi_operation_t operation; /*!< FlexSPI operation */
353     uint32_t baseAddress;          /*!< FlexSPI operation base address */
354     uint32_t seqId;                /*!< Sequence Id */
355     uint32_t seqNum;               /*!< Sequence Number */
356     bool isParallelModeEnable;     /*!< Is a parallel transfer */
357     uint32_t *txBuffer;            /*!< Tx buffer */
358     uint32_t txSize;               /*!< Tx size in bytes */
359     uint32_t *rxBuffer;            /*!< Rx buffer */
360     uint32_t rxSize;               /*!< Rx size in bytes */
361 } flexspi_xfer_t;
362 
363 /*!@brief Serial NOR configuration block */
364 typedef struct _flexspi_nor_config
365 {
366     flexspi_mem_config_block_t memConfig; /*!< Common memory configuration info via FlexSPI */
367     uint32_t pageSize;                    /*!< Page size of Serial NOR */
368     uint32_t sectorSize;                  /*!< Sector size of Serial NOR */
369     uint8_t ipcmdSerialClkFreq;           /*!< Clock frequency for IP command */
370     uint8_t isUniformBlockSize;           /*!< Sector/Block size is the same */
371     uint8_t isDataOrderSwapped;           /*!< Data order (D0, D1, D2, D3) is swapped (D1,D0, D3, D2) */
372     uint8_t reserved0[1];                 /*!< Reserved for future use */
373     uint8_t serialNorType;                /*!< Serial NOR Flash type: 0/1/2/3 */
374     uint8_t needExitNoCmdMode;            /*!< Need to exit NoCmd mode before other IP command */
375     uint8_t halfClkForNonReadCmd;         /*!< Half the Serial Clock for non-read command: true/false */
376     uint8_t needRestoreNoCmdMode;         /*!< Need to Restore NoCmd mode after IP commmand execution */
377     uint32_t blockSize;                   /*!< Block size */
378     uint32_t flashStateCtx;               /*!< Flash State Context */
379     uint32_t reserve2[10];                /*!< Reserved for future use */
380 } flexspi_nor_config_t;
381 /*! @} */
382 
383 /*!
384  * @addtogroup iap_otp_driver
385  * @{
386  */
387 
388 /*! @brief OTP Status Group */
389 enum
390 {
391     kStatusGroup_OtpGroup = 0x210,
392 };
393 
394 /*! @brief OTP Error Status definitions */
395 enum
396 {
397     kStatus_OTP_InvalidAddress = MAKE_STATUS(kStatusGroup_OtpGroup, 1), /*!< Invalid OTP address */
398     kStatus_OTP_ProgramFail    = MAKE_STATUS(kStatusGroup_OtpGroup, 2), /*!< Program Fail */
399     kStatus_OTP_CrcFail        = MAKE_STATUS(kStatusGroup_OtpGroup, 3), /*!< CrcCheck Fail */
400     kStatus_OTP_Error          = MAKE_STATUS(kStatusGroup_OtpGroup, 4), /*!< Errors happened during OTP operation */
401     kStatus_OTP_EccCheckFail   = MAKE_STATUS(kStatusGroup_OtpGroup, 5), /*!< Ecc Check failed during OTP operation */
402     kStatus_OTP_Locked         = MAKE_STATUS(kStatusGroup_OtpGroup, 6), /*!< OTP Fuse field has been locked */
403     kStatus_OTP_Timeout        = MAKE_STATUS(kStatusGroup_OtpGroup, 7), /*!< OTP operation time out */
404     kStatus_OTP_CrcCheckPass   = MAKE_STATUS(kStatusGroup_OtpGroup, 8), /*!< OTP CRC Check Pass */
405 };
406 /*! @} */
407 
408 /*!
409  * @addtogroup iap_boot_driver
410  * @{
411  */
412 
413 /*! @brief IAP boot option. */
414 typedef struct _iap_boot_option
415 {
416     union
417     {
418         struct
419         {
420             uint32_t reserved : 8;       /*! reserved field. */
421             uint32_t bootImageIndex : 4; /*! FlexSPI boot image index for FlexSPI NOR flash. */
422             uint32_t instance : 4;       /*! Only used when boot interface is FlexSPI/SD/MMC. */
423             uint32_t bootInterface : 4;  /*! RT500: 0: USART 2: SPI 3: USB HID 4:FlexSPI 6:SD 7:MMC.
424                                              RT600: 0: USART 1: I2C 2: SPI 3: USB HID 4:FlexSPI 7:SD 8:MMC*/
425             uint32_t mode : 4;           /* boot mode, 0: Master boot mode; 1: ISP boot */
426             uint32_t tag : 8;            /*! tag, should always be "0xEB". */
427         } B;
428         uint32_t U;
429     } option;
430 } iap_boot_option_t;
431 
432 /*! IAP boot option tag */
433 #define IAP_BOOT_OPTION_TAG (0xEBU)
434 /*! IAP boot option mode */
435 #define IAP_BOOT_OPTION_MODE_MASTER (0U)
436 #define IAP_BOOT_OPTION_MODE_ISP    (1U)
437 
438 /*! @} */
439 
440 /*******************************************************************************
441  * API
442  ******************************************************************************/
443 #if defined(__cplusplus)
444 extern "C" {
445 #endif
446 
447 /*!
448  * @addtogroup iap_boot_driver
449  * @{
450  */
451 
452 /*!
453  * @brief Invoke into ROM with specified boot parameters.
454  *
455  * @param option Boot parameters. Refer to #iap_boot_option_t.
456  */
457 void IAP_RunBootLoader(iap_boot_option_t *option);
458 /*! @} */
459 
460 /*!
461  * @addtogroup iap_flexspi_driver
462  * @{
463  */
464 
465 /*!
466  * @brief Initialize Serial NOR devices via FlexSPI.
467  *
468  * This function configures the FlexSPI controller with the arguments pointed by param config.
469  *
470  * @param instance FlexSPI controller instance, only support 0.
471  * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
472  * @return The status flags. This is a member of the
473  *         enumeration ::_flexspi_status
474  */
475 #if defined(DOXYGEN_OUTPUT) && DOXYGEN_OUTPUT
476 status_t IAP_FlexspiNorInit(uint32_t instance, flexspi_nor_config_t *config);
477 #else
478 AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorInit(uint32_t instance, flexspi_nor_config_t *config));
479 #endif
480 
481 /*!
482  * @brief Program data to Serial NOR via FlexSPI.
483  *
484  * This function Program data to specified destination address.
485  *
486  * @param instance FlexSPI controller instance, only support 0.
487  * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
488  * @param dstAddr The destination address to be programmed.
489  * @param src Points to the buffer which hold the data to be programmed.
490  * @return The status flags. This is a member of the
491  *         enumeration ::_flexspi_status
492  */
493 status_t IAP_FlexspiNorPageProgram(uint32_t instance,
494                                    flexspi_nor_config_t *config,
495                                    uint32_t dstAddr,
496                                    const uint32_t *src);
497 
498 /*!
499  * @brief Erase all the Serial NOR devices connected on FlexSPI.
500  *
501  * @param instance FlexSPI controller instance, only support 0.
502  * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
503  * @return The status flags. This is a member of the
504  *         enumeration ::_flexspi_status
505  */
506 status_t IAP_FlexspiNorEraseAll(uint32_t instance, flexspi_nor_config_t *config);
507 
508 /*!
509  * @brief Erase Flash Region specified by address and length.
510  *
511  * @param instance FlexSPI controller instance, only support 0.
512  * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
513  * @param start The start address to be erased.
514  * @param length The length to be erased.
515  * @return The status flags. This is a member of the
516  *         enumeration ::_flexspi_status
517  */
518 status_t IAP_FlexspiNorErase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);
519 
520 /*!
521  * @brief Erase one sector specified by address.
522  *
523  * @param instance FlexSPI controller instance, only support 0.
524  * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
525  * @param address The address of the sector to be erased.
526  * @return The status flags. This is a member of the
527  *         enumeration ::_flexspi_status
528  */
529 status_t IAP_FlexspiNorEraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
530 
531 /*!
532  * @brief Erase one block specified by address.
533  *
534  * @param instance FlexSPI controller instance, only support 0.
535  * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
536  * @param address The address of the block to be erased.
537  * @return The status flags. This is a member of the
538  *         enumeration ::_flexspi_status
539  */
540 status_t IAP_FlexspiNorEraseBlock(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);
541 
542 /*!
543  * @brief Get FlexSPI NOR Configuration Block based on specified option.
544  *
545  * @param instance FlexSPI controller instance, only support 0.
546  * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
547  * @param option The Flash Configuration Option block. Refer to #serial_nor_config_option_t.
548  * @return The status flags. This is a member of the
549  *         enumeration ::_flexspi_status
550  */
551 status_t IAP_FlexspiNorGetConfig(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
552 
553 /*!
554  * @brief Read data from Flexspi NOR Flash.
555  *
556  * @param instance FlexSPI controller instance, only support 0.
557  * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
558  * @param dst Buffer address used to store the read data.
559  * @param start The Read address.
560  * @param bytes The Read size
561  * @return The status flags. This is a member of the
562  *         enumeration ::_flexspi_status
563  */
564 status_t IAP_FlexspiNorRead(
565     uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes);
566 
567 /*!
568  * @brief Get FlexSPI Xfer data.
569  *
570  * @param instance FlexSPI controller instance, only support 0.
571  * @param xfer The FlexSPI Transfer Context block. Refer to #flexspi_xfer_t.
572  * @return The status flags. This is a member of the
573  *         enumeration ::_flexspi_status
574  */
575 status_t IAP_FlexspiXfer(uint32_t instance, flexspi_xfer_t *xfer);
576 
577 /*!
578  * @brief Update FlexSPI Lookup table.
579  *
580  * @param instance FlexSPI controller instance, only support 0.
581  * @param seqIndex The index of FlexSPI LUT to be updated.
582  * @param lutBase Points to the buffer which hold the LUT data to be programmed.
583  * @param numberOfSeq The number of LUT seq that need to be updated.
584  * @return The status flags. This is a member of the
585  *         enumeration ::_flexspi_status
586  */
587 status_t IAP_FlexspiUpdateLut(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq);
588 
589 /*!
590  * @brief Set the clock source for FlexSPI.
591  *
592  * @param clockSrc Clock source for flexspi interface.
593  * @return The status flags. This is a member of the
594  *         enumeration ::_flexspi_status
595  */
596 status_t IAP_FlexspiSetClockSource(uint32_t clockSrc);
597 
598 /*!
599  * @brief Configure the flexspi interface clock frequency and data sample mode.
600  *
601  * @param instance FlexSPI controller instance, only support 0.
602  * @param freqOption FlexSPI interface clock frequency selection.
603  * @param sampleClkMode FlexSPI controller data sample mode.
604  * @return The status flags. This is a member of the
605  *         enumeration ::_flexspi_status
606  */
607 void IAP_FlexspiConfigClock(uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode);
608 
609 /*!
610  * @brief Configure flexspi nor automatically.
611  *
612  * @param instance FlexSPI controller instance, only support 0.
613  * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
614  * @param option The Flash Configuration Option block. Refer to #serial_nor_config_option_t.
615  * @return The status flags. This is a member of the
616  *         enumeration ::_flexspi_status
617  */
618 #if defined(DOXYGEN_OUTPUT) && DOXYGEN_OUTPUT
619 status_t IAP_FlexspiNorAutoConfig(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
620 #else
621 AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorAutoConfig(uint32_t instance,
622                                                               flexspi_nor_config_t *config,
623                                                               serial_nor_config_option_t *option));
624 #endif
625 /*! @} */
626 
627 /*!
628  * @addtogroup iap_otp_driver
629  * @{
630  */
631 
632 /*!
633  * @brief Initialize OTP controller
634  *
635  * This function enables OTP Controller clock.
636  *
637  * @param src_clk_freq The Frequency of the source clock of OTP controller
638  * @return kStatus_Success
639  */
640 status_t IAP_OtpInit(uint32_t src_clk_freq);
641 
642 /*!
643  * @brief De-Initialize OTP controller
644  *
645  * This functin disables OTP Controller Clock.
646  * @return kStatus_Success
647  */
648 status_t IAP_OtpDeinit(void);
649 
650 /*!
651  * @brief Read Fuse value from OTP Fuse Block
652  *
653  * This function read fuse data from OTP Fuse block to specified data buffer.
654  *
655  * @param addr Fuse address
656  * @param data Buffer to hold the data read from OTP Fuse block
657  * @return kStatus_Success - Data read from OTP Fuse block successfully
658  *         kStatus_InvalidArgument - data pointer is invalid
659  *         kStatus_OTP_EccCheckFail - Ecc Check Failed
660  *         kStatus_OTP_Error - Other Errors
661  */
662 status_t IAP_OtpFuseRead(uint32_t addr, uint32_t *data);
663 
664 /*!
665  * @brief Program value to OTP Fuse block
666  *
667  * This function program data to specified OTP Fuse address.
668  *
669  * @param addr Fuse address
670  * @param data data to be programmed into OTP Fuse block
671  * @param lock lock the fuse field or not
672  * @return kStatus_Success - Data has been programmed into OTP Fuse block successfully
673  *         kStatus_OTP_ProgramFail - Fuse programming failed
674  *         kStatus_OTP_Locked - The address to be programmed into is locked
675  *         kStatus_OTP_Error - Other Errors
676  */
677 status_t IAP_OtpFuseProgram(uint32_t addr, uint32_t data, bool lock);
678 
679 /*!
680  * @brief Reload all shadow registers from OTP fuse block
681  *
682  * This function reloads all the shadow registers from OTP Fuse block
683  *
684  * @return kStatus_Success - Shadow registers' reloadding succeeded.
685  *         kStatus_OTP_EccCheckFail - Ecc Check Failed
686  *         kStatus_OTP_Error - Other Errors
687  */
688 status_t IAP_OtpShadowRegisterReload(void);
689 
690 /*!
691  * @brief Do CRC Check via OTP controller
692  *
693  * This function checks whether data in specified fuse address ranges match the crc value in the specified CRC address
694  *  and return the actual crc value as needed.
695  *
696  * @param start_addr Start address of selected Fuse address range
697  * @param end_addr   End address of selected Fuse address range
698  * @param crc_addr   Address that hold CRC data
699  *
700  * @return kStatus_Success CRC check succeeded, CRC value matched.
701  *         kStatus_InvalidArgument - Invalid Argument
702  *         kStatus_OTP_EccCheckFail Ecc Check Failed
703  *         kStatus_OTP_CrcFail CRC Check Failed
704  */
705 status_t IAP_OtpCrcCheck(uint32_t start_addr, uint32_t end_addr, uint32_t crc_addr);
706 
707 /*!
708  * @brief Calculate the CRC checksum for specified data for OTP
709  *
710  * This function calculates the CRC checksum for specified data for OTP
711  *
712  * @param src the source address of data
713  * @param numberOfWords number of Fuse words
714  * @param crcChecksum   Buffer to store the CRC checksum
715  *
716  * @return kStatus_Success CRC checksum is computed successfully.
717  *         kStatus_InvalidArgument - Invalid Argument
718  */
719 status_t IAP_OtpCrcCalc(uint32_t *src, uint32_t numberOfWords, uint32_t *crcChecksum);
720 /*! @} */
721 #if defined(__cplusplus)
722 }
723 #endif
724 
725 /*! @}*/
726 
727 #endif /* __FSL_IAP_H_ */
728