////////////////////////////////////////////////////////////////////////////////

/// spi flash w25qxx系列芯片驱动
///
/// 提供接口供文件系统调用
/// @file    fatfs_flash_spi.h 
/// @author  gkl 
/// @date    2017-04-25
/// @version v0.1

////////////////////////////////////////////////////////////////////////////////

#ifndef __SPI_FLASH_H
#define __SPI_FLASH_H

#include <stdio.h>
//#include "gpio.h"
#include "diskio.h"
#include "integer.h"
#include "bsp_ser.h"

#if 1
#define FLASH_W25Q128    //16M flash
#endif
#if 0
#define FLASH_W25Q256    //32M flash
#endif

#ifdef FLASH_W25Q128
/// W25Q128 16M
#define sFLASH_ID              0XEF4018    
#endif

/// W25Q128 32M
#ifdef FLASH_W25Q256
#define sFLASH_ID              0XEF4019  
#endif

#define SPI_FLASH_PageSize              256
#define SPI_FLASH_PerWritePageSize      256

/// flash 命令定义
#define W25X_FLASH_WRITE_BUSYBIT     0X01
#define W25X_Flash_WriteSR_CMD       0x01
#define W25X_Flash_PageProgram_CMD   0x02
#ifdef FLASH_W25Q128
#define W25X_Flash_ReadData_CMD      0x03
#endif
#ifdef FLASH_W25Q256
#define W25X_Flash_ReadData_CMD      0x13   //new add
#endif
#define W25X_Flash_WriteDisable_CMD  0x04
#define W25X_Flash_ReadSR_CMD        0x05
#define W25X_Flash_WriteEnable_CMD   0x06
#define W25X_Flash_SecErase_CMD      0x20
#define W25X_Flash_ChipErase_CMD     0xC7
#define W25X_Flash_BlockErase_CMD    0xD8
#define W25X_Flash_ManufactDeviceID_CMD  0x90
#define W25X_Flash_JedecDeviceID_CMD 0X9F 
#define W25X_Flash_PAGEBYTE_LENGTH   256
#define W25X_Flash_SECBYTE_LENGTH   (1024*4)
/// Block大小
#define W25X_Flash_BLOCKBYTE_LENGTH (W25X_Flash_SECBYTE_LENGTH << 4) 

/// 单片机 SPI接口
#define SPI_FLASH_WP_ENABLE         (drv_gpio_clrbit(PORTB,4)) 
#define SPI_FLASH_DI_HIGH           (drv_gpio_setbit(PORTB,3))
#define SPI_FLASH_DI_LOW            (drv_gpio_clrbit(PORTB,3))

#define SPI_FLASH_CLK_HIGH          (drv_gpio_setbit(PORTB,2))
#define SPI_FLASH_CLK_LOW           (drv_gpio_clrbit(PORTB,2))

#define SPI_FLASH_HOLD_HIGH         (drv_gpio_setbit(PORTA,29))
#define SPI_FLASH_HOLD_LOW          (drv_gpio_clrbit(PORTA,29))

#define SPI_FLASH_CS_DISABLE        (drv_gpio_setbit(PORTA,28))
#define SPI_FLASH_CS_ENABLE         (drv_gpio_clrbit(PORTA,28))
#define SPI_FLASH_DO_READ           (drv_gpio_getbit(PORTA,27))

/// 等待超时时间
#define SPIT_FLAG_TIMEOUT           ((uint32_t)0x1000)
#define SPIT_LONG_TIMEOUT           ((uint32_t)(10*SPIT_FLAG_TIMEOUT))

/// 信息输出
#define FLASH_DEBUG_ON         0 
#define FLASH_DEBUG_FUNC_ON    0

#define FLASH_INFO(fmt,arg...)           // term_printf("<<-FLASH-INFO->> "fmt"\n",##arg)
#define FLASH_ERROR(fmt,arg...)          term_printf("<<-FLASH-ERROR->> "fmt"\n",##arg)
#define FLASH_DEBUG(fmt,arg...)          do{\
                                          if(FLASH_DEBUG_ON)\
                                          term_printf("<<-FLASH-DEBUG->> [%d]"fmt"\n",__LINE__, ##arg);\
                                          }while(0)

#define FLASH_DEBUG_FUNC()               do{\
                                         if(FLASH_DEBUG_FUNC_ON)\
                                         term_printf("<<-FLASH-FUNC->> Func:%s@Line:%d\n",__func__,__LINE__);\
                                       }while(0)



DSTATUS TM_FATFS_FLASH_SPI_disk_initialize(void);
DSTATUS TM_FATFS_FLASH_SPI_disk_status(void);
DRESULT TM_FATFS_FLASH_SPI_disk_ioctl(BYTE cmd, char *buff) ;
DRESULT TM_FATFS_FLASH_SPI_disk_read(BYTE *buff, DWORD sector, UINT count) ;
DRESULT TM_FATFS_FLASH_SPI_disk_write(BYTE *buff, DWORD sector, UINT count) ;
int GetGBKCode_from_EXFlash(unsigned char* pBuffer,const unsigned char * c);

// void SPI_FLASH_SendByte(u_int8_t DataBuffer);
// void SPI_FLASH_WaitForWriteEnd(void);
// void SPI_FLASH_WriteEnable(void);
// u_int8_t SPI_FLASH_ReadByte();
// void SPI_FLASH_BufferRead(u_int8_t* pBuffer, u_int32_t ReadAddr, u_int32_t NumByteToRead);
// void SPI_FLASH_BufferWrite(u_int8_t* pBuffer, u_int32_t WriteAddr, u_int16_t NumByteToWrite);
// u_int32_t SPI_FLASH_ReadID();
// void SPI_FLASH_PageWrite(u_int8_t* pBuffer, u_int32_t WriteAddr, u_int16_t NumByteToWrite);
// void SPI_FLASH_SectorErase(u_int32_t SectorAddr);
// void SPI_Flash_GPIO_Init(void);
// void SPI_FLASH_BulkErase();

// __SPI_FLASH_H 
#endif 

