/**
  *********************************************************************************
  *
  * @file    hal_flash.h
  * @brief   Header file of FLASH driver
  *
  * @version V1.0
  * @date    20 Nov 2017
  * @author  AE Team
  * @note
  *
  * Copyright (C) Shanghai Eastsoft Microelectronics Co. Ltd. All rights reserved.
  *
  *********************************************************************************
  */

#ifndef __HAL_FLASH_H__
#define __HAL_FLASH_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "utils.h"

/** @addtogroup ES32FXXX_HAL
  * @{
  */

/** @addtogroup FLASH
  * @{
  */

/**
  * @defgroup FLASH_Private_Macros FLASH Private Macros
  * @{
  */
#define FLASH_REG_UNLOCK()				\
do {							\
	if (op_cmd == OP_FLASH)	{			\
		MSC->FLASHKEY.Word = 0x8ACE0246;	\
		MSC->FLASHKEY.Word = 0x9BDF1357;	\
	}						\
	else {						\
		MSC->INFOKEY.Word  = 0x7153BFD9;	\
		MSC->INFOKEY.Word  = 0x0642CEA8;	\
	}						\
} while(0)
#define FLASH_REQ()			(MSC->FLASHCR.FLASHREQ = 0x1)
#define FLASH_REQ_FIN()			(MSC->FLASHCR.FLASHREQ = 0x0)
#define FLASH_IAP_ENABLE()		(MSC->FLASHCR.IAPEN    = 0x1)
#define FLASH_IAP_DISABLE()		(MSC->FLASHCR.IAPEN    = 0x0)
#define FLASH_BASE_ADDR			0x00000000
#define	FLASH_PAGE_SIZE			1024UL
#define FLASH_WORD_SIZE			8UL
#define FLASH_TOTAL_SIZE		256UL
#define FLASH_PAGE_MASK			(FLASH_PAGE_SIZE - 1)
#define FLASH_WORD_MASK			(FLASH_WORD_SIZE - 1)
#define IS_FLASH_ADDRESS(ADDR)		((ADDR) < (FLASH_BASE_ADDR + FLASH_PAGE_SIZE * FLASH_TOTAL_SIZE))
#define IS_4BYTES_ALIGN(ADDR)		(((uint32_t)(ADDR) & 0x3) == 0 ? 1 : 0)
#define FLASH_PAGE_ADDR(ADDR)		((ADDR) & (~FLASH_PAGE_MASK))
#define FLASH_PAGEEND_ADDR(ADDR)	((ADDR) | FLASH_PAGE_MASK)
#define FLASH_WORD_ADDR(ADDR)		((ADDR) & (~FLASH_WORD_MASK))
#define FLASH_WORDEND_ADDR(ADDR)	((ADDR) | FLASH_WORD_MASK)
#define INFO_PAGE_SIZE			1024UL
#define INFO_PAGE_MASK			(INFO_PAGE_SIZE - 1)
#define INFO_PAGE_ADDR(ADDR)		((ADDR) & (~INFO_PAGE_MASK))

#ifdef USE_FLASH_FIFO
	#define	FLASH_FIFO 1
#else
	#define	FLASH_FIFO 0
#endif
/**
  * @}
  */

/** @defgroup FLASH_Private_Types FLASH Private Types
  * @{
  */
typedef enum {
	FLASH_CMD_AE = 0x000051AE,	/**< Program area erase all */
	FLASH_CMD_PE = 0x00005EA1,	/**< Page erase  */
	FLASH_CMD_WP = 0x00005DA2,	/**< Word program */
} flash_cmd_type;

typedef enum {
	OP_FLASH = 0,	/**< Operate Pragram area */
	OP_INFO  = 1,	/**< Operate info area */
} op_cmd_type;

/**
  * @}
  */

/** @addtogroup Flash_Public_Functions
  * @{
  */
hal_status_t flash_write(uint32_t addr, uint8_t *buf, uint16_t len);
hal_status_t flash_erase(uint32_t addr, uint16_t len);
hal_status_t flash_read(uint32_t *ram_addr, uint32_t addr, uint16_t len);
/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

#ifdef __cplusplus
}
#endif

#endif /* __HAL_FLASH_H__ */
