#ifndef _CPU_FLASH_H_
#define _CPU_FLASH_H_
#include <stdint.h>
#include <stdlib.h>
#include "datatype.h"
#include <stdbool.h>

enum
{
    FLASH_OPERATE_FAIL             =0x00,
    FLASH_SUCCEED                  = 0x01,
        /*flash ERROR*/
    FLASH_ERROR_ADDR_INVALID              = 0x02,
    FLASH_ERROR_ADDR_OUT                  = 0x03,
};
#define FLASH_SECTOR_SIZE       (0X1000)
#define FALSH_PAGE_SIZE         (0x100)
#define FLASH_ADDR_BASE         (0x00000000) //max size 1M flash
#define FLASH_PART_SIZE         (0x1000)
#define FLASH_BOOT_SIZE         (0x1000)
#define FLASH_VALID_ADDR        (FLASH_ADDR_BASE+FLASH_PART_SIZE+FLASH_BOOT_SIZE)
#define FLASH_END_ADDR          (0x00100000)

#define QSPI_SUPPORT_CHIP_JEDEC_ID_EON      0x1C


typedef struct {
	// comon flash API
	void (*flash_lock)(void);
	void (*flash_unlock)(void);
	uint32_t (*flash_read_id)(void);
	uint32_t (*flash_erase_chip)(void);
	uint32_t (*flash_erase_sector)(unsigned int adr);
	uint32_t (*flash_erase_page)(unsigned int adr);
	uint32_t (*flash_read)(unsigned long adr, unsigned long sz, unsigned char *buf);
	uint32_t (*flash_program)(unsigned long adr, unsigned long sz, unsigned char *buf);
	uint32_t (*flash_erase_otp)(unsigned int page);
	uint32_t (*flash_read_otp)(unsigned char page, unsigned long adr, unsigned long sz, unsigned char *buf);
	uint32_t (*flash_program_otp)(unsigned char page, unsigned long adr, unsigned long sz, unsigned char *buf);
	uint32_t (*flash_lock_otp)(unsigned int page);	
	// basic flash API
	uint32_t (*flash_command)(void *cmd, unsigned long  timeout);
	uint32_t (*flash_release_pd)(void);
	uint32_t (*flash_write_enable)(void);
	uint32_t (*flash_is_busy)(void);
	uint32_t (*flash_read_sta_reg1)(void);
	uint32_t (*flash_read_sta_reg2)(void);
	uint32_t (*flash_write_sta_reg)(unsigned int reg_val);	
	uint32_t (*flash_write_sta_reg_eon)(unsigned int reg_val);
	uint32_t (*flash_set_burst_len)(unsigned long  param);
	uint32_t (*flash_program_single)(unsigned char is_otp, unsigned long adr, unsigned long sz, unsigned char *buf) ;

}bootrom_func_t;

void flash_burst_enable(void);
void flash_burst_disable(void);
/*
* brief: flash read api
* param[0]: flash address (0x00002000~0x01100000)
* param[1]: read flash data size
* param[2]: buf for save data from flash.
* return  : true succeed or fail
*/
uint32_t flash_read(uint32_t address, uint32_t size, uint8_t *buf);
/*
* brief: flash write api
* param[0]: flash address (0x00002000~0x01100000)
* param[1]: read flash data size
* param[2]: buf for save data into flash.
* return  : true succeed or fail
*/
uint32_t flash_write(uint32_t address, uint32_t size, uint8_t *buf);
/*
* brief: flash erase api
* param[0]: flash address (0x00002000~0x01100000)
* param[1]: read flash data size
* return  : true succeed or fail
*/
uint32_t flash_erase(uint32_t address, uint32_t size);

/*
* brief: flash read otp api* 
* param[0]: page 0 1 2
* param[1]: flash address (0x00~0xff)
* param[2]: read flash data size(0x01~0xff)
* param[3]: buf for save data fram flash otp.
* return  : true succeed or fail
*/

uint32_t flash_otp_read(uint32_t page,uint32_t addr, uint32_t size, uint8_t *buf);

bool Flash_set_zero_long(uint32_t addr, uint32_t len);
bool Flash_set_data_long(uint32_t addr, uint32_t len, uint32_t *arr);
bool Flash_get_data_long(uint32_t addr, uint32_t len, uint32_t *arr);
bool Flash_set_data_byte(uint32_t addr, uint32_t len, uint8_t *arr);
bool Flash_get_data_byte(uint32_t addr, uint32_t len, uint8_t *arr);
bool Flash_clean_long(uint32_t addr, uint32_t len);
bool Flash_clean_bytes(uint32_t addr, uint32_t len);

#endif
