////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) Microsoft Corporation.  All rights reserved.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////#include <tinyhal.h>
#include <tinyhal.h>

//--//
#ifndef _DRIVERS_FLASH_SD_BL_H_
#define _DRIVERS_FLASH_SD_BL_H_ 1

//SPI registers
#define SPCR0	((volatile unsigned char      *)(0xFFFF8000))
#define SSLP0	((volatile unsigned char      *)(0xFFFF8001))
#define SPPCR0	((volatile unsigned char      *)(0xFFFF8002))
#define SPSR0	((volatile unsigned char      *)(0xFFFF8003))
#define SPDR0	((volatile unsigned long      *)(0xFFFF8004))
#define SPSCR0	((volatile unsigned char      *)(0xFFFF8008))
#define SPSSR0	((volatile unsigned char      *)(0xFFFF8009))
#define SPBR0	((volatile unsigned char      *)(0xFFFF800A))
#define SPDCR0	((volatile unsigned char      *)(0xFFFF800B))
#define SPCKD0	((volatile unsigned char      *)(0xFFFF800C))
#define SSLND0	((volatile unsigned char      *)(0xFFFF800D))
#define SPND0	((volatile unsigned char      *)(0xFFFF800E))
#define SPCMD00	((volatile unsigned short     *)(0xFFFF8010))
#define SPCMD01	((volatile unsigned short     *)(0xFFFF8012))
#define SPCMD02	((volatile unsigned short     *)(0xFFFF8014))
#define SPCMD03	((volatile unsigned short     *)(0xFFFF8016))
#define SPBFCR0	((volatile unsigned char      *)(0xFFFF8020))
#define SPBFDR0	((volatile unsigned short     *)(0xFFFF8022))

#define SD_DATA_SIZE  512

#define SD_CMD_SIZE   6 

struct SH7262_SD_BS_Driver
{
    typedef BYTE CHIP_WORD;

    #define DUMMY   0xff      

    #define RESPONSE_TIME_OUT     0xFFFFFFFF

    #define CSD_CID_LENGTH        0x10

    #define SCR_LENGTH            0x8

    #define CMD8_CHECK_PATTERN    0xAA

    #define SD_GO_IDLE_STATE      0x00            // CMD0
    #define SD_SEND_IF_COND       0x08            // CMD8
    #define SD_SEND_CSD           0x09            // CMD9
    #define SD_SEND_CID           0x0A            // CMD10
    #define SD_READ_SINGLE_BLOCK  0x11            // CMD17
    #define SD_SET_BLOCKLEN       0x10            // CMD16
    #define SD_WRITE_SINGLE_BLOCK 0x18            // CMD24
    #define SD_ERASE_WR_BLK_START 0x20            // CMD32
    #define SD_ERASE_WR_BLK_END   0x21            // CMD33
    #define SD_ERASE              0x26            // CMD38
    #define SD_APP_CMD            0x37            // CMD55
    #define SD_SEND_OP_COND       0x29            // ACMD41
    #define SD_SEND_SCR           0x33            // ACMD51

    #define SD_START_DATA_BLOCK_TOKEN   0xfe      

    // R1 response code
    #define R1_IN_READY_STATUS    0x00
    #define R1_IN_IDLE_STATUS     0x01
    #define R1_ERASE_RESET        0x02
    #define R1_ILLEGAL_COOMMAND   0x04
    #define R1_COM_CRC_ERROR      0x08
    #define R1_ERASE_SEQ_ERROR    0x10
    #define R1_ADDRESS_ERROR      0x20
    #define R1_PARAMETER_ERROR    0x40

    // SD operation result 
    #define SD_SUCCESS            0x00
    #define SD_BLOCK_SET_ERROR    0x01
    #define SD_RESPONSE_ERROR     0x02
    #define SD_DATA_TOKEN_ERROR   0x03
    #define SD_INIT_ERROR         0x04
    #define SD_CRC_ERROR          0x10
    #define SD_WRITE_ERROR        0x11
    #define SD_OTHER_ERROR        0x12
    #define SD_TIMEOUT_ERROR      0xFF

    //--//

    static BOOL ChipInitialize(void *context);

    static BOOL ChipUnInitialize(void *context);

    static const BlockDeviceInfo *GetDeviceInfo(void *context);

    static BOOL Read(void *context, ByteAddress Address, UINT32 NumBytes, BYTE *pSectorBuff);

    static BOOL Write(void *context, ByteAddress Address, UINT32 NumBytes, BYTE *pSectorBuff, BOOL ReadModifyWrite);

    static BOOL Memset(void *context, ByteAddress Address, UINT8 Data, UINT32 NumBytes);

    static BOOL GetSectorMetadata(void* context, ByteAddress SectorStart, SectorMetadata* pSectorMetadata);

    static BOOL SetSectorMetadata(void* context, ByteAddress SectorStart, SectorMetadata* pSectorMetadata);

    static BOOL IsBlockErased(void *context, ByteAddress BlockStartAddress, UINT32 BlockLength);

    static BOOL EraseBlock(void *context, ByteAddress Sector);

    static void SetPowerState(void *context, UINT32 State);

    static UINT32 MaxSectorWrite_uSec(void *context);

    static UINT32 MaxBlockErase_uSec(void *context);

    static BOOL ChipReadOnly(void *context, BOOL On, UINT32 ProtectionKey);

    static BOOL ReadProductID(void *context, BYTE *ManufacturerCode, BYTE *OEMID, BYTE *ProductName);

    static BOOL EraseSectors(SectorAddress Address, INT32 SectorCount);
    static BOOL ReadSector(SectorAddress Address, UINT32 Offset, UINT32 NumBytes, BYTE *pSectorBuff, UINT32 BytesPerSector);	       
    static BOOL WriteX(void *context, ByteAddress Address, UINT32 NumBytes, BYTE *pSectorBuff, BOOL ReadModifyWrite, BOOL fIncrementDataPtr);
	static BOOL ISR(GPIO_PIN Pin, BOOL PinState, void *Param);
	static BOOL DetectInsertEject();
	
  private:
    static BOOL InsertISR();
    static BOOL EjectISR();	
    static BYTE SPI_Send1Byte(BYTE data);
	static void SPI_SendXByte(BYTE *buffer, int len);
	static BYTE SPI_Recv1Byte(void);
	static void SPI_RecvXByte(BYTE *buffer, int len);
	static void SD_ChipSelectCtrl(int f);
	static void SPI_GPIOInitialize(void);
	static int CARD_GetCardDetect(void);
	static void SPI_Initialize();
	static BOOL Xaction_nWrite8_nRead8(SPI_XACTION_8 &Transaction);
    static void SD_CsSetHigh();
    static void SD_CsSetLow();
    static BYTE SD_SendCmdWithR1Resp(BYTE cmd, UINT32 arg, BYTE crc, BYTE expectedToken, INT32 iterations=100);
    static BOOL SD_SendCmdWithR7Resp(BYTE cmd, UINT32 arg, BYTE *outVoltage);
    static BYTE SD_CheckBusy(void);
    static BOOL ReadSectorHelper(void *context, ByteAddress StartSector, UINT32 NumSectors, BYTE *pSectorBuff, SectorMetadata *pSectorMetadata);
    static void SPISendCount(BYTE *pWrite, UINT32 WriteCount);
    static void SPIRecvCount(BYTE *pRead, UINT32 ReadCount, UINT32 Offset);
};

extern SH7262_SD_BS_Driver g_SH7262_SD_BS_Driver;

#endif // _DRIVERS_FLASH_SD_BL_H_

