/*!
 * @file        bmp561_flash_ctrl.h
 *
 * @brief       This file contains all the functions prototypes for the FLASH CTRL firmware library
 *
 * @version     V1.0.0
 *
 * @date        2025-01-01
 *
 * @attention
 *
 *  Copyright (C) 2025 Geehy Semiconductor
 *
 *  You may not use this file except in compliance with the
 *  GEEHY COPYRIGHT NOTICE (GEEHY SOFTWARE PACKAGE LICENSE).
 *
 *  The program is only for reference, which is distributed in the hope
 *  that it will be useful and instructional for customers to develop
 *  their software. Unless required by applicable law or agreed to in
 *  writing, the program is distributed on an "AS IS" BASIS, WITHOUT
 *  ANY WARRANTY OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the GEEHY SOFTWARE PACKAGE LICENSE for the governing permissions
 *  and limitations under the License.
 */

/* Define to prevent recursive inclusion */
#ifndef __BMP561_FLASH_CTRL_H
#define __BMP561_FLASH_CTRL_H

/* Includes */
#include "bmp561.h"
#include "bmp561_sysctrl.h"

#ifdef __cplusplus
  extern "C" {
#endif

/** @addtogroup Peripherals_Library Standard Peripheral Library
  @{
*/

/** @addtogroup FLASH_CTRL_Driver FLASH_CTRL Driver
  @{
*/

/** @addtogroup FLASH_CTRL_Enumerations Enumerations
  @{
*/

/**
 * @brief    FLASH option key status
 */
typedef enum
{
    FLASH_OPTKEY_WP_NOKEY         = 0x00,    /*!< Write protect */
    FLASH_OPTKEY_OPT0_UNLOCK      = 0x02,    /*!< Unlock Option byte 0 */
    FLASH_OPTKEY_OPT1_UNLOCK      = 0x04,    /*!< Unlock Option byte 1 */
    FLASH_OPTKEY_ERROR_LOCK       = 0x07,    /*!< Key error */
    FLASH_OPTKEY_ONLY_ONEKEY_EER0 = 0x01,    /*!< Only write one key */
    FLASH_OPTKEY_ONLY_ONEKEY_EER1 = 0x03,    /*!< Only write one key */
    FLASH_OPTKEY_ONLY_ONEKEY_EER2 = 0x05,    /*!< Only write one key */
    FLASH_OPTKEY_ONLY_ONEKEY_EER3 = 0x06,    /*!< Only write one key */
} FLASH_OPTKEY_T;

/**
 * @brief    FLASH key status
 */
typedef enum
{
    FLASH_KEY_WP_NOKEY         = 0x00,    /*!< Write protect */
    FLASH_KEY_MAIN_UNLOCK      = 0x03,    /*!< Unlock Main zone */
    FLASH_KEY_DATA_UNLOCK      = 0x04,    /*!< Unlock Data-Flash zone */
    FLASH_KEY_KEYERR_LOCK      = 0x07,    /*!< Key error */
    FLASH_KEY_ONLY_ONEKEY_EER0 = 0x01,    /*!< Only write one key */
    FLASH_KEY_ONLY_ONEKEY_EER1 = 0x02,    /*!< Only write one key */
    FLASH_KEY_ONLY_ONEKEY_EER2 = 0x05,    /*!< Only write one key */
    FLASH_KEY_ONLY_ONEKEY_EER3 = 0x06     /*!< Only write one key */
} FLASH_KEY_T;

/**
 * @brief    FLASH status
 */
typedef enum
{
    FLASH_FLAG_ERD     = 0x00000001,    /*!< Erase done flag */
    FLASH_FLAG_PRD     = 0x00000002,    /*!< Program done flag */
    FLASH_FLAG_BUSY    = 0x00000004,    /*!< Busy flag */
    FLASH_FLAG_KEYERR  = 0x00000008,    /*!< Flash key error flag */
    FLASH_FLAG_WRPRTER = 0x00000010,    /*!< Write protect error flag */
    FLASH_FLAG_WADRERR = 0x00000020,    /*!< Address error flag */
    FLASH_FLAG_TRIMERR = 0x00010000     /*!< Trim error flag */
} FLASH_FLAG_T;


/**
 * @brief    FLASH erase type
 */
typedef enum
{
    FLASH_ERASE_SECTOR = 0x00,    /*!< Sector erase */
    FLASH_ERASE_MAIN   = 0x01,    /*!< Main erase */
    FLASH_ERASE_CHIP   = 0x02     /*!< Chip erase */
} FLASH_ERASE_T;

/**
 * @brief    FLASH interrupt
 */
typedef enum
{
    FLASH_INT_EOP = 0x10,    /*!< End of program/erase interrupt */
    FLASH_INT_ERR = 0x20     /*!< Error occur interrupt */
} FLASH_INT_T;

/**
 * @brief    FLASH option byte status
 */
typedef enum
{
    FLASH_OB_OPTERR      = 0x00000001,    /*!< Option byte error flag */
    FLASH_OB_LEVEL1_PROT = 0x00000002,    /*!< Level 1 is protected flag */
    FLASH_OB_LEVEL2_PROT = 0x00000004,    /*!< Level 2 is protected flag */
    FLASH_OB_NBOOT0      = 0x00000010,    /*!< Nboot0 flag */
    FLASH_OB_NBOOT1      = 0x00000020,    /*!< Nboot1 flag */
    FLASH_OB_WWDTSW      = 0x00000040,    /*!< "0" means hardware activate WWDT, "1" means software activate WWDT */
    FLASH_OB_IWDTSW      = 0x00000080,    /*!< "0" means hardware activate IWDT, "1" means software activate IWDT */
    FLASH_OB_WLOCKEN     = 0x00010000,    /*!< Write protect flag */
} FLASH_OB_T;

/**
 * @brief   FLASH LVD threshold voltage
 */
typedef enum
{
    FLASH_LVDV_1P8V = 0x00,    /*!< 1.8V */
    FLASH_LVDV_1P9V = 0x01,    /*!< 1.9V */
    FLASH_LVDV_2P0V = 0x02,    /*!< 2.0V */
    FLASH_LVDV_2P1V = 0x03,    /*!< 2.1V */
    FLASH_LVDV_2P2V = 0x04,    /*!< 2.2V */
    FLASH_LVDV_2P3V = 0x05,    /*!< 2.3V */
    FLASH_LVDV_2P4V = 0x06,    /*!< 2.4V */
    FLASH_LVDV_2P5V = 0x07,    /*!< 2.5V */
    FLASH_LVDV_2P6V = 0x08,    /*!< 2.6V */
    FLASH_LVDV_2P7V = 0x09,    /*!< 2.7V */
    FLASH_LVDV_2P8V = 0x0A,    /*!< 2.8V */
    FLASH_LVDV_2P9V = 0x0B,    /*!< 2.9V */
    FLASH_LVDV_3P0V = 0x0C,    /*!< 3.0V */
    FLASH_LVDV_3P1V = 0x0D,    /*!< 3.1V */
    FLASH_LVDV_3P2V = 0x0E,    /*!< 3.2V */
    FLASH_LVDV_3P3V = 0x0F     /*!< 3.3V */
} FLASH_LVDV_T;

/**
 * @brief    FLASH write protect status
 */
typedef enum
{
    FLASH_WP_WP  = 0x00,    /*!< Write protect, not support erase or programming */
    FLASH_WP_NWP = 0x01     /*!< Not write protect status, support erase or programming */
} FLASH_WP_T;

/**@} end of group FLASH_CTRL_Enumerations */

/** @addtogroup FLASH_CTRL_Macros Macros
  @{
*/

/* 64K main flash */
#define MAINFLASH_BASEADDR    ((uint32_t)0x08000000)
#define MAINFLASH_SIZE        ((uint32_t)0x00010000)

/* 4K data flash */
#define DATAFLASH_BASEADDR    ((uint32_t)0x08010000)
#define DATAFLASH_SIZE        ((uint16_t)0x1000)

/* Option1 address */
#define OPTION1_BASEADDR      ((uint32_t)0x08011800)
#define OPTION1_SIZE          ((uint8_t)0x10)

#define M32(adr)              (*((u32*)(adr)))

/**@} end of group FLASH_CTRL_Macros */

/** @addtogroup FLASH_CTRL_Functions Functions
  @{
*/

/** Unlock Flash */
void FLASH_WriteFlashKey(uint32_t keyVal);
FLASH_KEY_T FLASH_ReadKeyStatus(void);
void FLASH_WriteOptionByteKey(uint32_t keyVal);
FLASH_OPTKEY_T FLASH_ReadOptionByteKeyStatus(void);

/* Flash configuration */
void FLASH_CTRL_Reset(void);
uint8_t FLASH_ReadFlag(FLASH_FLAG_T flag);
void FLASH_EnableOptionByteForceUpdate(void);
void FLASH_EnableInterrupt(FLASH_INT_T interrupt);
void FLASH_DisableInterrupt(FLASH_INT_T interrupt);
void FLASH_ConfigEraseOption(uint8_t eraseType);
void FLASH_StartErase(void);
void FLASH_StartProgram(void);
void FLASH_ConfigBaseTime(uint8_t counter);
uint8_t FLASH_ReadOptionByteFlag(FLASH_OB_T flag);
uint8_t FLASH_ReadDataFlashProtectFlag(void);
uint8_t FLASH_ReadLVDEnableFlag(void);
FLASH_LVDV_T FLASH_ReadLVDV(void);
FLASH_WP_T FLASH_ReadDataFlashLockFlag(uint8_t sectorNum);
FLASH_WP_T FLASH_ReadMainFlashLockFlag(uint8_t sectorBlock);
void FLASH_EnableLowPower(void);
void FLASH_DisableLowPower(void);
void FLASH_EnableFastWakeUp(void);
void FLASH_DisableFastWakeUp(void);
void FLASH_EnableReadOnly(void);
void FLASH_DisableReadOnly(void);
uint8_t FLASH_ReadTrimTag(void);

/* Flash program/erase */
void FLASH_EraseChip(void);
void FLASH_EraseMainBlock(void);
void FLASH_EraseSector(uint32_t addr);
void FLASH_ProgramPage(uint32_t addr, uint32_t length, uint8_t* buf);

/**@} end of group FLASH_CTRL_Functions */
/**@} end of group FLASH_CTRL_Driver */
/**@} end of group Peripherals_Library */

#ifdef __cplusplus
}
#endif

#endif /* __BMP561_FLASH_CTRL_H */
