#ifndef _W25Q128_H
#define _W25Q128_H

#include "comm_types.h"
#include "gd32f4xx_gpio.h"



extern unsigned short int ID;
extern unsigned char only_id[8];
/*
*********************************************************************************************************
*                                         
*********************************************************************************************************
*/

#define FLASH_DI_HIGH           (gpio_bit_set(GPIOB,GPIO_PIN_5))
#define FLASH_DI_LOW            (gpio_bit_reset(GPIOB,GPIO_PIN_5))

#define FLASH_CLK_HIGH          (gpio_bit_set(GPIOB,GPIO_PIN_3))
#define FLASH_CLK_LOW           (gpio_bit_reset(GPIOB,GPIO_PIN_3))

//#define FLASH_CS_DISABLE        (gpio_bit_set(GPIOE,GPIO_PIN_2))
//#define FLASH_CS_ENABLE         (gpio_bit_reset(GPIOE,GPIO_PIN_2))

#define FLASH_CS_DISABLE        (gpio_bit_set(GPIOB,GPIO_PIN_8))
#define FLASH_CS_ENABLE         (gpio_bit_reset(GPIOB,GPIO_PIN_8))


#define FLASH_DO_READ           (gpio_input_bit_get(GPIOB,GPIO_PIN_4))

#define FLASH_W25Q128

#define    FLASH_WRITE_BUSYBIT     0X01
#ifdef FLASH_W25Q128
#define    Flash_ReadData_CMD      0x03      //3 BYTE MODE
#endif

#ifdef FLASH_W25Q256
#define    Flash_ReadData_CMD      0x13      //4 BYTE MODE  new add
#endif


#define    Flash_ReadID                  0x90//读ID***16位
#define    Flash_ReadID_only             0x4b//读唯一ID***64位
#define    Flash_Chip_Erase_CMD          0xC7//片擦除

#define    Flash_WriteEnable_CMD         0x06
#define    Flash_WriteDisable_CMD        0x04
#define    Flash_PageProgram_CMD         0x02
#define    Flash_WriteSR_CMD             0x01
#define    Flash_ReadSR_CMD              0x05
#define    Flash_SecErase_CMD            0x20
#define    Flash_BlockErase_CMD          0xD8
#define    W25Q_4ByteAddrModeEnable      0xB7 
#define    W25Q_Exit4ByteAddrModeEnable  0xE9 
#define    Flash_PAGEBYTE_LENGTH   256
#define    Flash_SECBYTE_LENGTH    (1024*4)
#define    Flash_BLOCKBYTE_LENGTH (Flash_SECBYTE_LENGTH << 4) //Block大小

//计算FLASH存储的起始地址
#define FLASH_BLOCK_ADD(BLOCK) (BLOCK * 65536)
#define FLASH_SECTOR_ADD(BLOCK, SECTOR)  ((BLOCK * 65536) + (SECTOR * 4096))



#define W25Q128_BUFFER_LEN  256//一次读出的字节,且一定能被1024整除

typedef struct _w25q128_add_inf_
{
  unsigned int  add;//地址
  unsigned char block;//地址所在的block
  unsigned int  block_first_add;//地址所在的block的首地址
  unsigned int  block_tail_add;//地址所在的block的尾地址
  
  unsigned char sector;//地址所在的sector
  unsigned int  sector_first_add;//地址所在的sector的首地址
  unsigned int  sector_tail_add;//地址所在的sector的尾地址
  
}w25q128_add_inf;

/*******************************************************************************
** 函数声明
*******************************************************************************/
void Flash_GPIO_Init(void);
void Flash_Erase_Block(u_int8_t BlockNum);
void Flash_Erase_Sector(u_int8_t Block_Num,u_int8_t Sector_Number);
void Flash_Write_MorePage(u_int8_t *pBuffer, u_int32_t WriteAddr, u_int32_t WriteBytesNum);
void Flash_Read(u_int8_t *pBuffer,u_int32_t ReadAddr,u_int32_t ReadBytesNum);
void Enter4ByteAddrMode(void);
void Exit4ByteAddrMode(void);
void write_many_data(int n,unsigned char *p,unsigned int start_address);
void Flash_Write_Page(u_int8_t *pBuffer, u_int32_t WriteAddr, u_int32_t WriteBytesNum);
char w25q128_random_write(unsigned int write_add, unsigned int cache_add, char *data, unsigned int len);
unsigned int w25q128_random_crc(char *data, unsigned int len);
w25q128_add_inf w25q128_block_sector_to_add(unsigned char block, unsigned char sector);
w25q128_add_inf w25q128_add_to_block_sector(unsigned int add);
void FLASH_BulkErase();

void Read_w25q128_ID();
void Read_w25q128_only_ID();

#endif