/*
 * Copyright (c) 2016, Freescale Semiconductor, Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * o Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * o Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*!
 * @file fsl_flash_driver_c90tfs.h
 *
 * @page misra_violations MISRA-C:2012 violations
 *
 * @section [global]
 * Violates MISRA 2012 Advisory Rule 2.5, Global macro not referenced.
 * This is required to enable the use of a macro needed by
 * the user code (even if the macro is not used inside the flash driver code)
 * or driver code in the future.
 *
 * @section [global]
 * Violates MISRA 2012 Advisory Directive 4.9, Function-like macro defined.
 * This macro is needed in creating a common name for any IP.
 */

#ifndef FSL_FLASH_DRIVER_C90TFS_H
#define FSL_FLASH_DRIVER_C90TFS_H

#include <stdbool.h>
#include <stddef.h>
#include "device_registers.h"

/*!
 * @addtogroup c90tfs_flash_driver
 * @{
 */

/*******************************************************************************
 * FTFx - Register instance definitions
 *******************************************************************************/
/*******************************************************************************
 * FTFE
 *******************************************************************************/
#ifdef FTFE
#define FTFx_BASE                               FTFE_BASE
#define FTFx_FSTAT                              FTFE->FSTAT
#define FTFx_FCNFG                              FTFE->FCNFG
#define FTFx_FSEC                               FTFE->FSEC
#define FTFx_FOPT                               FTFE->FOPT
#define FTFx_FCCOB3                             FTFE->FCCOB[0]
#define FTFx_FCCOB2                             FTFE->FCCOB[1]
#define FTFx_FCCOB1                             FTFE->FCCOB[2]
#define FTFx_FCCOB0                             FTFE->FCCOB[3]
#define FTFx_FCCOB7                             FTFE->FCCOB[4]
#define FTFx_FCCOB6                             FTFE->FCCOB[5]
#define FTFx_FCCOB5                             FTFE->FCCOB[6]
#define FTFx_FCCOB4                             FTFE->FCCOB[7]
#define FTFx_FCCOBB                             FTFE->FCCOB[8]
#define FTFx_FCCOBA                             FTFE->FCCOB[9]
#define FTFx_FCCOB9                             FTFE->FCCOB[10]
#define FTFx_FCCOB8                             FTFE->FCCOB[11]
#define FTFx_FPROT3                             FTFE->FPROT[0]
#define FTFx_FPROT2                             FTFE->FPROT[1]
#define FTFx_FPROT1                             FTFE->FPROT[2]
#define FTFx_FPROT0                             FTFE->FPROT[3]
#define FTFx_FEPROT                             FTFE->FEPROT
#define FTFx_FDPROT                             FTFE->FDPROT
#ifdef  FTFE_FERSTAT
#define FTFx_FERSTAT                            FTFE_FERSTAT
#endif
#ifdef  FTFE_FERCNFG
#define FTFx_FERCNFG                            FTFE_FERCNFG
#endif
/* FSTAT Bit Fields */
#define FTFx_FSTAT_MGSTAT0_MASK                 FTFE_FSTAT_MGSTAT0_MASK
#define FTFx_FSTAT_MGSTAT0_SHIFT                FTFE_FSTAT_MGSTAT0_SHIFT
#define FTFx_FSTAT_MGSTAT0_WIDTH                FTFE_FSTAT_MGSTAT0_WIDTH
#define FTFx_FSTAT_MGSTAT0(x)                   FTFE_FSTAT_MGSTAT0(x)
#define FTFx_FSTAT_FPVIOL_MASK                  FTFE_FSTAT_FPVIOL_MASK
#define FTFx_FSTAT_FPVIOL_SHIFT                 FTFE_FSTAT_FPVIOL_SHIFT
#define FTFx_FSTAT_FPVIOL_WIDTH                 FTFE_FSTAT_FPVIOL_WIDTH
#define FTFx_FSTAT_FPVIOL(x)                    FTFE_FSTAT_FPVIOL(x)
#define FTFx_FSTAT_ACCERR_MASK                  FTFE_FSTAT_ACCERR_MASK
#define FTFx_FSTAT_ACCERR_SHIFT                 FTFE_FSTAT_ACCERR_SHIFT
#define FTFx_FSTAT_ACCERR_WIDTH                 FTFE_FSTAT_ACCERR_WIDTH
#define FTFx_FSTAT_ACCERR(x)                    FTFE_FSTAT_ACCERR(x)
#define FTFx_FSTAT_RDCOLERR_MASK                FTFE_FSTAT_RDCOLERR_MASK
#define FTFx_FSTAT_RDCOLERR_SHIFT               FTFE_FSTAT_RDCOLERR_SHIFT
#define FTFx_FSTAT_RDCOLERR_WIDTH               FTFE_FSTAT_RDCOLERR_WIDTH
#define FTFx_FSTAT_RDCOLERR(x)                  FTFE_FSTAT_RDCOLERR(x)
#define FTFx_FSTAT_CCIF_MASK                    FTFE_FSTAT_CCIF_MASK
#define FTFx_FSTAT_CCIF_SHIFT                   FTFE_FSTAT_CCIF_SHIFT
#define FTFx_FSTAT_CCIF_WIDTH                   FTFE_FSTAT_CCIF_WIDTH
#define FTFx_FSTAT_CCIF(x)                      FTFE_FSTAT_CCIF(x)
/* FCNFG Bit Fields */
#define FTFx_FCNFG_EEERDY_MASK                  FTFE_FCNFG_EEERDY_MASK
#define FTFx_FCNFG_EEERDY_SHIFT                 FTFE_FCNFG_EEERDY_SHIFT
#define FTFx_FCNFG_EEERDY_WIDTH                 FTFE_FCNFG_EEERDY_WIDTH
#define FTFx_FCNFG_EEERDY(x)                    FTFE_FCNFG_EEERDY(x)
#define FTFx_FCNFG_RAMRDY_MASK                  FTFE_FCNFG_RAMRDY_MASK
#define FTFx_FCNFG_RAMRDY_SHIFT                 FTFE_FCNFG_RAMRDY_SHIFT
#define FTFx_FCNFG_RAMRDY_WIDTH                 FTFE_FCNFG_RAMRDY_WIDTH
#define FTFx_FCNFG_RAMRDY(x)                    FTFE_FCNFG_RAMRDY(x)
#define FTFx_FCNFG_PFLSH_MASK                   FTFE_FCNFG_PFLSH_MASK
#define FTFx_FCNFG_PFLSH_SHIFT                  FTFE_FCNFG_PFLSH_SHIFT
#define FTFx_FCNFG_PFLSH_WIDTH                  FTFE_FCNFG_PFLSH_WIDTH
#define FTFx_FCNFG_PFLSH(x)                     FTFE_FCNFG_PFLSH(x)
#define FTFx_FCNFG_ERSSUSP_MASK                 FTFE_FCNFG_ERSSUSP_MASK
#define FTFx_FCNFG_ERSSUSP_SHIFT                FTFE_FCNFG_ERSSUSP_SHIFT
#define FTFx_FCNFG_ERSSUSP_WIDTH                FTFE_FCNFG_ERSSUSP_WIDTH
#define FTFx_FCNFG_ERSSUSP(x)                   FTFE_FCNFG_ERSSUSP(x)
#define FTFx_FCNFG_ERSAREQ_MASK                 FTFE_FCNFG_ERSAREQ_MASK
#define FTFx_FCNFG_ERSAREQ_SHIFT                FTFE_FCNFG_ERSAREQ_SHIFT
#define FTFx_FCNFG_ERSAREQ_WIDTH                FTFE_FCNFG_ERSAREQ_WIDTH
#define FTFx_FCNFG_ERSAREQ(x)                   FTFE_FCNFG_ERSAREQ(x)
#define FTFx_FCNFG_RDCOLLIE_MASK                FTFE_FCNFG_RDCOLLIE_MASK
#define FTFx_FCNFG_RDCOLLIE_SHIFT               FTFE_FCNFG_RDCOLLIE_SHIFT
#define FTFx_FCNFG_RDCOLLIE_WIDTH               FTFE_FCNFG_RDCOLLIE_WIDTH
#define FTFx_FCNFG_RDCOLLIE(x)                  FTFE_FCNFG_RDCOLLIE(x)
#define FTFx_FCNFG_CCIE_MASK                    FTFE_FCNFG_CCIE_MASK
#define FTFx_FCNFG_CCIE_SHIFT                   FTFE_FCNFG_CCIE_SHIFT
#define FTFx_FCNFG_CCIE_WIDTH                   FTFE_FCNFG_CCIE_WIDTH
#define FTFx_FCNFG_CCIE(x)                      FTFE_FCNFG_CCIE(x)
/* FSEC Bit Fields */
#define FTFx_FSEC_SEC_MASK                      FTFE_FSEC_SEC_MASK
#define FTFx_FSEC_SEC_SHIFT                     FTFE_FSEC_SEC_SHIFT
#define FTFx_FSEC_SEC_WIDTH                     FTFE_FSEC_SEC_WIDTH
#define FTFx_FSEC_SEC(x)                        FTFE_FSEC_SEC(x)
#define FTFx_FSEC_FSLACC_MASK                   FTFE_FSEC_FSLACC_MASK
#define FTFx_FSEC_FSLACC_SHIFT                  FTFE_FSEC_FSLACC_SHIFT
#define FTFx_FSEC_FSLACC_WIDTH                  FTFE_FSEC_FSLACC_WIDTH
#define FTFx_FSEC_FSLACC(x)                     FTFE_FSEC_FSLACC(x)
#define FTFx_FSEC_MEEN_MASK                     FTFE_FSEC_MEEN_MASK
#define FTFx_FSEC_MEEN_SHIFT                    FTFE_FSEC_MEEN_SHIFT
#define FTFx_FSEC_MEEN_WIDTH                    FTFE_FSEC_MEEN_WIDTH
#define FTFx_FSEC_MEEN(x)                       FTFE_FSEC_MEEN(x)
#define FTFx_FSEC_KEYEN_MASK                    FTFE_FSEC_KEYEN_MASK
#define FTFx_FSEC_KEYEN_SHIFT                   FTFE_FSEC_KEYEN_SHIFT
#define FTFx_FSEC_KEYEN_WIDTH                   FTFE_FSEC_KEYEN_WIDTH
#define FTFx_FSEC_KEYEN(x)                      FTFE_FSEC_KEYEN(x)
/* FOPT Bit Fields */
#define FTFx_FOPT_OPT_MASK                      FTFE_FOPT_OPT_MASK
#define FTFx_FOPT_OPT_SHIFT                     FTFE_FOPT_OPT_SHIFT
#define FTFx_FOPT_OPT_WIDTH                     FTFE_FOPT_OPT_WIDTH
#define FTFx_FOPT_OPT(x)                        FTFE_FOPT_OPT(x)
/* FCCOB Bit Fields */
#define FTFx_FCCOB_CCOBn_MASK                   FTFE_FCCOB_CCOBn_MASK
#define FTFx_FCCOB_CCOBn_SHIFT                  FTFE_FCCOB_CCOBn_SHIFT
#define FTFx_FCCOB_CCOBn_WIDTH                  FTFE_FCCOB_CCOBn_WIDTH
#define FTFx_FCCOB_CCOBn(x)                     FTFE_FCCOB_CCOBn(x)
/* FPROT Bit Fields */
#define FTFx_FPROT_PROT_MASK                    FTFE_FPROT_PROT_MASK
#define FTFx_FPROT_PROT_SHIFT                   FTFE_FPROT_PROT_SHIFT
#define FTFx_FPROT_PROT_WIDTH                   FTFE_FPROT_PROT_WIDTH
#define FTFx_FPROT_PROT(x)                      FTFE_FPROT_PROT(x)
/* FEPROT Bit Fields */
#define FTFx_FEPROT_EPROT_MASK                  FTFE_FEPROT_EPROT_MASK
#define FTFx_FEPROT_EPROT_SHIFT                 FTFE_FEPROT_EPROT_SHIFT
#define FTFx_FEPROT_EPROT_WIDTH                 FTFE_FEPROT_EPROT_WIDTH
#define FTFx_FEPROT_EPROT(x)                    FTFE_FEPROT_EPROT(x)
/* FDPROT Bit Fields */
#define FTFx_FDPROT_DPROT_MASK                  FTFE_FDPROT_DPROT_MASK
#define FTFx_FDPROT_DPROT_SHIFT                 FTFE_FDPROT_DPROT_SHIFT
#define FTFx_FDPROT_DPROT_WIDTH                 FTFE_FDPROT_DPROT_WIDTH
#define FTFx_FDPROT_DPROT(x)                    FTFE_FDPROT_DPROT(x)
/* FERSTAT Bit Fields */
#ifdef FTFx_FERSTAT
#define FTFx_FERSTAT_DFDIF_MASK                 FTFE_FERSTAT_DFDIF_MASK
#define FTFx_FERSTAT_DFDIF_SHIFT                FTFE_FERSTAT_DFDIF_SHIFT
#define FTFxFERSTAT_DFDIF_WIDTH                 FTFE_FERSTAT_DFDIF_WIDTH
#define FTFx_FERSTAT_DFDIF(x)                   FTFE_FERSTAT_DFDIF(x)
#endif
/* FERCNFG Bit Fields */
#ifdef FTFx_FERCNFG
#define FTFx_FERCNFG_DFDIE_MASK                 FTFE_FERCNFG_DFDIE_MASK
#define FTFx_FERCNFG_DFDIE_SHIFT                FTFE_FERCNFG_DFDIE_SHIFT
#define FTFx_FERCNFG_DFDIE_WIDTH                FTFE_FERCNFG_DFDIE_WIDTH
#define FTFx_FERCNFG_DFDIE(x)                   FTFE_FERCNFG_DFDIE(x)
#define FTFx_FERCNFG_FDFD_MASK                  FTFE_FERCNFG_FDFD_MASK
#define FTFx_FERCNFG_FDFD_SHIFT                 FTFE_FERCNFG_FDFD_SHIFT
#define FTFx_FERCNFG_FDFD_WIDTH                 FTFE_FERCNFG_FDFD_WIDTH
#define FTFx_FERCNFG_FDFD(x)                    FTFE_FERCNFG_FDFD(x)
#endif
/*******************************************************************************
 * FTFC
 *******************************************************************************/
#elif defined(FTFC)
#define FTFx_BASE                               FTFC_BASE
#define FTFx_FSTAT                              FTFC->FSTAT
#define FTFx_FCNFG                              FTFC->FCNFG
#define FTFx_FSEC                               FTFC->FSEC
#define FTFx_FOPT                               FTFC->FOPT
#define FTFx_FCCOB3                             FTFC->FCCOB[0]
#define FTFx_FCCOB2                             FTFC->FCCOB[1]
#define FTFx_FCCOB1                             FTFC->FCCOB[2]
#define FTFx_FCCOB0                             FTFC->FCCOB[3]
#define FTFx_FCCOB7                             FTFC->FCCOB[4]
#define FTFx_FCCOB6                             FTFC->FCCOB[5]
#define FTFx_FCCOB5                             FTFC->FCCOB[6]
#define FTFx_FCCOB4                             FTFC->FCCOB[7]
#define FTFx_FCCOBB                             FTFC->FCCOB[8]
#define FTFx_FCCOBA                             FTFC->FCCOB[9]
#define FTFx_FCCOB9                             FTFC->FCCOB[10]
#define FTFx_FCCOB8                             FTFC->FCCOB[11]
#define FTFx_FPROT3                             FTFC->FPROT[0]
#define FTFx_FPROT2                             FTFC->FPROT[1]
#define FTFx_FPROT1                             FTFC->FPROT[2]
#define FTFx_FPROT0                             FTFC->FPROT[3]
#define FTFx_FEPROT                             FTFC->FEPROT
#define FTFx_FDPROT                             FTFC->FDPROT
#define FTFx_FCSESTAT                           FTFC->FCSESTAT
#ifdef  FTFC_FERSTAT
#define FTFx_FERSTAT                            FTFC_FERSTAT
#endif
#ifdef  FTFC_FERCNFG
#define FTFx_FERCNFG                            FTFC_FERCNFG
#endif
/* FSTAT Bit Fields */
#define FTFx_FSTAT_MGSTAT0_MASK                 FTFC_FSTAT_MGSTAT0_MASK
#define FTFx_FSTAT_MGSTAT0_SHIFT                FTFC_FSTAT_MGSTAT0_SHIFT
#define FTFx_FSTAT_MGSTAT0_WIDTH                FTFC_FSTAT_MGSTAT0_WIDTH
#define FTFx_FSTAT_MGSTAT0(x)                   FTFC_FSTAT_MGSTAT0(x)
#define FTFx_FSTAT_FPVIOL_MASK                  FTFC_FSTAT_FPVIOL_MASK
#define FTFx_FSTAT_FPVIOL_SHIFT                 FTFC_FSTAT_FPVIOL_SHIFT
#define FTFx_FSTAT_FPVIOL_WIDTH                 FTFC_FSTAT_FPVIOL_WIDTH
#define FTFx_FSTAT_FPVIOL(x)                    FTFC_FSTAT_FPVIOL(x)
#define FTFx_FSTAT_ACCERR_MASK                  FTFC_FSTAT_ACCERR_MASK
#define FTFx_FSTAT_ACCERR_SHIFT                 FTFC_FSTAT_ACCERR_SHIFT
#define FTFx_FSTAT_ACCERR_WIDTH                 FTFC_FSTAT_ACCERR_WIDTH
#define FTFx_FSTAT_ACCERR(x)                    FTFC_FSTAT_ACCERR(x)
#define FTFx_FSTAT_RDCOLERR_MASK                FTFC_FSTAT_RDCOLERR_MASK
#define FTFx_FSTAT_RDCOLERR_SHIFT               FTFC_FSTAT_RDCOLERR_SHIFT
#define FTFx_FSTAT_RDCOLERR_WIDTH               FTFC_FSTAT_RDCOLERR_WIDTH
#define FTFx_FSTAT_RDCOLERR(x)                  FTFC_FSTAT_RDCOLERR(x)
#define FTFx_FSTAT_CCIF_MASK                    FTFC_FSTAT_CCIF_MASK
#define FTFx_FSTAT_CCIF_SHIFT                   FTFC_FSTAT_CCIF_SHIFT
#define FTFx_FSTAT_CCIF_WIDTH                   FTFC_FSTAT_CCIF_WIDTH
#define FTFx_FSTAT_CCIF(x)                      FTFC_FSTAT_CCIF(x)
/* FCNFG Bit Fields */
#define FTFx_FCNFG_EEERDY_MASK                  FTFC_FCNFG_EEERDY_MASK
#define FTFx_FCNFG_EEERDY_SHIFT                 FTFC_FCNFG_EEERDY_SHIFT
#define FTFx_FCNFG_EEERDY_WIDTH                 FTFC_FCNFG_EEERDY_WIDTH
#define FTFx_FCNFG_EEERDY(x)                    FTFC_FCNFG_EEERDY(x)
#define FTFx_FCNFG_RAMRDY_MASK                  FTFC_FCNFG_RAMRDY_MASK
#define FTFx_FCNFG_RAMRDY_SHIFT                 FTFC_FCNFG_RAMRDY_SHIFT
#define FTFx_FCNFG_RAMRDY_WIDTH                 FTFC_FCNFG_RAMRDY_WIDTH
#define FTFx_FCNFG_RAMRDY(x)                    FTFC_FCNFG_RAMRDY(x)
#define FTFx_FCNFG_ERSSUSP_MASK                 FTFC_FCNFG_ERSSUSP_MASK
#define FTFx_FCNFG_ERSSUSP_SHIFT                FTFC_FCNFG_ERSSUSP_SHIFT
#define FTFx_FCNFG_ERSSUSP_WIDTH                FTFC_FCNFG_ERSSUSP_WIDTH
#define FTFx_FCNFG_ERSSUSP(x)                   FTFC_FCNFG_ERSSUSP(x)
#define FTFx_FCNFG_ERSAREQ_MASK                 FTFC_FCNFG_ERSAREQ_MASK
#define FTFx_FCNFG_ERSAREQ_SHIFT                FTFC_FCNFG_ERSAREQ_SHIFT
#define FTFx_FCNFG_ERSAREQ_WIDTH                FTFC_FCNFG_ERSAREQ_WIDTH
#define FTFx_FCNFG_ERSAREQ(x)                   FTFC_FCNFG_ERSAREQ(x)
#define FTFx_FCNFG_RDCOLLIE_MASK                FTFC_FCNFG_RDCOLLIE_MASK
#define FTFx_FCNFG_RDCOLLIE_SHIFT               FTFC_FCNFG_RDCOLLIE_SHIFT
#define FTFx_FCNFG_RDCOLLIE_WIDTH               FTFC_FCNFG_RDCOLLIE_WIDTH
#define FTFx_FCNFG_RDCOLLIE(x)                  FTFC_FCNFG_RDCOLLIE(x)
#define FTFx_FCNFG_CCIE_MASK                    FTFC_FCNFG_CCIE_MASK
#define FTFx_FCNFG_CCIE_SHIFT                   FTFC_FCNFG_CCIE_SHIFT
#define FTFx_FCNFG_CCIE_WIDTH                   FTFC_FCNFG_CCIE_WIDTH
#define FTFx_FCNFG_CCIE(x)                      FTFC_FCNFG_CCIE(x)
/* FSEC Bit Fields */
#define FTFx_FSEC_SEC_MASK                      FTFC_FSEC_SEC_MASK
#define FTFx_FSEC_SEC_SHIFT                     FTFC_FSEC_SEC_SHIFT
#define FTFx_FSEC_SEC_WIDTH                     FTFC_FSEC_SEC_WIDTH
#define FTFx_FSEC_SEC(x)                        FTFC_FSEC_SEC(x)
#define FTFx_FSEC_FSLACC_MASK                   FTFC_FSEC_FSLACC_MASK
#define FTFx_FSEC_FSLACC_SHIFT                  FTFC_FSEC_FSLACC_SHIFT
#define FTFx_FSEC_FSLACC_WIDTH                  FTFC_FSEC_FSLACC_WIDTH
#define FTFx_FSEC_FSLACC(x)                     FTFC_FSEC_FSLACC(x)
#define FTFx_FSEC_MEEN_MASK                     FTFC_FSEC_MEEN_MASK
#define FTFx_FSEC_MEEN_SHIFT                    FTFC_FSEC_MEEN_SHIFT
#define FTFx_FSEC_MEEN_WIDTH                    FTFC_FSEC_MEEN_WIDTH
#define FTFx_FSEC_MEEN(x)                       FTFC_FSEC_MEEN(x)
#define FTFx_FSEC_KEYEN_MASK                    FTFC_FSEC_KEYEN_MASK
#define FTFx_FSEC_KEYEN_SHIFT                   FTFC_FSEC_KEYEN_SHIFT
#define FTFx_FSEC_KEYEN_WIDTH                   FTFC_FSEC_KEYEN_WIDTH
#define FTFx_FSEC_KEYEN(x)                      FTFC_FSEC_KEYEN(x)
/* FOPT Bit Fields */
#define FTFx_FOPT_OPT_MASK                      FTFC_FOPT_OPT_MASK
#define FTFx_FOPT_OPT_SHIFT                     FTFC_FOPT_OPT_SHIFT
#define FTFx_FOPT_OPT_WIDTH                     FTFC_FOPT_OPT_WIDTH
#define FTFx_FOPT_OPT(x)                        FTFC_FOPT_OPT(x)
/* FCCOB Bit Fields */
#define FTFx_FCCOB_CCOBn_MASK                   FTFC_FCCOB_CCOBn_MASK
#define FTFx_FCCOB_CCOBn_SHIFT                  FTFC_FCCOB_CCOBn_SHIFT
#define FTFx_FCCOB_CCOBn_WIDTH                  FTFC_FCCOB_CCOBn_WIDTH
#define FTFx_FCCOB_CCOBn(x)                     FTFC_FCCOB_CCOBn(x)
/* FPROT Bit Fields */
#define FTFx_FPROT_PROT_MASK                    FTFC_FPROT_PROT_MASK
#define FTFx_FPROT_PROT_SHIFT                   FTFC_FPROT_PROT_SHIFT
#define FTFx_FPROT_PROT_WIDTH                   FTFC_FPROT_PROT_WIDTH
#define FTFx_FPROT_PROT(x)                      FTFC_FPROT_PROT(x)
/* FEPROT Bit Fields */
#define FTFx_FEPROT_EPROT_MASK                  FTFC_FEPROT_EPROT_MASK
#define FTFx_FEPROT_EPROT_SHIFT                 FTFC_FEPROT_EPROT_SHIFT
#define FTFx_FEPROT_EPROT_WIDTH                 FTFC_FEPROT_EPROT_WIDTH
#define FTFx_FEPROT_EPROT(x)                    FTFC_FEPROT_EPROT(x)
/* FDPROT Bit Fields */
#define FTFx_FDPROT_DPROT_MASK                  FTFC_FDPROT_DPROT_MASK
#define FTFx_FDPROT_DPROT_SHIFT                 FTFC_FDPROT_DPROT_SHIFT
#define FTFx_FDPROT_DPROT_WIDTH                 FTFC_FDPROT_DPROT_WIDTH
#define FTFx_FDPROT_DPROT(x)                    FTFC_FDPROT_DPROT(x)
/* FCSESTAT Bit Fields */
#define FTFX_FCSESTAT_IDB_MASK                  FTFC_FCSESTAT_IDB_MASK
#define FTFX_FCSESTAT_IDB_SHIFT                 FTFC_FCSESTAT_IDB_SHIFT
#define FTFX_FCSESTAT_IDB_WIDTH                 FTFC_FCSESTAT_IDB_WIDTH
#define FTFX_FCSESTAT_IDB(x)                    FTFC_FCSESTAT_IDB(x)
#define FTFX_FCSESTAT_EDB_MASK                  FTFC_FCSESTAT_EDB_MASK
#define FTFX_FCSESTAT_EDB_SHIFT                 FTFC_FCSESTAT_EDB_SHIFT
#define FTFX_FCSESTAT_EDB_WIDTH                 FTFC_FCSESTAT_EDB_WIDTH
#define FTFX_FCSESTAT_EDB(x)                    FTFC_FCSESTAT_EDB(x)
#define FTFX_FCSESTAT_RIN_MASK                  FTFC_FCSESTAT_RIN_MASK
#define FTFX_FCSESTAT_RIN_SHIFT                 FTFC_FCSESTAT_RIN_SHIFT
#define FTFX_FCSESTAT_RIN_WIDTH                 FTFC_FCSESTAT_RIN_WIDTH
#define FTFX_FCSESTAT_RIN(x)                    FTFC_FCSESTAT_RIN(x)
#define FTFX_FCSESTAT_BOK_MASK                  FTFC_FCSESTAT_BOK_MASK
#define FTFX_FCSESTAT_BOK_SHIFT                 FTFC_FCSESTAT_BOK_SHIFT
#define FTFX_FCSESTAT_BOK_WIDTH                 FTFC_FCSESTAT_BOK_WIDTH
#define FTFX_FCSESTAT_BOK(x)                    FTFC_FCSESTAT_BOK(x)
#define FTFX_FCSESTAT_BFN_MASK                  FTFC_FCSESTAT_BFN_MASK
#define FTFX_FCSESTAT_BFN_SHIFT                 FTFC_FCSESTAT_BFN_SHIFT
#define FTFX_FCSESTAT_BFN_WIDTH                 FTFC_FCSESTAT_BFN_WIDTH
#define FTFX_FCSESTAT_BFN(x)                    FTFC_FCSESTAT_BFN(x)
#define FTFX_FCSESTAT_BIN_MASK                  FTFC_FCSESTAT_BIN_MASK
#define FTFX_FCSESTAT_BIN_SHIFT                 FTFC_FCSESTAT_BIN_SHIFT
#define FTFX_FCSESTAT_BIN_WIDTH                 FTFC_FCSESTAT_BIN_WIDTH
#define FTFX_FCSESTAT_BIN(x)                    FTFC_FCSESTAT_BIN(x)
#define FTFX_FCSESTAT_SB_MASK                   FTFC_FCSESTAT_SB_MASK
#define FTFX_FCSESTAT_SB_SHIFT                  FTFC_FCSESTAT_SB_SHIFT
#define FTFX_FCSESTAT_SB_WIDTH                  FTFC_FCSESTAT_SB_WIDTH
#define FTFX_FCSESTAT_SB(x)                     FTFC_FCSESTAT_SB(x)
#define FTFX_FCSESTAT_BSY_MASK                  FTFC_FCSESTAT_BSY_MASK
#define FTFX_FCSESTAT_BSY_SHIFT                 FTFC_FCSESTAT_BSY_SHIFT
#define FTFX_FCSESTAT_BSY_WIDTH                 FTFC_FCSESTAT_BSY_WIDTH
#define FTFX_FCSESTAT_BSY(x)                    FTFC_FCSESTAT_BSY(x)
/* FERSTAT Bit Fields */
#ifdef FTFx_FERSTAT
#define FTFx_FERSTAT_DFDIF_MASK                 FTFC_FERSTAT_DFDIF_MASK
#define FTFx_FERSTAT_DFDIF_SHIFT                FTFC_FERSTAT_DFDIF_SHIFT
#define FTFxFERSTAT_DFDIF_WIDTH                 FTFC_FERSTAT_DFDIF_WIDTH
#define FTFx_FERSTAT_DFDIF(x)                   FTFC_FERSTAT_DFDIF(x)
#endif
/* FERCNFG Bit Fields */
#ifdef FTFx_FERCNFG
#define FTFx_FERCNFG_DFDIE_MASK                 FTFC_FERCNFG_DFDIE_MASK
#define FTFx_FERCNFG_DFDIE_SHIFT                FTFC_FERCNFG_DFDIE_SHIFT
#define FTFx_FERCNFG_DFDIE_WIDTH                FTFC_FERCNFG_DFDIE_WIDTH
#define FTFx_FERCNFG_DFDIE(x)                   FTFC_FERCNFG_DFDIE(x)
#define FTFx_FERCNFG_FDFD_MASK                  FTFC_FERCNFG_FDFD_MASK
#define FTFx_FERCNFG_FDFD_SHIFT                 FTFC_FERCNFG_FDFD_SHIFT
#define FTFx_FERCNFG_FDFD_WIDTH                 FTFC_FERCNFG_FDFD_WIDTH
#define FTFx_FERCNFG_FDFD(x)                    FTFC_FERCNFG_FDFD(x)
#endif

#else
#endif


#define CLEAR_FTFx_FSTAT_ERROR_BITS     FTFx_FSTAT = (uint8_t)(FTFx_FSTAT_FPVIOL_MASK \
                                                               | FTFx_FSTAT_ACCERR_MASK \
                                                               | FTFx_FSTAT_RDCOLERR_MASK)

 /* Word size 2 bytes */
#define FTFx_WORD_SIZE                    0x0002U

/* Longword size 4 bytes */
#define FTFx_LONGWORD_SIZE                0x0004U

/* Phrase size 8 bytes */
#define FTFx_PHRASE_SIZE                  0x0008U

/* Double-phrase size 16 bytes */
#define FTFx_DPHRASE_SIZE                 0x0010U

/* FCCOB offset address to store resource code */
#if (FSL_FEATURE_FLS_PF_BLOCK_WRITE_UNIT_SIZE == FTFx_PHRASE_SIZE)
    #define FTFx_RSRC_CODE_REG        FTFx_FCCOB4
#else
    #define FTFx_RSRC_CODE_REG        FTFx_FCCOB8
#endif

/*******************************************************************************
 * Flash hardware algorithm operation commands
 *******************************************************************************/
#define FTFx_VERIFY_BLOCK               0x00U
#define FTFx_VERIFY_SECTION             0x01U
#define FTFx_PROGRAM_CHECK              0x02U
#define FTFx_READ_RESOURCE              0x03U
#define FTFx_PROGRAM_LONGWORD           0x06U
#define FTFx_PROGRAM_PHRASE             0x07U
#define FTFx_ERASE_BLOCK                0x08U
#define FTFx_ERASE_SECTOR               0x09U
#define FTFx_PROGRAM_SECTION            0x0BU
#define FTFx_VERIFY_ALL_BLOCK           0x40U
#define FTFx_READ_ONCE                  0x41U
#define FTFx_PROGRAM_ONCE               0x43U
#define FTFx_ERASE_ALL_BLOCK            0x44U
#define FTFx_SECURITY_BY_PASS           0x45U
#define FTFx_PFLASH_SWAP                0x46U
#define FTFx_ERASE_ALL_BLOCK_UNSECURE   0x49U
#define FTFx_PROGRAM_PARTITION          0x80U
#define FTFx_SET_EERAM                  0x81U

/*!
 * @name PFlash swap control codes
 * @{
 */
/*! @brief Initialize Swap System control code */
#define FTFx_SWAP_SET_INDICATOR_ADDR    0x01U
/*! @brief Set Swap in Update State */
#define FTFx_SWAP_SET_IN_PREPARE        0x02U
/*! @brief Set Swap in Complete State */
#define FTFx_SWAP_SET_IN_COMPLETE       0x04U
/*! @brief  Report Swap Status */
#define FTFx_SWAP_REPORT_STATUS         0x08U
/*@}*/

/*!
 * @name PFlash swap states
 * @{
 */
/*! @brief  Uninitialized swap mode */
#define FTFx_SWAP_UNINIT                0x00U
/*! @brief  Ready swap mode */
#define FTFx_SWAP_READY                 0x01U
/*! @brief  Update swap mode */
#define FTFx_SWAP_UPDATE                0x02U
/*! @brief  Update-Erased swap mode */
#define FTFx_SWAP_UPDATE_ERASED         0x03U
/*! @brief  Complete swap mode */
#define FTFx_SWAP_COMPLETE              0x04U
/*@}*/

/*! @brief Resume wait count used in FlashResume function */
#define RESUME_WAIT_CNT                 0x20U

#if (FSL_FEATURE_FLS_IS_FTFE == 1U)
    #define DFLASH_IFR_READRESOURCE_ADDRESS        0x8003F8U
#else /* FSL_FEATURE_FLASH_IS_FTFL == 1 or FSL_FEATURE_FLASH_IS_FTFA == 1 */
    #define DFLASH_IFR_READRESOURCE_ADDRESS        0x8000FCU
#endif

#define GET_BIT_0_7(value)              ((uint8_t)(((uint32_t)(value)) & 0xFFU))
#define GET_BIT_8_15(value)             ((uint8_t)((((uint32_t)(value))>>8) & 0xFFU))
#define GET_BIT_16_23(value)            ((uint8_t)((((uint32_t)(value))>>16) & 0xFFU))
#define GET_BIT_24_31(value)            ((uint8_t)(((uint32_t)(value))>>24))

/* Flash security status */
#define FLASH_SECURITY_STATE_KEYEN                 0x80U
#define FLASH_SECURITY_STATE_UNSECURED             0x02U

/* CSEc user key size */
#define CSE_KEY_SIZE_CODE_MAX                    0x03U

/*!
 * @addtogroup c90tfs_flash_driver
 * @{
 */

/*******************************************************************************
 * Return Code Definition for FTFx SSD
 *******************************************************************************/
/*!
 * @brief Return Code Definition for FTFx SSD
 *
 * Implements: flash_drv_status_t_Class
 */
typedef enum
{
    FTFx_OK             = 0x0000U,    /*!< Function executes successfully */
    FTFx_ERR_MGSTAT0    = 0x0001U,    /*!< MGSTAT0 error */
    FTFx_ERR_PVIOL      = 0x0010U,    /*!< Protection violation */
    FTFx_ERR_ACCERR     = 0x0020U,    /*!< Flash Access error */
    FTFx_ERR_RDCOLERR   = 0x0040U,    /*!< Read Collision Error */
    FTFx_ERR_CHANGEPROT = 0x0100U,    /*!< Cannot change protection status */
    FTFx_ERR_NOEEE      = 0x0200U,    /*!< FlexRAM is not set for EEPROM use */
    FTFx_ERR_EFLASHONLY = 0x0400U,    /*!< FlexNVM is set for full EEPROM backup */
    FTFx_ERR_RAMRDY     = 0x0800U,    /*!< Programming acceleration RAM is not available */
    FTFx_ERR_RANGE      = 0x1000U,    /*!< Address is out of the valid range */
    FTFx_ERR_SIZE       = 0x2000U,    /*!< Misaligned size */
    FTFx_ERR_PARAM      = 0x4000U     /*!< Invalid parameter */
} flash_drv_status_t;

/*!
 * @brief FlexRAM Function control Code
 *
 * Implements: flash_flexRAM_function_control_code_t_Class
 */
typedef enum
{
    EEE_ENABLE                              = 0x00U,    /*!< Make FlexRAM available for emulated EEPROM */
    EEE_QUICK_WRITE                         = 0x55U,    /*!< Make FlexRAM available for EEPROM quick writes */
    EEE_STATUS_QUERY                        = 0x77U,    /*!< EEPROM quick write status query */
    EEE_COMPLETE_INTERRUPT_QUICK_WRITE      = 0xAAU,    /*!< Complete interrupted EEPROM quick write process */
    EEE_DISABLE                             = 0xFFU,    /*!< Make FlexRAM available as RAM */
} flash_flexRam_function_control_code_t;

/*!
 * @name Flash security status
 * @{
 */
/*! @brief  Flash currently not in secure state */
#define FLASH_NOT_SECURE                   0x01U
/*! @brief  Flash is secured and backdoor key access enabled */
#define FLASH_SECURE_BACKDOOR_ENABLED      0x02U
/*! @brief  Flash is secured and backdoor key access disabled */
#define FLASH_SECURE_BACKDOOR_DISABLED     0x04U
/*@}*/

/*******************************************************************************
 * CallBack function period
 *******************************************************************************/
#ifndef FLASH_CALLBACK_CS
/*! @brief  Callback period count for FlashCheckSum */
#define FLASH_CALLBACK_CS               0x0AU
#endif

/*******************************************************************************
 * Null Callback function definition
 *******************************************************************************/
/*!
 * @name Null Callback function definition
 * @{
 */
/*! @brief  Null callback */
#define NULL_CALLBACK                   ((flash_callback_t)0xFFFFFFFFU)
/*! @brief  Null swap callback */
#define NULL_SWAP_CALLBACK              ((flash_swap_callback_t)0xFFFFFFFFU)
/*@}*/

/*******************************************************************************
 * Callback function prototype
 *******************************************************************************/
/*! @brief Call back function pointer data type */
typedef void (* flash_callback_t)(void);
/*! @brief Swap call back function pointer data type */
typedef bool (* flash_swap_callback_t)(uint8_t function);

/*******************************************************************************
 * Flash SSD Configuration Structure
 *******************************************************************************/
/*!
 * @brief Flash User Configuration Structure
 *
 * Implements: flash_user_config_t_Class
 */
typedef struct
{
    uint32_t      PFlashBase;            /*!< The base address of P-Flash memory */
    uint32_t      PFlashSize;            /*!< The size in byte of P-Flash memory */
    uint32_t      DFlashBase;            /*!< For FlexNVM device, this is the base address of D-Flash memory
                                              (FlexNVM memory); For non-FlexNVM device, this field is unused */
    uint32_t      EERAMBase;             /*!< The base address of FlexRAM (for FlexNVM device)
                                              or acceleration RAM memory (for non-FlexNVM device) */
    flash_callback_t      CallBack;      /*!< Call back function to service the time critical events */
} flash_user_config_t;

/*!
 * @brief Flash SSD Configuration Structure
 *
 * The structure includes the static parameters for C90TFS/FTFx which are
 * device-dependent. The fields including
 * PFlashBlockBase, PFlashBlockSize, DFlashBlockBase, EERAMBlockBase,
 * and CallBack are passed via flash_user_config_t.
 * The rest of parameters such as DFlashBlockSize, and EEEBlockSize will be
 * initialized in FlashInit() automatically.
 *
 * Implements: flash_ssd_config_t_Class
 */
typedef struct
{
    uint32_t      PFlashBase;          /*!< The base address of P-Flash memory */
    uint32_t      PFlashSize;          /*!< The size in byte of P-Flash memory */
    uint32_t      DFlashBase;          /*!< For FlexNVM device, this is the base address of D-Flash memory (FlexNVM memory);
                                            For non-FlexNVM device, this field is unused */
    uint32_t      DFlashSize;          /*!< For FlexNVM device, this is the size in byte of area
                                            which is used as D-Flash from FlexNVM memory;
                                            For non-FlexNVM device, this field is unused */
    uint32_t      EERAMBase;           /*!< The base address of FlexRAM (for FlexNVM device)
                                            or acceleration RAM memory (for non-FlexNVM device) */
    uint32_t      EEESize;             /*!< For FlexNVM device, this is the size in byte of EEPROM area which was partitioned
                                            from FlexRAM; For non-FlexNVM device, this field is unused */
    flash_callback_t      CallBack;    /*!< Call back function to service the time critical events */
} flash_ssd_config_t;

/*!
 * @brief EEPROM status structure
 *
 * Implements: flash_eeprom_status_t_Class
 */
typedef struct
{
    uint8_t      brownOutCode;              /*!< Brown-out detection code */
    uint16_t     numOfRecordReqMaintain;    /*!< Number of EEPROM quick write records requiring maintenance */
    uint16_t     sectorEraseCount;          /*!< EEPROM sector erase count */
} flash_eeprom_status_t;
/*******************************************************************************
 * Function Pointer
 *******************************************************************************/
/*! @brief FlashCommandSequence function pointer */
typedef flash_drv_status_t (*flash_command_sequence_t)(const flash_ssd_config_t * pSSDConfig);

/*******************************************************************************
 * Function Prototypes for Flash SSD
 *******************************************************************************/
/*!
 * @name C90TFS Flash driver APIs
 * @{
 */

#if defined(__cplusplus)
extern "C" {
#endif


/*!
 * @brief Initializes Flash.
 *
 * This API initializes Flash module by clearing status error
 * bit and reporting the memory configuration via SSD configuration structure.
 *
 * @param[in] pUserConf The user configuration structure pointer.
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @return operation status
 *        - FTFx_OK:    Operation was successful.
 */
flash_drv_status_t FlashInit(const flash_user_config_t * const pUserConf, \
                             flash_ssd_config_t * const pSSDConfig);

/*!
 * @brief Flash command sequence.
 *
 * This API is used to perform command write sequence on  Flash.
 * It is internal function, called by driver APIs only.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_PVIOL:      Operation failed due to a protection violation.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 *        - FTFx_FSTAT_RDCOLERR_MASK:    Operation failed due to a read collision error.
 */
START_FUNCTION_DECLARATION_RAMSECTION
flash_drv_status_t FlashCommandSequence(const flash_ssd_config_t * pSSDConfig)
END_FUNCTION_DECLARATION_RAMSECTION
/*!
 * @brief P-Flash get protection.
 *
 * This API retrieves the current P-Flash protection status. Considering
 * the time consumption for getting protection is very low and even can
 * be ignored. It is not necessary to utilize the Callback function to
 * support the time-critical events.
 *
 * @param[out] protectStatus To return the current value of the P-Flash Protection.
 *                          Each bit is corresponding to protection of 1/32 of the
 *                          total P-Flash. The least significant bit is corresponding
 *                          to the lowest address area of P-Flash. The most significant bit
 *                          is corresponding to the highest address area of P-Flash
 *                          and so on. There are two possible cases as below:
 *                          - 0: this area is protected.
 *                          - 1: this area is unprotected.
 */
void PFlashGetProtection(uint32_t* protectStatus);

/*!
 * @brief P-Flash set protection.
 *
 * This API sets the P-Flash protection to the intended protection status.
 * Setting P-Flash protection status is subject to a protection, transition
 * restriction. If there is a setting violation, it returns
 * an error code and the current protection status will not be changed.
 *
 * @param[in] protectStatus The expected protect status user wants to set to
 *                          P-Flash protection register. Each bit is corresponding
 *                          to protection of 1/32 of the total P-Flash. The least
 *                          significant bit is corresponding to the lowest
 *                          address area of P-Flash. The most significant bit
 *                          is corresponding to the highest address area of P-
 *                          Flash, and so on. There are two possible cases as shown below:
 *                          - 0: this area is protected.
 *                          - 1: this area is unprotected.
 * @return operation status
 *        - FTFx_OK:                Operation was successful.
 *        - FTFx_ERR_CHANGEPROT:    Operation failed due to protection status was not changed.
 */
flash_drv_status_t PFlashSetProtection(uint32_t protectStatus);

/*!
 * @brief Flash get security state.
 *
 * This API retrieves the current Flash security status, including
 * the security enabling state and the back door key enabling state.
 *
 * @param[out] securityState To return the current security status code.
 *                          - FLASH_NOT_SECURE (0x01U): Flash currently not in secure state
 *                          - FLASH_SECURE_BACKDOOR_ENABLED (0x02U): Flash is secured and
 *                          back door key access enabled
 *                          - FLASH_SECURE_BACKDOOR_DISABLED (0x04U): Flash is secured and
 *                          back door key access disabled.
 */
void FlashGetSecurityState(uint8_t* securityState);

/*!
 * @brief Flash security bypass.
 *
 * This API un-secures the device by comparing the user's provided back
 * door key with the ones in the Flash Configuration Field. If they are
 * matched, the security is released. Otherwise, an error code is returned.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] keyBuffer Point to the user buffer containing the back door key.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:            Operation was successful.
 *        - FTFx_ERR_ACCERR:    Operation failed due to an access error.
 */
flash_drv_status_t FlashSecurityBypass(const flash_ssd_config_t * pSSDConfig, \
                                       const uint8_t* keyBuffer, \
                                       flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Flash erase all blocks.
 *
 * This API erases all Flash memory, initializes the FlexRAM, verifies
 * all memory contents, and then releases the MCU security.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_PVIOL:      Operation failed due to a protection violation.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */

flash_drv_status_t FlashEraseAllBlock(const flash_ssd_config_t * pSSDConfig, \
                                      flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Flash verify all blocks.
 *
 * This function checks to see if the P-Flash and/or D-Flash, EEPROM
 * backup area, and D-Flash IFR have been erased to the specified read
 * margin level, if applicable, and releases security if the readout passes.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] marginLevel Read Margin Choice as follows:
 *                         - marginLevel = 0x0U: use the Normal read level
 *                         - marginLevel = 0x1U: use the User read
 *                         - marginLevel = 0x2U: use the Factory read
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t FlashVerifyAllBlock(const flash_ssd_config_t * pSSDConfig, \
                                       uint8_t marginLevel, \
                                       flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Flash erase sector.
 *
 * This API erases one or more sectors in P-Flash or D-Flash memory.
 * This API always returns FTFx_OK if size provided by the user is
 * zero regardless of the input validation.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Address in the first sector to be erased.
 * @param[in] size Size to be erased in bytes. It is used to determine number of sectors to be erased.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 *
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_PVIOL:      Operation failed due to a protection violation.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 *        - FTFx_ERR_SIZE:       Operation failed due to misaligned size.
 */
flash_drv_status_t FlashEraseSector(const flash_ssd_config_t * pSSDConfig, \
                                    uint32_t dest, \
                                    uint32_t size, \
                                    flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Flash verify section.
 *
 * This API checks if a section of the P-Flash or the D-Flash memory
 * is erased to the specified read margin level.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Start address for the intended verify operation.
 * @param[in] number Number of alignment unit to be verified. Refer to corresponding
 *                   reference manual to get correct information of alignment constrain.
 * @param[in] marginLevel Read Margin Choice as follows:
 *                        - marginLevel = 0x0U: use Normal read level
 *                        - marginLevel = 0x1U: use the User read
 *                        - marginLevel = 0x2U: use the Factory read
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t FlashVerifySection(const flash_ssd_config_t * pSSDConfig, \
                                      uint32_t dest, \
                                      uint16_t number, \
                                      uint8_t marginLevel, \
                                      flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Flash erase suspend.
 *
 * This API is used to suspend a current operation of Flash erase sector command.
 * This function must be located in RAM memory or different Flash blocks which are
 * targeted for writing to avoid the RWW error.
 */
void FlashEraseSuspend(void);

/*!
 * @brief Flash erase resume.
 *
 * This API is used to resume a previous suspended operation of Flash erase sector command
 * This function must be located in RAM memory or different Flash blocks which are targeted
 * for writing to avoid RWW error.
 */
void FlashEraseResume(void);

/*!
 * @brief Flash read once.
 *
 * This API is used to read out a reserved 64 byte field located in the P-Flash IFR via given number
 * of record. See the corresponding reference manual to get the correct value of this number.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] recordIndex The record index will be read. It can be from 0x0U
 *                        to 0x7U or from 0x0U to 0xF according to specific derivative.
 * @param[in] pDataArray Pointer to the array to return the data read by the read once command.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 */
flash_drv_status_t FlashReadOnce(const flash_ssd_config_t * pSSDConfig, \
                                 uint8_t recordIndex, \
                                 uint8_t* pDataArray, \
                                 flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Flash program once.
 *
 * This API is used to program to a reserved 64 byte field located in the
 * P-Flash IFR via given number of record. See the corresponding reference manual
 * to get correct value of this number.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] recordIndex The record index will be read. It can be from 0x0U
 *                        to 0x7U or from 0x0U to 0xF according to specific derivative.
 * @param[in] pDataArray Pointer to the array from which data will be
 *                       taken for program once command.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t FlashProgramOnce(const flash_ssd_config_t * pSSDConfig, \
                                    uint8_t recordIndex, \
                                    const uint8_t* pDataArray, \
                                    flash_command_sequence_t pFlashCommandSequence);

#if FSL_FEATURE_FLS_HAS_READ_RESOURCE_CMD
/*!
 * @brief Flash read resource.
 *
 * This API is used to read data from special purpose memory in Flash memory module
 * including P-Flash IFR, swap IFR, D-Flash IFR space and version ID.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Start address for the intended read operation.
 * @param[out] pDataArray Pointer to the data returned by the read resource command.
 * @param[in] resourceSelectCode Read resource select code:
 *                               - 0: Flash IFR
 *                               - 1: Version ID
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 */
flash_drv_status_t FlashReadResource(const flash_ssd_config_t * pSSDConfig, \
                                     uint32_t dest, \
                                     uint8_t* pDataArray, \
                                     uint8_t resourceSelectCode, \
                                     flash_command_sequence_t pFlashCommandSequence);
#endif
/*!
 * @brief Flash program
 *
 * This API is used to program 4 consecutive bytes (for program long
 * word command) and 8 consecutive bytes (for program phrase command) on
 * P-Flash or D-Flash block. This API always returns FTFx_OK if size
 * provided by user is zero regardless of the input validation
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Start address for the intended program operation.
 * @param[in] size Size in byte to be programmed
 * @param[in] pData Pointer of source address from which data has to
 *                  be taken for program operation.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 *        - FTFx_ERR_SIZE:       Operation failed due to misaligned size.
 */
flash_drv_status_t FlashProgram(const flash_ssd_config_t * pSSDConfig, \
                                uint32_t dest, \
                                uint32_t size, \
                                const uint8_t* pData, \
                                flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Flash program check
 *
 * This API tests a previously programmed P-Flash or D-Flash long word
 * to see if it reads correctly at the specified margin level. This
 * API always returns FTFx_OK if size provided by user is zero
 * regardless of the input validation
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Start address for the intended program check operation.
 * @param[in] size Size in byte to check accuracy of program operation
 * @param[in] pExpectedData The pointer to the expected data.
 * @param[in] pFailAddr Returned the first aligned failing address.
 * @param[in] marginLevel Read margin choice as follows:
 *                        - marginLevel = 0x1U: read at User margin 1/0 level.
 *                        - marginLevel = 0x2U: read at Factory margin 1/0 level.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t FlashProgramCheck(const flash_ssd_config_t * pSSDConfig, \
                                     uint32_t dest, \
                                     uint32_t size, \
                                     const uint8_t* pExpectedData, \
                                     uint32_t* pFailAddr, \
                                     uint8_t marginLevel, \
                                     flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Calculates check sum.
 *
 * This API performs 32 bit sum of each byte data over a specified Flash
 * memory range without carry which provides rapid method for checking data integrity.
 * The callback time period of this API is determined via FLASH_CALLBACK_CS macro in the
 * SSD_FTFx_Common.h which is used as a counter value for the CallBack() function calling in
 * this API. This value can be changed as per the user requirement. User can change this value
 * to obtain the maximum permissible callback time period.
 * This API always returns FTFx_OK if size provided by user is zero regardless of the input
 * validation.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Start address of the Flash range to be summed.
 * @param[in] size Size in byte of the Flash range to be summed.
 * @param[in] pSum To return the sum value.
 * @return operation status
 *        - FTFx_OK:           Operation was successful.
 *        - FTFx_ERR_RANGE:    Operation failed due to addresses were out of the valid range.
 */
flash_drv_status_t FlashCheckSum(const flash_ssd_config_t * pSSDConfig, \
                                 uint32_t dest, \
                                 uint32_t size, \
                                 uint32_t* pSum);

#if FSL_FEATURE_FLS_HAS_PROGRAM_SECTION_CMD
/*!
 * @brief Flash program section
 *
 * This API will program the data found in the Section Program Buffer
 * to previously erased locations in the Flash memory. Data is preloaded into
 * the Section Program Buffer by writing to the acceleration Ram and FlexRam
 * while it is set to function as a RAM. The Section Program Buffer is limited
 * to the value of FlexRam divides by a ratio. Refer to the associate reference
 * manual to get correct value of this ratio.
 * For derivatives including swap feature, the swap indicator address is encountered
 * during FlashProgramSection, it is bypassed without setting FPVIOL but the content
 * are not be programmed. In addition, the content of source data used to program to
 * swap indicator will be re-initialized to 0xFF after completion of this command.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Start address for the intended program operation.
 * @param[in] number Number of alignment unit to be programmed. Refer to associate
 *                   reference manual to get correct value of this alignment constrain.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_PVIOL:      Operation failed due to a protection violation.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 *        - FTFx_ERR_RAMRDY:     Operation failed due to FlexRAM was not available for traditional RAM access.
 */
flash_drv_status_t FlashProgramSection(const flash_ssd_config_t * pSSDConfig, \
                                       uint32_t dest, \
                                       uint16_t number, \
                                       flash_command_sequence_t pFlashCommandSequence);
#endif

#if FSL_FEATURE_FLS_HAS_ERASE_BLOCK_CMD
/*!
 * @brief Flash erase block
 *
 * This API erases all addresses in an individual P-Flash or D-Flash block.
 * For the derivatives including multiply logical P-Flash or D-Flash blocks,
 * this API erases a single block in a single call.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Start address for the intended erase operation.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_PVIOL:      Operation failed due to a protection violation.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t FlashEraseBlock(const flash_ssd_config_t * pSSDConfig, \
                                   uint32_t dest, \
                                   flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Flash verify block
 *
 * This API checks to see  if an entire P-Flash or D-Flash block has been
 * erased to the specified margin level
 * For the derivatives including multiply logical P-Flash or D-Flash blocks,
 * this API erases a single block in a single call.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Start address for the intended verify operation.
 * @param[in] marginLevel Read Margin Choice as follows:
 *                        - marginLevel = 0x0U: use Normal read level
 *                        - marginLevel = 0x1U: use the User read
 *                        - marginLevel = 0x2U: use the Factory read
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t FlashVerifyBlock(const flash_ssd_config_t * pSSDConfig, \
                                    uint32_t dest, \
                                    uint8_t marginLevel, \
                                    flash_command_sequence_t pFlashCommandSequence);
#endif

#if FSL_FEATURE_FLS_HAS_FLEX_NVM
/*!
 * @brief EERAM get protection
 *
 * This API retrieves which EEPROM sections of FlexRAM are protected
 * against program and erase operations. Considering the time consumption
 * for getting protection is very low and even can be ignored, it is not necessary
 * to utilize the Callback function to support the time-critical events
 *
 * @param[out] protectStatus To return the current value of the EEPROM
 *                          Protection Register. Each bit is corresponding to
 *                          protection status of 1/8 of the total EEPROM
 *                          use. The least significant bit is corresponding to
 *                          the lowest address area of EEPROM. The most
 *                          significant bit is corresponding to the highest
 *                          address area of EEPROM and so on. There are
 *                          two possible cases as below:
 *                          - 0: this area is protected.
 *                          - 1: this area is unprotected.
 * @return operation status
 *        - FTFx_OK:           Operation was successful.
 *        - FTFx_ERR_NOEEE:    Operation failed due to FlexRAM is not available for EEPROM operation.
 */
flash_drv_status_t EERAMGetProtection(uint8_t* protectStatus);

/*!
 * @brief EERAM set protection
 *
 * This API sets protection to the intended protection status for EEPROM us
 * area of FlexRam. This is subject to a protection transition restriction.
 * If there is a setting violation, it returns failed information and
 * the current protection status will not be changed.
 *
 * @param[in] protectStatus The intended protection status value should be
 *                          written to the EEPROM Protection Register.
 *                          Each bit is corresponding to
 *                          protection status of 1/8 of the total EEPROM
 *                          use. The least significant bit is corresponding to
 *                          the lowest address area of EEPROM. The most
 *                          significant bit is corresponding to the highest
 *                          address area of EEPROM and so on. There are
 *                          two possible cases as below:
 *                          - 0: this area is protected.
 *                          - 1: this area is unprotected.
 * @return operation status
 *        - FTFx_OK:                Operation was successful.
 *        - FTFx_ERR_NOEEE:         Operation failed due to FlexRAM is not available for EEPROM operation.
 *        - FTFx_ERR_CHANGEPROT:    Operation failed due to protection status was not changed.
 */
flash_drv_status_t EERAMSetProtection(uint8_t protectStatus);

/*!
 * @brief Set FlexRAM function
 *
 * This function is used to change the function of the FlexRAM. When not partitioned for
 * emulated EEPROM, the FlexRAM is typically used as traditional RAM.
 * Otherwise, the FlexRam is typically used to store EEPROM data, the writing to EEPROM is normal write or
 * quick write.
 * In addition, this function may be used to get EEPROM status or complete interrupted EEPROM quick write process.
 * For example, after partitioning to have EEPROM backup, FlexRAM is used for EEPROM
 * use accordingly and if want to change FlexRAM to traditional RAM for FlashProgramSection() use, call this API
 * with the function control code is 0xFFU.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] flexRamFuncCode FlexRam function control code. It can be:
 *                            - 0x00U: Make FlexRAM available for emulated EEPROM.
 *                            - 0x55U: Make FlexRAM available for EEPROM quick writes.
 *                            - 0x77U: EEPROM quick write status query.
 *                            - 0xAAU: Complete interrupted EEPROM quick write process.
 *                            - 0xFFU: Make FlexRAM available as RAM.
 * @param[in] byteOfQuickWrite Number of FlexRAM bytes allocated for EEPROM quick writes. This parameter is only used for EEE_QUICK_WRITE command,
                               it should be 0 if the function is not used for EEEPROM quick write.
 * @param[out] pEEPROMStatus Pointer to the EEPROM status. This parameter is only used for EEE_STATUS_QUERY command,
                             it should be NULL if the function is not used for EEPROM status query.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:            Operation was successful.
 *        - FTFx_ERR_ACCERR:    Operation failed due to an access error.
 */
flash_drv_status_t SetFlexRamFunction(const flash_ssd_config_t * pSSDConfig, \
                                      flash_flexRam_function_control_code_t flexRamFuncCode, \
                                      uint16_t byteOfQuickWrite, \
                                      flash_eeprom_status_t * const pEEPROMStatus, \
                                      flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief EEPROM Emulator Write
 *
 * This API is used to write data to FlexRAM section which is partitioned
 * as EEPROM use for EEPROM operation. After data has been written to EEPROM
 * use section of FlexRAM, the EEPROM file system will create new data record
 * in EEPROM back-up area of FlexNVM in round-robin fashion.
 * There is no alignment constraint for destination and size parameters
 * provided by user. However, according to user's input provided, this
 * API will set priority to write to FlexRAM with following rules:
 * 32-bit writing is invoked if destination is 32 bit aligned and size
 * is not less than 32 bits.
 * 16-bit writing is invoked if destination is 16 bit aligned and size
 * is not less than 16 bits.
 * 8-bit writing is invoked if destination is 8 bit aligned and size is not less than 8 bits.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] dest Start address for the intended write operation.
 * @param[in] size Size in byte to be written.
 * @param[in] pData Pointer to source address from which data
 *                  has to be taken for writing operation.
 * @return operation status
 *        - FTFx_OK:           Operation was successful.
 *        - FTFx_ERR_RANGE:    Operation failed due to addresses were out of the valid range.
 *        - FTFx_ERR_NOEEE:    Operation failed due to an access error.
 *        - FTFx_ERR_PVIOL:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t EEEWrite(const flash_ssd_config_t * pSSDConfig, \
                            uint32_t dest, \
                            uint32_t size, \
                            const uint8_t* pData);

/*!
 * @brief Flash D/E-Flash Partition.
 *
 * This API prepares the FlexNVM block for use as D-Flash, EEPROM backup, or a combination
 * of both and initializes the FlexRAM.
 * In addition, this function is used to configure number of user keys and user key 'Verify Only' attribute if
 * CSEc is enabled.
 *
 * The single partition choice should be used through entire life time of a given
 * application to guarantee the Flash endurance and data retention of Flash module.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer
 * @param[in] EEEDataSizeCode EEPROM Data Size Code
 * @param[in] DEPartitionCode FlexNVM Partition Code
 * @param[in] uCSEcKeySize CSEc Key Size Code, it shouble be 0 if the function is not used for configuring CSEc part.
              It can be:
              - 0x00U: Number of User Keys is Zero
                       Number of Bytes (subtracts from the total 4K EEERAM space) is 0
              - 0x01U: Number of User Keys is 1 to 6 keys
                       Number of Bytes (subtracts from the total 4K EEERAM space) is 128 bytes
              - 0x02U: Number of User Keys is 1 to 12 keys
                       Number of Bytes (subtracts from the total 4K EEERAM space) is 256 bytes
              - 0x03U: Number of User Keys is 1 to 24 keys
                       Number of Bytes (subtracts from the total 4K EEERAM space) is 512 bytes
 * @param[in] uSFE Security Flag Extension, it shouble be false if the function is not used for configuring CSEc part.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t DEFlashPartition(const flash_ssd_config_t * pSSDConfig, \
                                    uint8_t uEEEDataSizeCode, \
                                    uint8_t uDEPartitionCode, \
                                    uint8_t uCSEcKeySize,     \
                                    bool uSFE,             \
                                    flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief D-Flash get protection.
 *
 * This API retrieves current P-Flash protection status. Considering the time consumption
 * for getting protection is very low and even can be ignored, it is not necessary to utilize
 * the Callback function to support the time-critical events.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer
 * @param[out] protectStatus To return the current value of the D-Flash Protection
 *                          Register. Each bit is corresponding to protection status
 *                          of 1/8 of the total D-Flash. The least significant bit is
 *                          corresponding to the lowest address area of D-Flash. The
 *                          most significant bit is corresponding to the highest address
 *                          area of D-Flash and so on. There are two possible cases as below:
 *                          - 0 : this area is protected.
 *                          - 1 : this area is unprotected.
 * @return operation status
 *        - FTFx_OK:                Operation was successful.
 *        - FTFx_ERR_EFLASHONLY:    Operation failed due to FlexNVM was not set for data flash.
 */
flash_drv_status_t DFlashGetProtection(const flash_ssd_config_t * pSSDConfig, \
                                       uint8_t* protectStatus);

/*!
 * @brief D-Flash set protection.
 *
 * This API sets the D-Flash protection to the intended protection status. Setting D-Flash
 * protection status is subject to a protection transition restriction. If there is a setting
 * violation, it returns failed information and the current protection status will not be changed.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer
 * @param[in] protectStatus The expected protect status user wants to set to D-Flash Protection
 *                          Register. Each bit is corresponding to protection status
 *                          of 1/8 of the total D-Flash. The least significant bit is
 *                          corresponding to the lowest address area of D-Flash. The
 *                          most significant bit is corresponding to the highest address
 *                          area of D-Flash and so on. There are two possible cases as below:
 *                          - 0 : this area is protected.
 *                          - 1 : this area is unprotected.
 * @return operation status
 *        - FTFx_OK:                Operation was successful.
 *        - FTFx_ERR_EFLASHONLY:    Operation failed due to FlexNVM was not set for data flash.
 *        - FTFx_ERR_CHANGEPROT:    Operation failed due to protection status was not changed.
 */
flash_drv_status_t DFlashSetProtection(const flash_ssd_config_t * pSSDConfig, \
                                       uint8_t protectStatus);
#endif /* End of FSL_FEATURE_FLS_HAS_FLEX_NVM */

#ifdef FSL_FEATURE_FLS_HAS_PF_BLOCK_SWAP
/*!
 * @brief Swaps between the two halves of the total logical P-Flash memory blocks in the memory map.
 *
 * The swap API provides to user with an ability to interfere in a swap progress by letting the
 * user code know about the swap state in each phase of the process. This is done via pSwapCallBack()
 * parameter. To stop at each intermediate swap state, set the return value of
 * this callback function to FALSE. To complete swap process within a single call,
 * set the return value of this function to TRUE.
 *
 * Erase the non-active swap indicator  somewhere in the
 * application code or in the swap call back function when swap system is in UPDATE state.
 *
 * In addition, if user does not want to use the swap call back parameter, pass the NULL_SWAP_CALLBACK
 * as a null pointer. In this situation, the PFlashSwap() behaves in the same way as setting the return
 * value of pSwapCallBack to TRUE and the user does not need to erase the non-active swap
 * indicator when the swap system is in UPDATE state.
 *
 * Below is an example to show how to implement a swap callback:
 * @code
 * bool PFlashSwapCallback(uint8_t currentSwapMode)
 * {
 *     switch (currentSwapMode)
 *     {
 *     case FTFx_SWAP_UNINI:
 *         Put your application-specific code here
 *         break;
 *     case FTFx_SWAP_READY:
 *         Put your application-specific code here
 *         break;
 *     case FTFx_SWAP_UPDATE:
 *         Put your application-specific code here (example: erase non-active swap indicator here)
 *         break;
 *     case FTFx_SWAP_UPDATE_ERASED:
 *         Put your application-specific code here (example: erase non-active swap indicator here)
 *         break;
 *     case FTFx_SWAP_COMPLETE:
 *         Put your application-specific code here
 *         break;
 *     default:
 *         break;
 *    }
 *    return TRUE; Return FALSE to stop at intermediate swap state
 * }
 * @endcode
 * The swap indicator provided by the user must be within the lower half of P-Flash block but not in the
 * Flash configuration area. If P-Flash block has two logical blocks, the swap indicator must be
 * in P-Flash block 0. If the P-Flash block has four logical blocks, the swap indicator can be in block
 * 0 or block 1. It must not be in the Flash configuration field.
 * The user must use the same swap indicator for all swap control code except report swap status once
 * swap system has been initialized. To refresh swap system to un-initialization state,
 * use the FlashEraseAllBlock() to clean up the swap environment.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer
 * @param[in] addr Address of swap indicator.
 * @param[in] pSwapCallback Callback to do specific task while the swapping is being performed
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t PFlashSwap(const flash_ssd_config_t * pSSDConfig, \
                              uint32_t addr, \
                              flash_swap_callback_t pSwapCallback, \
                              flash_command_sequence_t pFlashCommandSequence);

/*!
 * @brief Performs swap control command corresponding with the swap control code provided via the swapcmd parameter.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer
 * @param[in] addr Address of swap indicator.
 * @param[in] swapcmd Swap Control Code:
 *                    - 0x01U: Initialize Swap System
 *                    - 0x02U: Set Swap in Update State
 *                    - 0x04U: Set Swap in Complete Stat
 *                    - 0x08U: Report Swap Status
 * @param[in] pCurrentSwapMode Current Swap Mode:
 *                             - 0x00U: Uninitialized
 *                             - 0x01U: Ready
 *                             - 0x02U: Update
 *                             - 0x03U: Update-Erased
 *                             - 0x04U: Complete
 * @param[in] pCurrentSwapBlockStatus Current Swap Block Status indicates which program Flash block
 *                                    is currently located at relative Flash address 0x0_0000
 *                                    - 0x00U: Program Flash block 0
 *                                    - 0x01U: Program Flash block 1
 * @param[in] pNextSwapBlockStatus Next Swap Block Status indicates which program Flash block
 *                                 is located at relative Flash address 0x0_0000 after the next reset.
 *                                 - 0x00U: Program Flash block 0
 *                                 - 0x01U: Program Flash block 1
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t PFlashSwapCtl(const flash_ssd_config_t * pSSDConfig, \
                                 uint32_t addr, \
                                 uint8_t swapcmd, \
                                 uint8_t* pCurrentSwapMode, \
                                 uint8_t* pCurrentSwapBlockStatus, \
                                 uint8_t* pNextSwapBlockStatus, \
                                 flash_command_sequence_t pFlashCommandSequence);

#endif /* End of FSL_FEATURE_FLS_HAS_PF_BLOCK_SWAP */
#if FSL_FEATURE_FLS_HAS_ERASE_ALL_BLOCKS_UNSECURE_CMD
/*!
 * @brief Flash erase all blocks unsecure.
 *
 * This API erases all Flash memory, initializes the FlexRAM, verifies
 * all memory contents, and then releases the MCU security.
 *
 * @param[in] pSSDConfig The SSD configuration structure pointer.
 * @param[in] pFlashCommandSequence Pointer to the Flash command sequence function.
 * @return operation status
 *        - FTFx_OK:             Operation was successful.
 *        - FTFx_ERR_ACCERR:     Operation failed due to an access error.
 *        - FTFx_ERR_PVIOL:      Operation failed due to a protection violation.
 *        - FTFx_ERR_MGSTAT0:    Operation failed due to an error was detected during execution of an FTFx command.
 */
flash_drv_status_t FlashEraseAllBlockUnsecure (const flash_ssd_config_t * pSSDConfig, \
                                               flash_command_sequence_t pFlashCommandSequence);
#endif

#if defined(__cplusplus)
}
#endif

/*@}*/ /* End of C90TFS Flash driver APIs*/
/*! @}*/ /* End of addtogroup c90tfs_flash_driver */

#endif /* FSL_FLASH_DRIVER_C90TFS_H */
