/**
  ******************************************************************************
  * @file    ys32md211_flash.h
  * @version V1.0.1
  * @date    2022.6.13
  * @brief   This file contains all the functions prototypes for the FLASH 
  *          firmware library.
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __YS32MD211_FLASH_H
#define __YS32MD211_FLASH_H

#ifdef __cplusplus
 extern "C" {
#endif

#include "ys32md211.h"
#include "system_ys32md211.h"

/** @addtogroup YS32MD211_StdPeriph_Driver
  * @{
  */

/** @addtogroup FLASH
  * @{
  */

/* Exported types ------------------------------------------------------------*/

/** 
  * @brief  FLASH Status
  */ 
typedef enum
{
  FLASH_BUSY = 1,
  FLASH_ERROR_WRP,
  FLASH_ERROR_PROGRAM,
  FLASH_COMPLETE,
  FLASH_TIMEOUT
}FLASH_Status;

/******************  FLASH Keys  **********************************************/
#define FLASH_UNLOCK_KEY()         		     {FLASH->KEYR = FLASH_KEY1; FLASH->KEYR = FLASH_KEY2;}
#define FLASH_LOCK_KEY()           		     {FLASH->CR |= FLASH_CR_LOCK;}
#define FLASH_OB_UNLOCK_KEY()         	     {FLASH->OPTKEYR = FLASH_OPTKEY1; FLASH->OPTKEYR = FLASH_OPTKEY2;}
#define FLASH_OB_LOCK_KEY()           	     {FLASH->CR |= FLASH_CR_OPTLOCK;}

/** @defgroup FLASH_Latency 
  * @{
  */ 
#define FLASH_Latency_0                	FLASH_ACR_LATENCY_00
#define FLASH_Latency_1                	FLASH_ACR_LATENCY_01
/**
  * @}
  */ 

/** @defgroup FLASH_MEROPT 
  * @{
  */
#define FLASH_MEROPT_28K                ((uint32_t)0x00000000)
#define FLASH_MEROPT_32K                ((uint32_t)0x00000001)
#define IS_FLASH_MEROPT(MEROPT) (((MEROPT) == FLASH_MEROPT_28K) || \
                                 ((MEROPT) == FLASH_MEROPT_32K))
/**
  * @}
  */

/** 
  * @brief  FLASH_Read Protection Level  
  */ 
#define OB_RDP_Level_0   ((uint8_t)0xAA)
#define OB_RDP_Level_1   ((uint8_t)0xBB)
#define IS_OB_RDP(LEVEL) (((LEVEL) == OB_RDP_Level_0)||\
                          ((LEVEL) == OB_RDP_Level_1))
/**
  * @}
  */ 

 /** @defgroup FLASH_Option_Bytes_BOOT1
  * @{
  */
#define OB_BOOT1_RESET                 ((uint8_t)0x00)     /*!< BOOT1 Reset */
#define OB_BOOT1_SET                   FLASH_OPTR_nBOOT1   /*!< BOOT1 Set */
#define IS_OB_BOOT1(BOOT1) (((BOOT1) == OB_BOOT1_RESET) || ((BOOT1) == OB_BOOT1_SET))
/**
  * @}
  */
  
 /** @defgroup FLASH_Option_Bytes_NRST_MODE
  * @{
  */
#define OB_NRST_MODE_RESET             ((uint8_t)0x00)        /*!< GPIO */
#define OB_NRST_MODE_SET               FLASH_OPTR_NRST_MODE   /*!< Input Reset  */
#define IS_OB_NRST_MODE(MODE) (((MODE) == OB_NRST_MODE_RESET) || ((MODE) == OB_NRST_MODE_SET))
/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_IWatchdog 
  * @{
  */
#define OB_IWDG_SW                     FLASH_OPTR_IWDG_SW  /*!< Software IWDG selected */
#define OB_IWDG_HW                     ((uint8_t)0x00)     /*!< Hardware IWDG selected */
#define IS_OB_IWDG(SOURCE) (((SOURCE) == OB_IWDG_SW) || ((SOURCE) == OB_IWDG_HW))
/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_WWatchdog 
  * @{
  */
#define OB_WWDG_SW                     FLASH_OPTR_WWDG_SW  /*!< Software WWDG selected */
#define OB_WWDG_HW                     ((uint8_t)0x00)     /*!< Hardware WWDG selected */
#define IS_OB_WWDG(SOURCE) (((SOURCE) == OB_WWDG_SW) || ((SOURCE) == OB_WWDG_HW))
/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_BOR_EN 
  * @{
  */
#define OB_BOR_EN                     FLASH_OPTR_BOR_EN   /*!< BOR EN selected */
#define OB_BOR_DIS                    ((uint8_t)0x00)     /*!< BOR DIS selected */
#define IS_OB_BOR_EN(SOURCE) (((SOURCE) == OB_BOR_EN) || ((SOURCE) == OB_BOR_DIS))
/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_BOR_LEV
  * @{
  */
#define OB_BOR_LEV_1d8_1d7                  FLASH_OPTR_BOR_LEV_000
#define OB_BOR_LEV_2d0_1d9                  FLASH_OPTR_BOR_LEV_001
#define OB_BOR_LEV_2d2_2d1                  FLASH_OPTR_BOR_LEV_010
#define OB_BOR_LEV_2d4_2d3                  FLASH_OPTR_BOR_LEV_011
#define OB_BOR_LEV_2d6_2d5                  FLASH_OPTR_BOR_LEV_100
#define OB_BOR_LEV_2d8_2d7                  FLASH_OPTR_BOR_LEV_101
#define OB_BOR_LEV_3d0_2d9                  FLASH_OPTR_BOR_LEV_110
#define OB_BOR_LEV_3d2_3d1                  FLASH_OPTR_BOR_LEV_111
#define IS_OB_BOR_LEV(SOURCE) (((SOURCE) == OB_BOR_LEV_1d8_1d7) || ((SOURCE) == OB_BOR_LEV_2d6_2d5) ||\
                               ((SOURCE) == OB_BOR_LEV_2d0_1d9) || ((SOURCE) == OB_BOR_LEV_2d8_2d7) ||\
                               ((SOURCE) == OB_BOR_LEV_2d2_2d1) || ((SOURCE) == OB_BOR_LEV_3d0_2d9) ||\
                               ((SOURCE) == OB_BOR_LEV_2d4_2d3) || ((SOURCE) == OB_BOR_LEV_3d2_3d1))
/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_Write_Protection 
  * @{
  */ 
#define OB_WRP_Pages0to7               ((uint32_t)0x00000001) /* Write protection of page 0 to 7 */
#define OB_WRP_Pages8to15              ((uint32_t)0x00000002) /* Write protection of page 8 to 15 */
#define OB_WRP_Pages16to23             ((uint32_t)0x00000004) /* Write protection of page 16 to 23 */
#define OB_WRP_Pages24to27             ((uint32_t)0x00000008) /* Write protection of page 24 to 27 */

#define OB_WRP_AllPages                ((uint32_t)0x0000000F) /*!< Write protection of all Sectors */

#define IS_OB_WRP(PAGE) (((PAGE) != 0x0000000))
/**
  * @}
  */

/** @defgroup FLASH_Option_Bytes_SDK
  * @{
  */
#define IS_OB_SDK(PAGE) (((PAGE) >= 0x02) && ((PAGE) <= 0x5))
/**
  * @}
  */

/** @defgroup FLASH_Timeout_definition 
  * @{
  */ 
#define FLASH_ER_PRG_TIMEOUT         ((uint32_t)0x000B0000)
/**
  * @}
  */ 

/** @defgroup FLASH_Interrupts 
  * @{
  */
#define FLASH_IT_EOP                   FLASH_CR_EOPIE  /*!< End of programming interrupt source */
#define FLASH_IT_ERR                   FLASH_CR_ERRIE  /*!< Error interrupt source */
#define IS_FLASH_IT(IT) ((((IT) & (uint32_t)0xFCFFFFFF) == 0x00000000) && (((IT) != 0x00000000)))
/**
  * @}
  */ 

/** @defgroup FLASH_Flags 
  * @{
  */ 

#define FLASH_FLAG_BSY                 FLASH_SR_BSY     /*!< FLASH Busy flag */
#define FLASH_FLAG_WRPERR              FLASH_SR_WRPERR  /*!< FLASH Write protected error flag */
#define FLASH_FLAG_EOP                 FLASH_SR_EOP     /*!< FLASH End of Programming flag */
#define FLASH_FLAG_OPTVERR             FLASH_SR_OPTVERR /*!< FLASH OB Programming error flag */
 
#define IS_FLASH_CLEAR_FLAG(FLAG) ((((FLAG) & (uint32_t)0xFFFE7FEE) == 0x00000000) && ((FLAG) != 0x00000000))

#define IS_FLASH_GET_FLAG(FLAG)  (((FLAG) == FLASH_FLAG_BSY) || ((FLAG) == FLASH_FLAG_WRPERR) || \
                                  ((FLAG) == FLASH_FLAG_EOP) || ((FLAG) == FLASH_FLAG_OPTVERR))
                                  
/** @defgroup FLASH_Page_Length
  * @{
  */
#define IS_FLASH_Page_Length(WORDS) ((WORDS) <= 64)
/**
  * @}
  */
/**
  * @}
  */ 

/* FLASH Interface configuration functions ************************************/
void FLASH_Trimming(void);
void FLASH_SetLatency(uint32_t FLASH_Latency);

/* FLASH Memory Programming functions *****************************************/
void FLASH_Unlock(uint32_t FLASH_Key1, uint32_t FLASH_Key2);
void FLASH_Lock(void);
FLASH_Status FLASH_ErasePage(uint32_t Page_Address);
FLASH_Status FLASH_EraseAllPages(uint32_t FLASH_MEROPT);
FLASH_Status FLASH_EraseSector(uint32_t Address);
FLASH_Status FLASH_ProgramPage(uint32_t Address, uint32_t * Buffer, uint32_t Length);
uint32_t FLASH_Read32(uint32_t Address);
uint8_t FLASH_Read8(uint32_t Address);

/* FLASH Option Bytes Programming functions *****************************************/
void FLASH_OB_Unlock(uint32_t FLASH_OptKey1, uint32_t FLASH_OptKey2);
void FLASH_OB_Lock(void);
void FLASH_OB_Launch(void);
FLASH_Status FLASH_OB_Erase(void);
FLASH_Status FLASH_OB_EnableWRP(uint32_t OB_WRP);
FLASH_Status FLASH_OB_EnableSDK(uint32_t Start, uint32_t End);
FLASH_Status FLASH_OB_RDPConfig(uint32_t OB_RDP);
FLASH_Status FLASH_OB_BOOTConfig(uint32_t OB_BOOT1);
FLASH_Status FLASH_OB_WriteUser(uint32_t OB_USER);
FLASH_Status FLASH_OB_ProgramData(uint32_t OPTR, uint32_t PCROPR, uint32_t WRPR);
uint32_t FLASH_OB_GetUser(void);
uint32_t FLASH_OB_GetWRP(void);
uint32_t FLASH_OB_GetSDK(void);
FlagStatus FLASH_OB_GetRDP(void);

/* FLASH Interrupts and flags management functions **********************************/
void FLASH_ITConfig(uint32_t FLASH_IT, FunctionalState NewState);
FlagStatus FLASH_GetFlagStatus(uint32_t FLASH_FLAG);
void FLASH_ClearFlag(uint32_t FLASH_FLAG);
FLASH_Status FLASH_GetStatus(void);
FLASH_Status FLASH_WaitForLastOperation(uint32_t Timeout);
#ifdef __cplusplus
}
#endif

#endif /* __YS32MD211_FLASH_H */

/**
  * @}
  */


