#ifndef _SPI_H
#define _SPI_H
#include<cyg/hal/hal_io.h>
#include<stdio.h>

#define OUTPORT		0xFC00
#define	INPORT		OUTPORT+1
#define CTR_BASE	OUTPORT+2
#define	STR_BASE	OUTPORT+3
#define CSR_BASE	OUTPORT+4
#define ESR_BASE	OUTPORT+5

//Command MX
#define RDSR		0x05
#define WREN		0x06
#define WRDI 	        0x04

#define WRITE_OK	0x10
#define	GET_OK		0x20
#define WAIT_LOOP	0xFFFFFFFF
//#define SECTOR_SIZE	0x10000  	//64KB

#define FIFO_SIZE	16
#define MAX_CYCLE	256

#define CS_ENABLE  	HAL_WRITE_UINT8(CSR_BASE, 0);
#define CS_DISABLE	HAL_WRITE_UINT8(CSR_BASE, 1);

#define MANUFACTURE_SST		0xBF
#define MANUFACTURE_MX		0xC2
#define MANUFACTURE_ST          0x20
#define MANUFACTURE_ATMEL       0x1F
#define MANUFACTURE_NEXFLASH    0xEF

#define FIFO_ENABLE		0x10
#define AUTO_FETCH_DISABLE	0x20
struct spi_info {
	unsigned char manufacture_id;
	unsigned char device_id;
	unsigned long flash_base;
	unsigned long block_size;
	unsigned char cmd_erase;
	unsigned char cmd_write;
	//unsigned long flash_size;
};
#if 0
struct spi_device {
        unsigned long flash_base;
	unsigned long block_size;
	unsigned char  cmd_erase;
	unsigned char cmd_write;
	int (*erase)(int block_num);
	int (*write)(unsigned long src,unsigned long dst,unsigned long len);
     
};
#endif	

#define SPI_CHECK_OUT	\
{			\
	unsigned char value;	\
	unsigned long loop=WAIT_LOOP	;\
	while(loop --)	\
	{		\
	  HAL_READ_UINT8(STR_BASE,value);	\
	  if( value & WRITE_OK )	\
		break;			\
	}				\
					\
}						
		


#define SPI_CHECK_IN		\
{				\
	unsigned char value;	\
   	unsigned long loop= WAIT_LOOP;	\
   					\
   	HAL_WRITE_UINT8(INPORT,0);			\
   	while( loop --)			\
        {							\
	 HAL_READ_UINT8(STR_BASE,value);\
	 if( value & GET_OK)	\
	    break;			\
        }				\
}

#define SPI_CHECK_BUSY	\
{			\
	unsigned char value;			\
     	unsigned long loop = WAIT_LOOP ;	\
	CS_DISABLE			\
	while( loop --)			\
	{				\
	  CS_ENABLE			\
          HAL_WRITE_UINT8(OUTPORT,RDSR);		\
	  SPI_CHECK_OUT			\
					\
	  SPI_CHECK_IN			\
	  CS_DISABLE			\
	  HAL_READ_UINT8(INPORT,value);\
	  if(! ( value  & 1 ))	\
		break;			\
	}				\
}

#define SPI_WRITE(CMD,AD1,AD2,AD3)	\
{					\
	SPI_CHECK_BUSY			\
					\
 	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,WREN);		\
	SPI_CHECK_OUT			\
	CS_DISABLE			\
					\
	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,CMD);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD3);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD2);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD1);		\
	SPI_CHECK_OUT			\
					\
}

#define SPI_READ(CMD,AD1,AD2,AD3)	\
{					\
	CS_DISABLE			\
					\
	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,CMD);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD3);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD2);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD1);		\
	SPI_CHECK_OUT			\
					\
}

#define SPI_FREAD(CMD,AD1,AD2,AD3)	\
{					\
	CS_DISABLE			\
					\
	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,CMD);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD3);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD2);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD1);		\
	SPI_CHECK_OUT			\
					\
					\
	HAL_WRITE_UINT8(OUTPORT,AD1);	   	\
	SPI_CHECK_OUT			\
					\
}

#define SECTOR_ERASE(CMD,AD1,AD2,AD3)	\
{					\
	SPI_CHECK_BUSY			\
					\
	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,WREN);		\
	SPI_CHECK_OUT			\
	CS_DISABLE			\
					\
	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,CMD);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD3);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD2);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD1);		\
	SPI_CHECK_OUT			\
	CS_DISABLE			\
					\
					\
}

#define CHIP_ERASE(CMD)			\
{					\
	SPI_CHECK_BUSY			\
					\
	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,WREN);		\
	SPI_CHECK_OUT			\
	CS_DISABLE			\
					\
	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,CMD);		\
	SPI_CHECK_OUT			\
	CS_DISABLE			\
}

#define SPI_RDID(CMD)			\
{                                         \
	HAL_WRITE_UINT8(OUTPORT,CMD);	\
	SPI_CHECK_OUT;			\
}
	
#define SST_AAI_START(AD1,AD2,AD3,DATA)\
{					\
	SPI_CHECK_BUSY			\
					\
	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,WREN);	\
	SPI_CHECK_OUT			\
	CS_DISABLE			\
					\
	CS_ENABLE			\
	HAL_WRITE_UINT8(OUTPORT,0xAF);	\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD3);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD2);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,AD1);		\
	SPI_CHECK_OUT			\
					\
	HAL_WRITE_UINT8(OUTPORT,DATA);		\
	SPI_CHECK_OUT			\
					\
	SPI_CHECK_BUSY			\
			\
	CS_DISABLE	\
}

#define SST_AAI_STOP		\
{				\
	unsigned char value;			\
     	unsigned long loop = WAIT_LOOP ;	\
						\
	SPI_CHECK_BUSY		\
				\
	CS_ENABLE		\
	HAL_WRITE_UINT8(OUTPORT,WRDI);	\
	SPI_CHECK_OUT			\
					\
	CS_DISABLE			\
					\
	CS_ENABLE			\
	while( loop --)			\
	{					\
	    HAL_WRITE_UINT8(OUTPORT,RDSR);	\
	    SPI_CHECK_IN			\
		    				\
	    HAL_READ_UINT8(INPORT,value);	\
            					\
	    if(! (value & 2 ))			\
	        break ;				\
	}					\
	CS_DISABLE				\
}
	        
	    
		  
	

		
   	
	
	
	

#endif

