aboutsummaryrefslogtreecommitdiff
path: root/lib/chibios-contrib/ext/mcux-sdk/devices/MIMXRT633S/drivers/fsl_iap.h
blob: 3726c96090c1e30436bd27914be4f6c768de6174 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
/*
 * Copyright 2018-2020 NXP
 * All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#ifndef __FSL_IAP_H_
#define __FSL_IAP_H_

#include "fsl_common.h"
/*!
 * @addtogroup IAP_driver
 * @{
 */

/*! @file */

/*******************************************************************************
 * Definitions
 ******************************************************************************/
/*! @name Driver version */
/*@{*/
/*! @brief IAP driver version 2.1.1. */
#define FSL_IAP_DRIVER_VERSION (MAKE_VERSION(2, 1, 1))
/*@}*/

/*!
 * @addtogroup iap_flexspi_driver
 * @{
 */

/*! @brief FlexSPI LUT command */
#define NOR_CMD_INDEX_READ        CMD_INDEX_READ        /*!< 0 */
#define NOR_CMD_INDEX_READSTATUS  CMD_INDEX_READSTATUS  /*!< 1 */
#define NOR_CMD_INDEX_WRITEENABLE CMD_INDEX_WRITEENABLE /*!< 2 */
#define NOR_CMD_INDEX_ERASESECTOR 3                     /*!< 3 */
#define NOR_CMD_INDEX_PAGEPROGRAM CMD_INDEX_WRITE       /*!< 4 */
#define NOR_CMD_INDEX_CHIPERASE   5                     /*!< 5 */
#define NOR_CMD_INDEX_DUMMY       6                     /*!< 6 */
#define NOR_CMD_INDEX_ERASEBLOCK  7                     /*!< 7 */

#define NOR_CMD_LUT_SEQ_IDX_READ \
    CMD_LUT_SEQ_IDX_READ /*!< 0  READ LUT sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS \
    CMD_LUT_SEQ_IDX_READSTATUS /*!< 1  Read Status LUT sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_READSTATUS_XPI \
    2 /*!< 2  Read status DPI/QPI/OPI sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE \
    CMD_LUT_SEQ_IDX_WRITEENABLE /*!< 3  Write Enable sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_WRITEENABLE_XPI \
    4 /*!< 4  Write Enable DPI/QPI/OPI sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_ERASESECTOR 5 /*!< 5  Erase Sector sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_ERASEBLOCK  8 /*!< 8 Erase Block sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM \
    CMD_LUT_SEQ_IDX_WRITE                /*!< 9  Program sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_CHIPERASE 11 /*!< 11 Chip Erase sequence in lookupTable id stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_READ_SFDP 13 /*!< 13 Read SFDP sequence in lookupTable id stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_RESTORE_NOCMD \
    14 /*!< 14 Restore 0-4-4/0-8-8 mode sequence id in lookupTable stored in config block */
#define NOR_CMD_LUT_SEQ_IDX_EXIT_NOCMD \
    15 /*!< 15 Exit 0-4-4/0-8-8 mode sequence id in lookupTable stored in config blobk */

/*!
 * @name FlexSPI status.
 * @{
 */
/*! @brief FlexSPI Driver status group. */
enum
{
    kStatusGroup_FlexSPI    = 60,
    kStatusGroup_FlexSPINOR = 201,
};

/*! @brief FlexSPI Driver status. */
enum _flexspi_status
{
    kStatus_FLEXSPI_Success         = MAKE_STATUS(kStatusGroup_Generic, 0), /*!< API is executed successfully*/
    kStatus_FLEXSPI_Fail            = MAKE_STATUS(kStatusGroup_Generic, 1), /*!< API is executed fails*/
    kStatus_FLEXSPI_InvalidArgument = MAKE_STATUS(kStatusGroup_Generic, 4), /*!< Invalid argument*/
    kStatus_FLEXSPI_SequenceExecutionTimeout =
        MAKE_STATUS(kStatusGroup_FlexSPI, 0), /*!< The FlexSPI Sequence Execution timeout*/
    kStatus_FLEXSPI_InvalidSequence = MAKE_STATUS(kStatusGroup_FlexSPI, 1), /*!< The FlexSPI LUT sequence invalid*/
    kStatus_FLEXSPI_DeviceTimeout   = MAKE_STATUS(kStatusGroup_FlexSPI, 2), /*!< The FlexSPI device timeout*/
    kStatus_FLEXSPINOR_ProgramFail =
        MAKE_STATUS(kStatusGroup_FlexSPINOR, 0), /*!< Status for Page programming failure */
    kStatus_FLEXSPINOR_EraseSectorFail =
        MAKE_STATUS(kStatusGroup_FlexSPINOR, 1),                               /*!< Status for Sector Erase failure */
    kStatus_FLEXSPINOR_EraseAllFail = MAKE_STATUS(kStatusGroup_FlexSPINOR, 2), /*!< Status for Chip Erase failure */
    kStatus_FLEXSPINOR_WaitTimeout  = MAKE_STATUS(kStatusGroup_FlexSPINOR, 3), /*!< Status for timeout */
    kStatus_FLEXSPINOR_NotSupported = MAKE_STATUS(kStatusGroup_FlexSPINOR, 4), /*  Status for PageSize overflow */
    kStatus_FLEXSPINOR_WriteAlignmentError =
        MAKE_STATUS(kStatusGroup_FlexSPINOR, 5), /*!< Status for Alignement error */
    kStatus_FLEXSPINOR_CommandFailure =
        MAKE_STATUS(kStatusGroup_FlexSPINOR, 6), /*!< Status for Erase/Program Verify Error */
    kStatus_FLEXSPINOR_SFDP_NotFound = MAKE_STATUS(kStatusGroup_FlexSPINOR, 7), /*!< Status for SFDP read failure */
    kStatus_FLEXSPINOR_Unsupported_SFDP_Version =
        MAKE_STATUS(kStatusGroup_FlexSPINOR, 8), /*!< Status for Unrecognized SFDP version */
    kStatus_FLEXSPINOR_Flash_NotFound =
        MAKE_STATUS(kStatusGroup_FlexSPINOR, 9), /*!< Status for Flash detection failure */
    kStatus_FLEXSPINOR_DTRRead_DummyProbeFailed =
        MAKE_STATUS(kStatusGroup_FlexSPINOR, 10), /*!< Status for DDR Read dummy probe failure */
};
/*! @} */

/*! @brief Flash Configuration Option0 device_type. */
enum
{
    kSerialNorCfgOption_Tag                         = 0x0c,
    kSerialNorCfgOption_DeviceType_ReadSFDP_SDR     = 0,
    kSerialNorCfgOption_DeviceType_ReadSFDP_DDR     = 1,
    kSerialNorCfgOption_DeviceType_HyperFLASH1V8    = 2,
    kSerialNorCfgOption_DeviceType_HyperFLASH3V0    = 3,
    kSerialNorCfgOption_DeviceType_MacronixOctalDDR = 4,
    kSerialNorCfgOption_DeviceType_MacronixOctalSDR = 5, /* For RT600 devcies only. */
    kSerialNorCfgOption_DeviceType_MicronOctalDDR   = 6,
    kSerialNorCfgOption_DeviceType_MicronOctalSDR   = 7, /* For RT600 devcies only. */
    kSerialNorCfgOption_DeviceType_AdestoOctalDDR   = 8,
    kSerialNorCfgOption_DeviceType_AdestoOctalSDR   = 9, /* For RT600 devcies only. */
};

/*! @brief Flash Configuration Option0 quad_mode_setting. */
enum
{
    kSerialNorQuadMode_NotConfig            = 0,
    kSerialNorQuadMode_StatusReg1_Bit6      = 1,
    kSerialNorQuadMode_StatusReg2_Bit1      = 2,
    kSerialNorQuadMode_StatusReg2_Bit7      = 3,
    kSerialNorQuadMode_StatusReg2_Bit1_0x31 = 4,
};

/*! @brief Flash Configuration Option0 misc_mode. */
enum
{
    kSerialNorEnhanceMode_Disabled         = 0,
    kSerialNorEnhanceMode_0_4_4_Mode       = 1,
    kSerialNorEnhanceMode_0_8_8_Mode       = 2,
    kSerialNorEnhanceMode_DataOrderSwapped = 3,
    kSerialNorEnhanceMode_2ndPinMux        = 4,
};

/*! @brief FLEXSPI_RESET_PIN boot configurations in OTP */
enum
{
    kFlashResetLogic_Disabled     = 0,
    kFlashResetLogic_ResetPin     = 1,
    kFlashResetLogic_JedecHwReset = 2,
};

/*! @brief Flash Configuration Option1 flash_connection. */
enum
{
    kSerialNorConnection_SinglePortA,
    kSerialNorConnection_Parallel,
    kSerialNorConnection_SinglePortB,
    kSerialNorConnection_BothPorts
};

/*! @brief Serial NOR Configuration Option */
typedef struct _serial_nor_config_option
{
    union
    {
        struct
        {
            uint32_t max_freq : 4;          /*!< Maximum supported Frequency */
            uint32_t misc_mode : 4;         /*!< miscellaneous mode */
            uint32_t quad_mode_setting : 4; /*!< Quad mode setting */
            uint32_t cmd_pads : 4;          /*!< Command pads */
            uint32_t query_pads : 4;        /*!< SFDP read pads */
            uint32_t device_type : 4;       /*!< Device type */
            uint32_t option_size : 4;       /*!< Option size, in terms of uint32_t, size = (option_size + 1) * 4 */
            uint32_t tag : 4;               /*!< Tag, must be 0x0E */
        } B;
        uint32_t U;
    } option0;

    union
    {
        struct
        {
            uint32_t dummy_cycles : 8;     /*!< Dummy cycles before read */
            uint32_t status_override : 8;  /*!< Override status register value during device mode configuration */
            uint32_t pinmux_group : 4;     /*!< The pinmux group selection */
            uint32_t dqs_pinmux_group : 4; /*!< The DQS Pinmux Group Selection */
            uint32_t drive_strength : 4;   /*!< The Drive Strength of FlexSPI Pads */
            uint32_t flash_connection : 4; /*!< Flash connection option: 0 - Single Flash connected to port A, 1 - */
            /*! Parallel mode, 2 - Single Flash connected to Port B */
        } B;
        uint32_t U;
    } option1;

} serial_nor_config_option_t;

/*! @brief Flash Run Context */
typedef union
{
    struct
    {
        uint8_t por_mode;
        uint8_t current_mode;
        uint8_t exit_no_cmd_sequence;
        uint8_t restore_sequence;
    } B;
    uint32_t U;
} flash_run_context_t;

/*!@brief Flash Device Mode Configuration Sequence */
enum
{
    kRestoreSequence_None           = 0,
    kRestoreSequence_HW_Reset       = 1,
    kRestoreSequence_4QPI_FF        = 2,
    kRestoreSequence_5QPI_FF        = 3,
    kRestoreSequence_8QPI_FF        = 4,
    kRestoreSequence_Send_F0        = 5,
    kRestoreSequence_Send_66_99     = 6,
    kRestoreSequence_Send_6699_9966 = 7,
    kRestoreSequence_Send_06_FF     = 8, /*  Adesto EcoXIP */
};

/*!@brief Flash Config Mode Definition */
enum
{
    kFlashInstMode_ExtendedSpi = 0x00,
    kFlashInstMode_0_4_4_SDR   = 0x01,
    kFlashInstMode_0_4_4_DDR   = 0x02,
    kFlashInstMode_QPI_SDR     = 0x41,
    kFlashInstMode_QPI_DDR     = 0x42,
    kFlashInstMode_OPI_SDR     = 0x81, /* For RT600 devices only. */
    kFlashInstMode_OPI_DDR     = 0x82,
};

/*!@brief Flash Device Type Definition */
enum
{
    kFlexSpiDeviceType_SerialNOR    = 1,    /*!< Flash devices are Serial NOR */
    kFlexSpiDeviceType_SerialNAND   = 2,    /*!< Flash devices are Serial NAND */
    kFlexSpiDeviceType_SerialRAM    = 3,    /*!< Flash devices are Serial RAM/HyperFLASH */
    kFlexSpiDeviceType_MCP_NOR_NAND = 0x12, /*!< Flash device is MCP device, A1 is Serial NOR, A2 is Serial NAND */
    kFlexSpiDeviceType_MCP_NOR_RAM  = 0x13, /*!< Flash deivce is MCP device, A1 is Serial NOR, A2 is Serial RAMs */
};

/*!@brief Flash Pad Definitions */
enum
{
    kSerialFlash_1Pad  = 1,
    kSerialFlash_2Pads = 2,
    kSerialFlash_4Pads = 4,
    kSerialFlash_8Pads = 8,
};

/*!@brief FlexSPI LUT Sequence structure */
typedef struct _lut_sequence
{
    uint8_t seqNum; /*!< Sequence Number, valid number: 1-16 */
    uint8_t seqId;  /*!< Sequence Index, valid number: 0-15 */
    uint16_t reserved;
} flexspi_lut_seq_t;

/*!@brief Flash Configuration Command Type */
enum
{
    kDeviceConfigCmdType_Generic,    /*!< Generic command, for example: configure dummy cycles, drive strength, etc */
    kDeviceConfigCmdType_QuadEnable, /*!< Quad Enable command */
    kDeviceConfigCmdType_Spi2Xpi,    /*!< Switch from SPI to DPI/QPI/OPI mode */
    kDeviceConfigCmdType_Xpi2Spi,    /*!< Switch from DPI/QPI/OPI to SPI mode */
    kDeviceConfigCmdType_Spi2NoCmd,  /*!< Switch to 0-4-4/0-8-8 mode */
    kDeviceConfigCmdType_Reset,      /*!< Reset device command */
};

/*!@brief FlexSPI Dll Time Block */
typedef struct
{
    uint8_t time_100ps;  /* Data valid time, in terms of 100ps */
    uint8_t delay_cells; /* Data valid time, in terms of delay cells */
} flexspi_dll_time_t;

/*!@brief FlexSPI Memory Configuration Block */
typedef struct _FlexSPIConfig
{
    uint32_t tag;       /*!< [0x000-0x003] Tag, fixed value 0x42464346UL */
    uint32_t version;   /*!< [0x004-0x007] Version,[31:24] -'V', [23:16] - Major, [15:8] - Minor, [7:0] - bugfix */
    uint32_t reserved0; /*!< [0x008-0x00b] Reserved for future use */
    uint8_t readSampleClkSrc;   /*!< [0x00c-0x00c] Read Sample Clock Source, valid value: 0/1/3 */
    uint8_t csHoldTime;         /*!< [0x00d-0x00d] CS hold time, default value: 3 */
    uint8_t csSetupTime;        /*!< [0x00e-0x00e] CS setup time, default value: 3 */
    uint8_t columnAddressWidth; /*!< [0x00f-0x00f] Column Address with, for HyperBus protocol, it is fixed to 3, For */
    /*! Serial NAND, need to refer to datasheet */
    uint8_t deviceModeCfgEnable; /*!< [0x010-0x010] Device Mode Configure enable flag, 1 - Enable, 0 - Disable */
    uint8_t
        deviceModeType; /*!< [0x011-0x011] Specify the configuration command type:Quad Enable, DPI/QPI/OPI switch, */
    /*! Generic configuration, etc. */
    uint16_t waitTimeCfgCommands; /*!< [0x012-0x013] Wait time for all configuration commands, unit: 100us, Used for */
    /*! DPI/QPI/OPI switch or reset command */
    flexspi_lut_seq_t
        deviceModeSeq; /*!< [0x014-0x017] Device mode sequence info, [7:0] - LUT sequence id, [15:8] - LUt */
    /*! sequence number, [31:16] Reserved */
    uint32_t deviceModeArg;    /*!< [0x018-0x01b] Argument/Parameter for device configuration */
    uint8_t configCmdEnable;   /*!< [0x01c-0x01c] Configure command Enable Flag, 1 - Enable, 0 - Disable */
    uint8_t configModeType[3]; /*!< [0x01d-0x01f] Configure Mode Type, similar as deviceModeTpe */
    flexspi_lut_seq_t
        configCmdSeqs[3]; /*!< [0x020-0x02b] Sequence info for Device Configuration command, similar as deviceModeSeq */
    uint32_t reserved1;   /*!< [0x02c-0x02f] Reserved for future use */
    uint32_t configCmdArgs[3]; /*!< [0x030-0x03b] Arguments/Parameters for device Configuration commands */
    uint32_t reserved2;        /*!< [0x03c-0x03f] Reserved for future use */
    uint32_t
        controllerMiscOption; /*!< [0x040-0x043] Controller Misc Options, see Misc feature bit definitions for more */
    /*! details */
    uint8_t deviceType;    /*!< [0x044-0x044] Device Type:  See Flash Type Definition for more details */
    uint8_t sflashPadType; /*!< [0x045-0x045] Serial Flash Pad Type: 1 - Single, 2 - Dual, 4 - Quad, 8 - Octal */
    uint8_t serialClkFreq; /*!< [0x046-0x046] Serial Flash Frequencey, device specific definitions, See System Boot */
    /*! Chapter for more details */
    uint8_t
        lutCustomSeqEnable; /*!< [0x047-0x047] LUT customization Enable, it is required if the program/erase cannot */
    /*! be done using 1 LUT sequence, currently, only applicable to HyperFLASH */
    uint32_t reserved3[2];               /*!< [0x048-0x04f] Reserved for future use */
    uint32_t sflashA1Size;               /*!< [0x050-0x053] Size of Flash connected to A1 */
    uint32_t sflashA2Size;               /*!< [0x054-0x057] Size of Flash connected to A2 */
    uint32_t sflashB1Size;               /*!< [0x058-0x05b] Size of Flash connected to B1 */
    uint32_t sflashB2Size;               /*!< [0x05c-0x05f] Size of Flash connected to B2 */
    uint32_t csPadSettingOverride;       /*!< [0x060-0x063] CS pad setting override value */
    uint32_t sclkPadSettingOverride;     /*!< [0x064-0x067] SCK pad setting override value */
    uint32_t dataPadSettingOverride;     /*!< [0x068-0x06b] data pad setting override value */
    uint32_t dqsPadSettingOverride;      /*!< [0x06c-0x06f] DQS pad setting override value */
    uint32_t timeoutInMs;                /*!< [0x070-0x073] Timeout threshold for read status command */
    uint32_t commandInterval;            /*!< [0x074-0x077] CS deselect interval between two commands */
    flexspi_dll_time_t dataValidTime[2]; /*!< [0x078-0x07b] CLK edge to data valid time for PORT A and PORT B */
    uint16_t busyOffset;                 /*!< [0x07c-0x07d] Busy offset, valid value: 0-31 */
    uint16_t
        busyBitPolarity; /*!< [0x07e-0x07f] Busy flag polarity, 0 - busy flag is 1 when flash device is busy, 1 - */
    /*! busy flag is 0 when flash device is busy */
    uint32_t lookupTable[64];           /*!< [0x080-0x17f] Lookup table holds Flash command sequences */
    flexspi_lut_seq_t lutCustomSeq[12]; /*!< [0x180-0x1af] Customizable LUT Sequences */
    uint32_t reserved4[4];              /*!< [0x1b0-0x1bf] Reserved for future use */
} flexspi_mem_config_t;

/*!@brief FlexSPI Operation Type */
typedef enum _FlexSPIOperationType
{
    kFlexSpiOperation_Command = 0, /*!< FlexSPI operation: Only command, both TX and */
    /*! RX buffer are ignored. */
    kFlexSpiOperation_Config = 1, /*!< FlexSPI operation: Configure device mode, the */
    /*! TX FIFO size is fixed in LUT. */
    kFlexSpiOperation_Write = 2, /*!< FlexSPI operation: Write,  only TX buffer is */
    /*! effective */
    kFlexSpiOperation_Read = 3, /*!< FlexSPI operation: Read, only Rx Buffer is */
    /*! effective. */
    kFlexSpiOperation_End = kFlexSpiOperation_Read,
} flexspi_operation_t;

/*!@brief FlexSPI Transfer Context */
typedef struct _FlexSpiXfer
{
    flexspi_operation_t operation; /*!< FlexSPI operation */
    uint32_t baseAddress;          /*!< FlexSPI operation base address */
    uint32_t seqId;                /*!< Sequence Id */
    uint32_t seqNum;               /*!< Sequence Number */
    bool isParallelModeEnable;     /*!< Is a parallel transfer */
    uint32_t *txBuffer;            /*!< Tx buffer */
    uint32_t txSize;               /*!< Tx size in bytes */
    uint32_t *rxBuffer;            /*!< Rx buffer */
    uint32_t rxSize;               /*!< Rx size in bytes */
} flexspi_xfer_t;

/*!@brief Serial NOR configuration block */
typedef struct _flexspi_nor_config
{
    flexspi_mem_config_t memConfig; /*!< Common memory configuration info via FlexSPI */
    uint32_t pageSize;              /*!< Page size of Serial NOR */
    uint32_t sectorSize;            /*!< Sector size of Serial NOR */
    uint8_t ipcmdSerialClkFreq;     /*!< Clock frequency for IP command */
    uint8_t isUniformBlockSize;     /*!< Sector/Block size is the same */
    uint8_t isDataOrderSwapped;     /*!< Data order (D0, D1, D2, D3) is swapped (D1,D0, D3, D2) */
    uint8_t reserved0[1];           /*!< Reserved for future use */
    uint8_t serialNorType;          /*!< Serial NOR Flash type: 0/1/2/3 */
    uint8_t needExitNoCmdMode;      /*!< Need to exit NoCmd mode before other IP command */
    uint8_t halfClkForNonReadCmd;   /*!< Half the Serial Clock for non-read command: true/false */
    uint8_t needRestoreNoCmdMode;   /*!< Need to Restore NoCmd mode after IP commmand execution */
    uint32_t blockSize;             /*!< Block size */
    uint32_t flashStateCtx;         /*!< Flash State Context */
    uint32_t reserve2[10];          /*!< Reserved for future use */
} flexspi_nor_config_t;
/*! @} */

/*!
 * @addtogroup iap_otp_driver
 * @{
 */

/*! @brief OTP Status Group */
enum
{
    kStatusGroup_OtpGroup = 0x210,
};

/*! @brief OTP Error Status definitions */
enum
{
    kStatus_OTP_InvalidAddress = MAKE_STATUS(kStatusGroup_OtpGroup, 1), /*!< Invalid OTP address */
    kStatus_OTP_ProgramFail    = MAKE_STATUS(kStatusGroup_OtpGroup, 2), /*!< Program Fail */
    kStatus_OTP_CrcFail        = MAKE_STATUS(kStatusGroup_OtpGroup, 3), /*!< CrcCheck Fail */
    kStatus_OTP_Error          = MAKE_STATUS(kStatusGroup_OtpGroup, 4), /*!< Errors happened during OTP operation */
    kStatus_OTP_EccCheckFail   = MAKE_STATUS(kStatusGroup_OtpGroup, 5), /*!< Ecc Check failed during OTP operation */
    kStatus_OTP_Locked         = MAKE_STATUS(kStatusGroup_OtpGroup, 6), /*!< OTP Fuse field has been locked */
    kStatus_OTP_Timeout        = MAKE_STATUS(kStatusGroup_OtpGroup, 7), /*!< OTP operation time out */
    kStatus_OTP_CrcCheckPass   = MAKE_STATUS(kStatusGroup_OtpGroup, 8), /*!< OTP CRC Check Pass */
};
/*! @} */

/*!
 * @addtogroup iap_boot_driver
 * @{
 */

/*! @brief IAP boot option. */
typedef struct _iap_boot_option
{
    union
    {
        struct
        {
            uint32_t reserved : 8;       /*! reserved field. */
            uint32_t bootImageIndex : 4; /*! FlexSPI boot image index for FlexSPI NOR flash. */
            uint32_t instance : 4;       /*! Only used when boot interface is FlexSPI/SD/MMC. */
            uint32_t bootInterface : 4;  /*! RT500: 0: USART 2: SPI 3: USB HID 4:FlexSPI 6:SD 7:MMC.
                                             RT600: 0: USART 1: I2C 2: SPI 3: USB HID 4:FlexSPI 7:SD 8:MMC*/
            uint32_t mode : 4;           /* boot mode, 0: Master boot mode; 1: ISP boot */
            uint32_t tag : 8;            /*! tag, should always be "0xEB". */
        } B;
        uint32_t U;
    } option;
} iap_boot_option_t;

/*! IAP boot option tag */
#define IAP_BOOT_OPTION_TAG (0xEBU)
/*! IAP boot option mode */
#define IAP_BOOT_OPTION_MODE_MASTER (0U)
#define IAP_BOOT_OPTION_MODE_ISP    (1U)

/*! @} */

/*******************************************************************************
 * API
 ******************************************************************************/
#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @addtogroup iap_boot_driver
 * @{
 */

/*!
 * @brief Invoke into ROM with specified boot parameters.
 *
 * @param option Boot parameters. Refer to #iap_boot_option_t.
 */
void IAP_RunBootLoader(iap_boot_option_t *option);
/*! @} */

/*!
 * @addtogroup iap_flexspi_driver
 * @{
 */

/*!
 * @brief Initialize Serial NOR devices via FlexSPI.
 *
 * This function configures the FlexSPI controller with the arguments pointed by param config.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiNorInit(uint32_t instance, flexspi_nor_config_t *config);

/*!
 * @brief Program data to Serial NOR via FlexSPI.
 *
 * This function Program data to specified destination address.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
 * @param dstAddr The destination address to be programmed.
 * @param src Points to the buffer which hold the data to be programmed.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiNorPageProgram(uint32_t instance,
                                   flexspi_nor_config_t *config,
                                   uint32_t dstAddr,
                                   const uint32_t *src);

/*!
 * @brief Erase all the Serial NOR devices connected on FlexSPI.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiNorEraseAll(uint32_t instance, flexspi_nor_config_t *config);

/*!
 * @brief Erase Flash Region specified by address and length.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
 * @param start The start address to be erased.
 * @param length The length to be erased.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiNorErase(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t length);

/*!
 * @brief Erase one sector specified by address.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
 * @param address The address of the sector to be erased.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiNorEraseSector(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);

/*!
 * @brief Erase one block specified by address.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
 * @param address The address of the block to be erased.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiNorEraseBlock(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);

/*!
 * @brief Get FlexSPI NOR Configuration Block based on specified option.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
 * @param option The Flash Configuration Option block. Refer to #serial_nor_config_option_t.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiNorGetConfig(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);

/*!
 * @brief Read data from Flexspi NOR Flash.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
 * @param dst Buffer address used to store the read data.
 * @param start The Read address.
 * @param bytes The Read size
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiNorRead(
    uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t start, uint32_t bytes);

/*!
 * @brief Get FlexSPI Xfer data.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param xfer The FlexSPI Transfer Context block. Refer to #flexspi_xfer_t.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiXfer(uint32_t instance, flexspi_xfer_t *xfer);

/*!
 * @brief Update FlexSPI Lookup table.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param seqIndex The index of FlexSPI LUT to be updated.
 * @param lutBase Points to the buffer which hold the LUT data to be programmed.
 * @param numberOfSeq The number of LUT seq that need to be updated.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiUpdateLut(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t numberOfSeq);

/*!
 * @brief Set the clock source for FlexSPI.
 *
 * @param clockSrc Clock source for flexspi interface.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
status_t IAP_FlexspiSetClockSource(uint32_t clockSrc);

/*!
 * @brief Configure the flexspi interface clock frequency and data sample mode.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param freqOption FlexSPI interface clock frequency selection.
 * @param sampleClkMode FlexSPI controller data sample mode.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
void IAP_FlexspiConfigClock(uint32_t instance, uint32_t freqOption, uint32_t sampleClkMode);

/*!
 * @brief Configure flexspi nor automatically.
 *
 * @param instance FlexSPI controller instance, only support 0.
 * @param config The Flash configuration block. Refer to #flexspi_nor_config_t.
 * @param option The Flash Configuration Option block. Refer to #serial_nor_config_option_t.
 * @return The status flags. This is a member of the
 *         enumeration ::_flexspi_status
 */
#if defined(DOXYGEN_OUTPUT) && DOXYGEN_OUTPUT
status_t IAP_FlexspiNorAutoConfig(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option);
#else
AT_QUICKACCESS_SECTION_CODE(status_t IAP_FlexspiNorAutoConfig(uint32_t instance,
                                                              flexspi_nor_config_t *config,
                                                              serial_nor_config_option_t *option));
#endif
/*! @} */

/*!
 * @addtogroup iap_otp_driver
 * @{
 */

/*!
 * @brief Initialize OTP controller
 *
 * This function enables OTP Controller clock.
 *
 * @param src_clk_freq The Frequency of the source clock of OTP controller
 * @return kStatus_Success
 */
status_t IAP_OtpInit(uint32_t src_clk_freq);

/*!
 * @brief De-Initialize OTP controller
 *
 * This functin disables OTP Controller Clock.
 * @return kStatus_Success
 */
status_t IAP_OtpDeinit(void);

/*!
 * @brief Read Fuse value from OTP Fuse Block
 *
 * This function read fuse data from OTP Fuse block to specified data buffer.
 *
 * @param addr Fuse address
 * @param data Buffer to hold the data read from OTP Fuse block
 * @return kStatus_Success - Data read from OTP Fuse block successfully
 *         kStatus_InvalidArgument - data pointer is invalid
 *         kStatus_OTP_EccCheckFail - Ecc Check Failed
 *         kStatus_OTP_Error - Other Errors
 */
status_t IAP_OtpFuseRead(uint32_t addr, uint32_t *data);

/*!
 * @brief Program value to OTP Fuse block
 *
 * This function program data to specified OTP Fuse address.
 *
 * @param addr Fuse address
 * @param data data to be programmed into OTP Fuse block
 * @param lock lock the fuse field or not
 * @return kStatus_Success - Data has been programmed into OTP Fuse block successfully
 *         kStatus_OTP_ProgramFail - Fuse programming failed
 *         kStatus_OTP_Locked - The address to be programmed into is locked
 *         kStatus_OTP_Error - Other Errors
 */
status_t IAP_OtpFuseProgram(uint32_t addr, uint32_t data, bool lock);

/*!
 * @brief Reload all shadow registers from OTP fuse block
 *
 * This function reloads all the shadow registers from OTP Fuse block
 *
 * @return kStatus_Success - Shadow registers' reloadding succeeded.
 *         kStatus_OTP_EccCheckFail - Ecc Check Failed
 *         kStatus_OTP_Error - Other Errors
 */
status_t IAP_OtpShadowRegisterReload(void);

/*!
 * @brief Do CRC Check via OTP controller
 *
 * This function checks whether data in specified fuse address ranges match the crc value in the specified CRC address
 *  and return the actual crc value as needed.
 *
 * @param start_addr Start address of selected Fuse address range
 * @param end_addr   End address of selected Fuse address range
 * @param crc_addr   Address that hold CRC data
 *
 * @return kStatus_Success CRC check succeeded, CRC value matched.
 *         kStatus_InvalidArgument - Invalid Argument
 *         kStatus_OTP_EccCheckFail Ecc Check Failed
 *         kStatus_OTP_CrcFail CRC Check Failed
 */
status_t IAP_OtpCrcCheck(uint32_t start_addr, uint32_t end_addr, uint32_t crc_addr);

/*!
 * @brief Calculate the CRC checksum for specified data for OTP
 *
 * This function calculates the CRC checksum for specified data for OTP
 *
 * @param src the source address of data
 * @param numberOfWords number of Fuse words
 * @param crcChecksum   Buffer to store the CRC checksum
 *
 * @return kStatus_Success CRC checksum is computed successfully.
 *         kStatus_InvalidArgument - Invalid Argument
 */
status_t IAP_OtpCrcCalc(uint32_t *src, uint32_t numberOfWords, uint32_t *crcChecksum);
/*! @} */
#if defined(__cplusplus)
}
#endif

/*! @}*/

#endif /* __FSL_IAP_H_ */