/*!
    \file    flash.h
    \brief   the header file of flash

*/

#ifndef FLASH_H
#define FLASH_H
#include "gpio.h"

typedef struct
{
uint8_t resv_bit          :3;
uint8_t XIP_en            :1;
uint8_t dummy_clk_cyc     :4;
}ST_SPI_VCR;
typedef union
{
  ST_SPI_VCR st_vcr;
  uint8_t vcr;
}UN_SPI_VCR;

typedef struct
{
uint8_t out_drv_str       :3;
uint8_t acceler_en        :1;
uint8_t hold_disab        :1;
uint8_t resv_bit          :1;
uint8_t dual_cmd_en       :1;
uint8_t quad_cmd_en       :1;
}ST_SPI_VECR;
typedef union
{
  ST_SPI_VECR st_vecr;
  uint8_t vecr;
}UN_SPI_VECR;

/*****************************************************************************************
* User config table structure definition
*
* Must contain multiples of 4 bytes.
*****************************************************************************************/
typedef struct tag_ST_SpiUsrCfg
{
  uint16_t  signature;              /* #0-1 User config area signtature = 0xBA5E */
  uint8_t   mod_override;           /* #2 User forced boot mode */
  uint8_t   addr_len;               /* #3 Flash access address length (plain number) */

  uint8_t   fast_rd_inst;           /* #4 Fast read instruction */
  uint8_t   trans_typ     :4;       /* #5 Fast read trasmission type */
  uint8_t   spi_frf       :4;       /*    Fast read SPI frame format */
  uint8_t   fastrd_dmycyc;          /* #6 Fast read dmy cyc cnt (plain number) */
  uint8_t   xip_dmycyc;             /* #7 XIP dmy cyc cnt (plain number) */

  uint16_t  xip_mod_bits;           /* #8-9 XIP mode bit value */
  uint8_t   xip_MBL_bitcnt;         /* #10 XIP mode bit length (plain number) */
  uint8_t   xip_cnt_tmo;            /* #11 XIP count time-out */

  uint32_t  src_addr;               /* #12-15 Flash->SRAM copy Src address */
  uint32_t  dest_addr;              /* #16-19 Flash->SRAM copy Dest address */
  uint32_t  copy_len;               /* #20-23 Flash->SRAM copy length */
  uint8_t   qe_rd_inst;             /* #24 QE status read instruction */
  uint8_t   qe_wt_inst;             /* #25 QE status write instruction */
  uint8_t   qe_bit_pos;             /* #26 QE bit position */
  uint8_t   u8_rsvd1;               /* #27 Reserved 1 bytes */

  uint8_t   write_inst;             /* #28 write instruction */
  uint8_t   xip_inst;               /* #29 XIP instruction */
  uint8_t   xip_trans_typ     :4;   /* #30 XIP transmission type */
  uint8_t   xip_spi_frf       :4;   /*     XIP SPI frame format */
  uint8_t   qspi_baud_div;          /* #31 QSPI baud rate divisor */

  uint32_t  chksum;                 /* #32-35 User config area 32-bit check sum */
} ST_SpiUsrCfg;

/*N25Q128 status*/
#define SPIFLASH_IS_BUSY            0x01u
#define SPIFLASH_IS_WEL             0x02u

/*N25Q128 SPI Flash instructions define*/
#define SPIF_WRITE_EN               0x06u
#define SPIF_WRITE_DIS              0x04u
#define SPIF_READ_SR                0x05u
#define SPIF_WRITE_SR               0x01u

#define SPIF_READ_DATA              0x03u   /* 1-1-1 dmy=0 */

#define SPIF_FAST_READ              0x0Bu   /* 1-1-1 dmy=8 */
#define SPIF_FAST_READ_DUAL_OUT     0x3Bu   /* 1-1-2 dmy=8 */
#define SPIF_FAST_READ_QUAD_OUT     0x6Bu   /* 1-1-4 dmy=8 */

#define SPIF_FAST_READ_DUAL_IO      0xBBu   /* 1-2-2 dmy=4 or 8 */
#define SPIF_FAST_READ_QUAD_IO      0xEBu   /* 1-4-4 dmy=6 or 10 */

#define SPIF_PAGE_PROGRAM           0x02u   /* 1-1-1 dmy=0 */
#define SPIF_PAGE_PROG_QUAD_IN      0x32u   /* 1-1-4 dmy=0 */

#define SPIF_SECTOR_ERASE           0x20u
#define SPIF_BLOCK_ERASE_32         0x52u
#define SPIF_BLOCK_ERASE_64         0xD8u
#define SPIF_CHIP_ERASE             0xC7u

#define SPIF_POWER_DOWN             0xB9u
#define SPIF_RPD_DID                0xABu
#define SPIF_READ_UID               0x4Bu
#define SPIF_READ_MF_DEVID          0x9Fu
#define SPIF_RESET_ENABLE           0x66u
#define SPIF_RESET_DEVICE           0x99u

#define SPIF_READ_STATUS_REG_2      0x35u
#define SPIF_WRITE_STATUS_REG_2     0x31u


/*******************************************************************************
* Default page program specification
*******************************************************************************/
#define SPIF_PAGE_SIZE              256u
#define SPIF_DEF_PAGE_PRG_INST      SPIF_PAGE_PROG_QUAD_IN
#define SPIF_DEF_PAGE_PRG_SPI_FRF   SPI_SPI_FRF_QUAD

/*******************************************************************************
* Default fast read specification will be retrieved from user config area
*******************************************************************************/
#define SPI_USR_CFG_SIGNATURE       0xBA5Eu
#define SPI_RD_LEN                  256u

/*******************************************************************************
* SPI user configured forced boot mode
*******************************************************************************/
#define SPI_DEFAULT_BOOT            ((uint8_t)0x00u)
#define SPI_FORCE_BOOT_BASEVAL      ((uint8_t)0x10u)
#define SPI_FORCE_BOOT_SRAM         (SPI_FORCE_BOOT_BASEVAL + (uint8_t)BOOT_SRAM)
#define SPI_FORCE_BOOT_FLASH        (SPI_FORCE_BOOT_BASEVAL + (uint8_t)BOOT_FLASH)
#define SPI_FORCE_BOOT_FLASH_CACHE  (SPI_FORCE_BOOT_BASEVAL + (uint8_t)BOOT_FLASH_CACHE)
#define SPI_FORCE_BOOT_DEBUG        (SPI_FORCE_BOOT_BASEVAL + (uint8_t)BOOT_DEBUG)
#define SPI_FORCE_UPLOADER          ((uint8_t)0x14u)

/*
    SPI FLASH CAPACITY IS 512K
    4K per sector
    16 page per sector
    256 bytes per page
*/

extern const ST_SpiUsrCfg spi_def_cfg;
extern ST_SpiUsrCfg spi_cfg;

extern uint32_t aligned_flash_buff[64u];
extern uint8_t *flash_buff;
extern uint32_t flash_addr_end;

/*functions*/
void SPIF_init(void);
void SPIF_GetDevID(uint8_t *id_buff, uint32_t len);
uint8_t SPIF_SectorErase(uint8_t cmd, uint32_t sector);
uint8_t SPIF_BlockErase4K(uint32_t block);
uint8_t SPIF_BlockErase32K(uint32_t block);
uint8_t SPIF_BlockErase64K(uint32_t block);
uint8_t SPIF_ChipErase(void);
uint8_t SPIF_PageProgram(uint32_t page, uint8_t *data, uint32_t len);
uint8_t SPIF_Program(uint32_t page, uint8_t *data, uint32_t len);
uint8_t SPIF_ReadData(uint32_t addr, uint8_t *data, uint32_t len);
void SPIM_TxRx(uint8_t inst, uint32_t addr, uint8_t *buf, uint32_t tlen, uint32_t rlen);
void SPIM_TxRx32(uint8_t inst, uint32_t addr, uint8_t *buf, uint32_t tlen, uint32_t rlen);
void SPIM_EnhTxRx32(uint8_t inst, uint32_t addr, uint8_t *buf, uint32_t tlen, uint32_t rlen);

uint8_t SPIF_WriteEN(void);
uint8_t SPIF_WaitReady(void);
void SPIF_XIP_Init(void);
void SPIF_GetFlashCfg(void);
uint8_t SPIF_QuadInstEn(void);

#endif  /* FLASH_H */
