/**
 * \file    drv_flash.h
 * \brief   Flash interface header file
 *
 * \detail  When write data to flash in 4KB boundary, hardware will erase sector automatically
 *
 * \par     Copyright (c) 2018 UWE Technologies Corp., Ltd. All Rights Reserved.
 * \author  James
 * \date    2018-03-05
 * \version 
 * 
 * \history 
 *  Date        Note
 *  2018-03-05  Original Creation
 * 
 */
 
#ifndef __DRV_FLASH_H_
#define __DRV_FLASH_H_


#include "types.h"
#include "utils.h"
#include "drv_reg_intf.h"
#include "reg_def_flash.h"


// default flash size is 512KB for firmware and config data
#define DRV_FLASH_SIZE              0x80000U
#define DRV_FLASH_SECTOR_SIZE       4096U
#define DRV_FLASH_SECTOR_CNT        (DRV_FLASH_SIZE/DRV_FLASH_SECTOR_SIZE)
#define DRV_FLASH_NVR_SIZE          512U

/* (address % 4096) == (address & 0xFFF) */
#define DRV_FLASH_SECTOR_MOD      0xFFF
/* (address % 512) == (address & 0x1FF) */
#define DRV_FLASH_SECU_SECTOR_MOD 0x1FF

/** \brief Write 32 bits input data to flash
 *
 * \param addr      Start address
 * \param input     The input data
 * \return          TRUE: succeeded, FALSE: failed
 */
bool_t drv_flash_write_32bits(u32_t addr, u32_t input);

/** \brief Flash sector erase
 *
 * \param addr      Start address, the address must be aligned on a 4096 bytes boundary
 */
void drv_flash_sector_erase(u32_t addr);

/** \brief Flash read operation via hardware DMA
 *
 * \param addr      Start address
 * \param buf       The pointer of destination address
 * \param len       The length need to be read
 */
void drv_flash_read(u32_t addr, u8_t *buf, int len);

/** \brief Flash write operation via hardware DMA
 *
 * \param addr      Start address
 * \param buf       The pointer of destination address
 * \param len       The length need to be written, the best speed to write 
 *                  which is the length is multiple of 32 bytes
 * \return          TRUE: succeeded, FALSE: failed
 */
bool_t drv_flash_write(u32_t addr, u8_t *buf, int len);

/** \brief Flash read operation via software copy
 *
 * \param addr      Start address
 * \param buf       The pointer of destination address
 * \param len       The length need to be read
 */
void drv_flash_read2(u32_t addr, u8_t *buf, int len);

/** \brief Flash write operation via software copy
 *
 * \param addr      Start address
 * \param buf       The pointer of destination address
 * \param len       The length need to be written, the best speed to write 
 *                  which is the length is multiple of 32 bytes
 * \return          TRUE: succeeded, FALSE: failed
 */
bool_t drv_flash_write2(u32_t addr, u8_t *buf, int len);

/** \brief Enable or disable security register operation 
 *
 * \param en        1: enable, 0: disable
 */
void drv_flash_nvr_en(bool_t en);



/**
 * Security FLASH register address	TRIM code
 * 24¡¯h00_2000	ROSC trim bits[4:0] 
 * 24¡¯h00_2001	LDO1 trim bits[4:0], TUNE33
 * 24¡¯h00_2002	LDO2 trim bits[4:0], TURNBG
 * 24¡¯h00_2003	RD trim bits[3:0]
 * 24¡¯h00_2004	Current source trim bits[4:0]
 * 24¡¯h00_2005	Current sensor offset bits[7:0]
 * 24¡¯h00_2006	Current sensor offset bits[11:8]
 * 
 * 24¡¯h00_2008	Reference voltage bits[7:0]
 * 24¡¯h00_2009	Reference voltage bits[15:8]    
 * 24¡¯h00_200A	Firmware program start flag = h55
 * 24¡¯h00_200B	Firmware program end flag = hAA    
 */
#define DRV_FLASH_TRIM_CODE_OFFSET_ROSC         (0)
#define DRV_FLASH_TRIM_CODE_OFFSET_LDO1         (1)
#define DRV_FLASH_TRIM_CODE_OFFSET_LDO2         (2)
#define DRV_FLASH_TRIM_CODE_OFFSET_RD           (3)
#define DRV_FLASH_TRIM_CODE_OFFSET_CUR_SRC      (4)
#define DRV_FLASH_TRIM_CODE_OFFSET_CUR_SEN1     (5)
#define DRV_FLASH_TRIM_CODE_OFFSET_CUR_SEN2     (6)
#define DRV_FLASH_TRIM_CODE_OFFSET_REF_VOLT1    (8)
#define DRV_FLASH_TRIM_CODE_OFFSET_REF_VOLT2    (9)
#define DRV_FLASH_TRIM_CODE_OFFSET_FW_PRG_S     (10)
#define DRV_FLASH_TRIM_CODE_OFFSET_FW_PRG_E     (11)
#define DRV_FLASH_TRIM_CODE_NUM                 (12)
extern u8_t trim_code_buffer[DRV_FLASH_TRIM_CODE_NUM];
extern u16_t g_current_sense_offset;
extern u16_t g_v33_reference_voltage;

#define DRV_FLASH_FW_PRG_START_FLAG             (0x55)
#define DRV_FLASH_FW_PRG_END_FLAG               (0xAA)

/** \brief Get current sense offset
 *
 * \return current sense offset
 */
#define drv_flash_trim_current_sense_offset_get()   (g_current_sense_offset)

/** \brief Set current sense offset
 *
 * \param offset        The current sense offset
 */
void drv_flash_trim_current_sense_offset_set(u32_t offset);

/** \brief Get the reference voltage from Flash Trim Area
 *
 * \return The reference voltage, unit is milli-volt
 */
#define drv_flash_trim_ref_volt_get()               (g_v33_reference_voltage)

/** \brief Set the reference voltage to Flash Trim Area
 *
 * \param ref_volt      The reference voltage, unit is milli-volt
 */
void drv_flash_trim_ref_volt_set(u32_t ref_volt);

/** \brief Get the trim value of LDO2 from Flash Trim Area
 *
 * \return  Trim value
 */
u32_t drv_flash_trim_ldo2_get();

/** \brief Set the trim value of LDO2 to Flash Trim Area
 *
 * \param value         The LDO2 trim value
 */
void drv_flash_trim_ldo2_set(u32_t value);

/** \brief Get the trim value of RD from Flash Trim Area
 *
 * \return  Trim value
 */
u32_t drv_flash_trim_rd_get();

/** \brief Get the trim value of current source from Flash Trim Area
 *
 * \return  Trim value
 */
u32_t drv_flash_trim_current_source_get();

/** \brief Check if the firmware is unbroken
 *
 * \return  0: broken, 1: unbroken
 */
bool_t drv_flash_firmware_is_unbroken();


#endif /* #ifndef __DRV_FLASH_H_ */

