#include "sdio_drv.h"
#include "uart.h"
#include "delay.h"
#include "sys.h"
#include "spi_func.h"
#include "eport_drv.h"
#include "edma_drv.h"
//#include "bsp.h"

////进行移植时,需要修改
//void SD_SPI_Configuration(void)//配置SPI接口	
//{
//    SPI_InitTypeDef SPI_InitStruct ;
// 
//    EPORT_ConfigGpio(EPORT_PIN3,GPIO_OUTPUT);
//	
//	SPI_Cmd(SPI1,DISABLE);
//	//////SPI模块配置//////

//	SPI_InitStruct.SPI_Direction  	     =  SPI_Direction_2Lines_FullDuplex;
//	SPI_InitStruct.SPI_Mode              =  SPI_MASTERMODE;
//	SPI_InitStruct.SPI_DataSize          =  SPI_DataSize_8b;
//	SPI_InitStruct.SPI_CPOL              =  SPI_CPOL_High;
//	SPI_InitStruct.SPI_CPHA              =  SPI_CPHA_2Edge;
//	SPI_InitStruct.SPI_BaudRatePrescaler =  SPI_BaudRatePrescaler_256;
//	SPI_InitStruct.SPI_FirstBit          =  SPI_FirstBit_MSB;
//	SPI_InitStruct.SPI_CRCPolynomial     =  7;
//	
//	SPI_Init(SPI1, &SPI_InitStruct);                                      //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器

//	SPI_Cmd(SPI1,ENABLE);	
//}
// 
//  
////进行移植时,需要修改
//void SD_SPI_HightSpeed(void)  //提高SD卡的读写速度
//{
//    SPI_InitTypeDef SPI_InitStruct ;
// 
//	SPI_Cmd(SPI1,DISABLE);

//    //////SPI模块配置//////
//  	/* SPI1 Config */
//	SPI_InitStruct.SPI_Direction  	     =  SPI_Direction_2Lines_FullDuplex;
//	SPI_InitStruct.SPI_Mode              =  SPI_MASTERMODE;
//	SPI_InitStruct.SPI_DataSize          =  SPI_DataSize_8b;
//	SPI_InitStruct.SPI_CPOL              =  SPI_CPOL_High;
//	SPI_InitStruct.SPI_CPHA              =  SPI_CPHA_2Edge;
//	SPI_InitStruct.SPI_BaudRatePrescaler =  SPI_BaudRatePrescaler_256;
//	SPI_InitStruct.SPI_FirstBit          =  SPI_FirstBit_MSB;
//	SPI_InitStruct.SPI_CRCPolynomial     =  7;

//	SPI_Init(SPI1, &SPI_InitStruct);                                      //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
//	SPI_Cmd(SPI1,ENABLE);	
//}  


//*************************************** SPI3 **********************************************
void SPI3_Initial(void)
{
	SPI_ConfigGpio(SPI3, SPI_SS, GPIO_OUTPUT);  //cs
	SPI_Cmd(SPI3,DISABLE);

/*	
	SPI_InitTypeDef SPI_InitStruct;

	SPI_Cmd(SPI3,DISABLE);
	//SPI模块配置
	SPI_InitStruct.SPI_Direction  	     =  SPI_Direction_2Lines_FullDuplex;
	SPI_InitStruct.SPI_Mode              =  SPI_MASTERMODE;
	SPI_InitStruct.SPI_DataSize          =  SPI_DataSize_8b;
	SPI_InitStruct.SPI_CPOL              =  SPI_CPOL_High;
	SPI_InitStruct.SPI_CPHA              =  SPI_CPHA_2Edge;
	SPI_InitStruct.SPI_BaudRatePrescaler =  SPI_BaudRatePrescaler_256;
	SPI_InitStruct.SPI_FirstBit          =  SPI_FirstBit_MSB;
	SPI_InitStruct.SPI_CRCPolynomial     =  7;
	SPI_Init(SPI3, &SPI_InitStruct);                                      //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
*/	
	SPI_Init(SPI3, SPI_MASTERMODE); 
	
	SPI3->SPIDMACR &= (~0x03);	//禁止SPI TX RX的DMA

	SPI_Cmd(SPI3,ENABLE);
	SPI3_ReadWriteByte(0xff);
}


UINT16 SPI3_ReadWriteByte(UINT16 TxData)
{	
	u16 retry=0;				 
	while((SPI3->SPISRHW)&(SPISR_TXFFULL_MASK)) //等待发送区空	
	{
		retry++;
		if(retry>=0XFFFE)return 0; 	//超时退出
	}			  
	SPI3->SPIDR=TxData;	 	  		//发送一个byte 
	retry=0;
	while((SPI3->SPISRHW) & (SPISR_RXFEMP_MASK)) 		//等待接收完一个byte  
	{
		retry++;
		if(retry>=0XFFFE)return 0;	//超时退出
	}	  						    
	return SPI3->SPIDR;          		//返回收到的数据
	
}

void SPI3_SetSpeed(u16 speed)
{
	SPI_Cmd(SPI3,DISABLE);
/*	
	SPI_InitTypeDef SPI_InitStruct;

    //////SPI模块配置//////
  	//  SPI1 Config 
	SPI_InitStruct.SPI_Direction  	     =  SPI_Direction_2Lines_FullDuplex;
	SPI_InitStruct.SPI_Mode              =  SPI_Mode_Master;
	SPI_InitStruct.SPI_DataSize          =  SPI_DataSize_8b;
	SPI_InitStruct.SPI_CPOL              =  SPI_CPOL_High;
	SPI_InitStruct.SPI_CPHA              =  SPI_CPHA_2Edge;
	SPI_InitStruct.SPI_BaudRatePrescaler =  speed;
	SPI_InitStruct.SPI_FirstBit          =  SPI_FirstBit_MSB;
	SPI_InitStruct.SPI_CRCPolynomial     =  7;

	SPI_Init(SPI3, &SPI_InitStruct);                                      //根据SPI_InitStruct中指定的参数初始化外设SPIx寄存器
*/
	rSPI_Attr[2].SPI_BaudRatePrescaler=speed;
	SPI_Init(SPI3, SPI_MASTERMODE);
	
	SPI_Cmd(SPI3,ENABLE);	

	SPI3_ReadWriteByte(0xff);
}


u8  SD_Type=0;//SD卡的类型 
 
#define Speed_High SPI_BaudRatePrescaler_4


//@brief: SD卡初始化
//@param :
//@retval: 1：错误 r1:命令响应
u8 SD_Init(void)
{
	u16 i;
	u8 r1;
	u16 retry;
	u8 buff[6];

	SPI3_Initial();                                      //初始化SPI1

	SPI3_SetSpeed(SPI_BaudRatePrescaler_256);         //SD卡初始化时钟不能超过400KHz
	
//	SD_CS = 1;                                        //打开SD卡片选引脚
	SD_CS_SET;
	DelayMS(5);                                      //等待SD卡上电稳定，完成初始化

	for(i=0;i<10;i++)
	{
		SPI3_ReadWriteByte(0xff);                       //产生80个时钟脉冲
	}

//将SD卡复位至idle状态
	
//	SD_CS = 0; 
	SD_CS_RESET;
	retry = 0;
	do
	{
		r1 = SD_SendCommand(CMD0,0,0X95);               //发送CMD0
		SPI3_ReadWriteByte(0xff);
		retry++;
	}while((r1!=0x01)&&(retry<200));                  //收到正确响应或超时后退出

	if(retry==200)                                    //如果退出原因为超时
	{
		return 1;
	}

	r1= SD_SendCommand(CMD8,0x01aa,0x87);                 //如果退出原因为SD卡复位至idle并收到正确响应，继续发送CMD8获取SD卡版本信息
 //如果是v2.0版本的SD卡
	if(r1==0x01)                                      //接收到CMD8的正确响应接收CMD8响应后续传送的4字节数据
	{
		buff[0] = SPI3_ReadWriteByte(0xff);             //接收CMD8响应后续传送的4字节数据
		buff[1] = SPI3_ReadWriteByte(0xff);
		buff[2] = SPI3_ReadWriteByte(0xff);
		buff[3] = SPI3_ReadWriteByte(0xff);

//		SD_CS = 1;

//		SPI3_ReadWriteByte(0xff);                       //多发送8个时钟信号

 //开始初始化SD卡
		
//		SD_CS = 0;
		SD_CS_RESET;
		retry = 0;

		do
		{
			r1 = SD_SendCommand(CMD55,0,0xff);               //发送CMD55，通知SD卡下一条命令为应用相关命令而非通用命令
			SPI3_ReadWriteByte(0xff);
			if(r1!=0x01)                                  //如果主机未接收到CMD55的正确响应
				return r1;
			r1 = SD_SendCommand(ACMD41,0x40000000,1);      //否则继续发送ACMD41
			SPI3_ReadWriteByte(0xff);
			retry++;
			if(retry>200)
				return r1;                                  //超时退出
		}while(r1!=0);                                  //接收到ACMD41的正确响应退出
		
//		SD_CS = 1;
		SD_CS_SET;
		SPI3_ReadWriteByte(0xff);
		
//		SD_CS = 0;
		SD_CS_RESET;
 //初始化指令发送完成，继续获取OCR信息
 //识别SD2.00版本的SD卡类型

		r1 = SD_SendCommand_NoDeassert(CMD58,0,0);      //发送CMD58

		if(r1!=0x00)
			return r1;                                    //未接收到CMD58的正确响应退出
		buff[0] = SPI3_ReadWriteByte(0xff);             //否则接收CMD58响应后续传回的4字节COR信息
		buff[1] = SPI3_ReadWriteByte(0xff);
		buff[2] = SPI3_ReadWriteByte(0xff);
		buff[3] = SPI3_ReadWriteByte(0xff);

//		SD_CS =1;
		SD_CS_SET;
		SPI3_ReadWriteByte(0xff);

 //分析OCR信息中的bit30(CCS)判断卡的类型
 //CCS=1,SDHC;CCS=0;SD2.0;
		
	if(buff[0]&0x40)
	{
		SD_Type = SD_TYPE_V2HC;                         //类型为SDHC
	}
	else
	{
		SD_Type = SD_TYPE_V2;                           //类型为SD2.0
	}
	SPI3_SetSpeed(Speed_High);           //SPI4时钟频率配置为45MHz

	}
	//printf("SD_Type:%d\r\n",SD_Type);
	return 0;
	
}

//@brief:向SD卡发送命令（发送结束后关闭片选信号）
//@param:cmd start bit+transmission bit+command index
//@param:arg
//@param :crc CRC7+end bit
//@retval: r1:命令响应
u8 SD_SendCommand(u8 cmd,u32 arg,u8 crc)
{
	unsigned char r1;
	unsigned int Retry = 0;

//	SD_CS = 1;
	SD_CS_SET;
	SPI3_ReadWriteByte(0xff);

//	SD_CS = 0;
	SD_CS_RESET;
	SPI3_ReadWriteByte(cmd|0x40);                                //将CMD命令中的传输位设置为1
	SPI3_ReadWriteByte((u8)(arg>>24));                           //写入CMD命令的32位参数
	SPI3_ReadWriteByte((u8)(arg>>16));
	SPI3_ReadWriteByte((u8)(arg>>8));
	SPI3_ReadWriteByte((u8)(arg));
	SPI3_ReadWriteByte(crc);                                     //写入CRC校验和

	while((r1 = SPI3_ReadWriteByte(0xff))==0xff)                 //接收到相关命令的正确响应后退出
	{
		Retry++;
		if(Retry>800) break;                                       //超时退出
	}

//	SD_CS = 1;
	SD_CS_SET;
	SPI3_ReadWriteByte(0xff);                                    //额外发送8个时钟信号，使SD卡完成剩余工作

	return r1;
}

//@brief:向SD卡发送命令（发送结束后持续打开片选信号）
//@param:cmd start bit+transmission bit+command index
//@param:arg
//@param :crc CRC7+end bit
//@retval:r1:命令响应
u8 SD_SendCommand_NoDeassert(u8 cmd,u32 arg,u8 crc)
{
	unsigned char r1;
	unsigned int Retry = 0;

//	SD_CS = 1;
	SD_CS_SET;
	SPI3_ReadWriteByte(0xff);

//	SD_CS = 0;
	SD_CS_RESET;
	SPI3_ReadWriteByte(cmd|0x40);
	SPI3_ReadWriteByte((u8)(arg>>24));
	SPI3_ReadWriteByte((u8)(arg>>16));
	SPI3_ReadWriteByte((u8)(arg>>8));
	SPI3_ReadWriteByte((u8)(arg));
	SPI3_ReadWriteByte(crc);

	while((r1 = SPI3_ReadWriteByte(0xff))==0xff)
	{
		Retry++;
		if(Retry >800) break;
	}
	return r1;
}
//@brief:从SD卡中读取指定长度的数据
//@param:*data 指向存储读回数据的缓冲区的指针
//@param:len 数据长度
//@param:release 读取结束后是否释放总线
//@retval:1：错误 0：正确
u8 SD_ReceiveData(u8 *data,u16 len,u8 release)
{
	u16 retry;
	u8 r1;
	u8 tx_buff[512] = {0};
	

//	SD_CS = 0;
	SD_CS_RESET;
	retry = 0;
	do
	{
		r1 = SPI3_ReadWriteByte(0xff);
		retry++;
		if(retry>4000)
		{
//			SD_CS  = 1;
			SD_CS_SET;
			return 1;                                      //超时退出
		}
	}while(r1!=0xfe);                                  //主机收到SD卡传回的正确数据读取响应退出

	
/*****************************正常模式*************************************/	
//接收到正确响应后，开始接收数据
	while(len--)
	{
		*data = SPI3_ReadWriteByte(0xff);
		data++;
	}
/*****************************正常模式*************************************/	
	
/*****************************DMA模式*************************************/	
//	SPI3_DMA_Tran(tx_buff,data,len);
//	SPI3_DMA_Wait();
	
//	SPI_EnableDMA(SPI1,TRUE);
//	dma_spitran(0,tx_buff,data,len,0);
//	SPI_EnableDMA(SPI1,FALSE);

/*****************************DMA模式*************************************/	

	
	SPI3_ReadWriteByte(0xff);                          //发送2个无效CRC
	SPI3_ReadWriteByte(0xff);

	if(release == RELEASE)                             //是否需要释放总线
	{
//		SD_CS = 1;
		SD_CS_SET;
		SPI3_ReadWriteByte(0xff);
	}

	return 0;
}

//@brief:获取CID寄存器数据
//@param:*cid_data 指向存储CID寄存器数据的缓冲区的指针
//@retval:0：正确 r1:命令响应
u8 SD_GetCID(u8 *cid_data)
{
	u8 r1;
	

	r1 = SD_SendCommand(CMD10,0,0xff);                    //发送CMD10命令以获取CID寄存器数据
	if(r1!=0x00)
		return r1;                                      //主机未接收到正确响应退出

		SD_ReceiveData(cid_data,16,RELEASE);            //接收CID寄存器数据并释放总线
		return 0;
}

//@brief:获取CSD寄存器数据
//@param:*csd_data 指向存储CSD寄存器数据的缓冲区的指针
//@retval:0：正确 r1：命令响应
u8 SD_GetCSD(u8 *csd_data)
{
	u8 r1;
	

	r1 = SD_SendCommand(CMD9,0,0xff);                     //发送CMD9命令以获取CSD寄存器数据
	if(r1!=0x00)
		return r1;                                      //主机未接收到正确响应退出

		SD_ReceiveData(csd_data,16,RELEASE);            //接收CSD寄存器数据并释放总线
		return 0;
}

//@brief:获取SD卡容量信息
//@param：
//@retval:Capacity：SD卡容量
u32 SD_GetCapacity(void)
{
    u8 csd[16];
    u32 Capacity;
    u8 r1;
    u16 i;
    u16 temp;

    if(SD_GetCSD(csd)!=0)
    return 0;                                      //未成功获取CSD寄存器数据退出

    if((csd[0]&0xC0)==0x40)                        //如果CSD寄存器版本为v2.0
    {
			Capacity=((u32)csd[8])<<8;
      Capacity+=(u32)csd[9]+1;
			Capacity = ((u32)Capacity)/2;
       //Capacity = (Capacity)*1024;	              //得到扇区数
       //Capacity*=512;	                            //得到字节数
			
    }
    else		                                      //如果CSD寄存器版本是v1.0
    {
       i = csd[6]&0x03;
       i<<=8;
       i += csd[7];
       i<<=2;
       i += ((csd[8]&0xc0)>>6);
       r1 = csd[9]&0x03;
       r1<<=1;
       r1 += ((csd[10]&0x80)>>7);
       r1+=2;
       temp = 1;
       while(r1)
       {
        temp*=2;
         r1--;
       }
       Capacity = ((u32)(i+1))*((u32)temp);
       i = csd[5]&0x0f;
       temp = 1;
   while(i)
   {
      temp*=2;
      i--;
   }

   Capacity *= (u32)temp;                          //得到字节数
   }
   return (u32)Capacity;                           //返回SD卡容量（字节）
}

//@brief:singleblock读取
//@param:sector 数据地址（扇区地址）
//@param:*buffer 指向存储读回数据的缓冲的指针
//@retval:0：正确 r1:命令响应
u8 SD_ReadSector(u32 sector, u8 *buffer)
{
  u8 r1;
	

  SPI3_SetSpeed(Speed_High);          //SPI4时钟频率配置为45MHz

  if(SD_Type!=SD_TYPE_V2HC)	                        //如果不是SDHC卡
  {
    sector = sector<<9;	                            //512*sector即物理扇区的边界对齐地址
  }
   r1 = SD_SendCommand(CMD17,sector, 1);	          //发送CMD17 读单块命令
   if(r1 != 0x00)	return r1;                        //未接收到CMD17的正确响应退出
   r1 = SD_ReceiveData(buffer, 512, RELEASE);	      //一个扇区为512字节 读取数据并释放总线
   if(r1 != 0)
     return r1;                                     //读取数据失败退出
   else
     return 0; 	                                  	//读取数据成功
}

//@brief:multiblock读取
//@param:sector 数据地址（扇区地址）
//@param：*buff 指向存储读回数据的缓冲的指针
//@param：count 要读取的扇区数量
//@retval：0：正确 count：未处理完扇区数 r1:命令响应
u8 SD_ReadSectors(u32 sector, u8 *buff, u32 count)
{
  u8 r1;
 
  SPI3_SetSpeed(Speed_High);                       //SPI1时钟频率配置为45MHz
  if(SD_Type != SD_TYPE_V2HC)
  {
    	sector = sector<<9;
  }
  r1 = SD_SendCommand(CMD18, sector, 1);                        //发送CMD18 读多块命令
  if(r1 != 0x00)	return r1;
  do	                                                          //开始接收数据
  {
    	if(SD_ReceiveData((u8 *)buff, 512, NO_RELEASE) != 0x00)       //读取数据完成后不释放总线
    	{
       		break;                                                //读取数据失败退出
    	}
    	buff += 512;
  }while(--count);                                              //数据接收全部完成

  SD_SendCommand(CMD12, 0, 1);	                                //全部传输完成，发送停止命令
//  SD_CS=1;      	                                            //释放总线
	SD_CS_SET;
  
  SPI3_ReadWriteByte(0xFF);
  if(count != 0)
    return count;                                               //如果数据传输中途因错误退出，返回剩余扇区个数
  else
    return 0;
}

//@brief:SD卡繁忙检测
//@param：
//@retval：0：空闲 1：繁忙
u8 SD_WaitReady(void)
{
  u8 r1;
  u16 retry=0;
  do
  {
    r1 = SPI3_ReadWriteByte(0xFF);              //当SD卡繁忙，数据线会被拉低；当SD卡结束繁忙后，数据线会被拉高
    retry++;
    if(retry==0xfffe)
    	return 1;
  }while(r1!=0xFF);
    	return 0;
}

//@brief:singleblock写入
//@param:sector 数据地址（扇区地址）
//@param:*data 指向存储要写入SD卡的数据的缓冲区的指针
//@retval：0：正确 1：超时 r1:命令响应
u8 SD_WriteSector(u32 sector, const u8 *data)
{
  	u8 r1;
  	u16 i;
  	u16 retry;

  	SPI3_SetSpeed(SPI_BaudRatePrescaler_256);                       //SPI4时钟频率配置为45MHz

	if (SD_Type!=SD_TYPE_V2HC) sector = sector<<9;                                   	//如果不是SDHC卡，将sector地址转为byte地址
     		
	r1 = SD_SendCommand(CMD24, sector, 0x00);	                //发送CMD24 写扇区命令
  	if(r1 != 0x00) return r1;

//        SD_CS = 0;                                           //开始准备写入数据
	SD_CS_RESET;
  	SPI3_ReadWriteByte(0xff);                                      //先发3个空数据，等待SD卡准备好
  	SPI3_ReadWriteByte(0xff);
  	SPI3_ReadWriteByte(0xff);

	SPI3_ReadWriteByte(0xFE);                                      //发送数据发送起始符号

  	for (i=0;i<512;i++)                                            //发送一个sector的数据
		SPI3_ReadWriteByte(*data++);

  	SPI3_ReadWriteByte(0xff);                                      //发送2个无效CRC校验
  	SPI3_ReadWriteByte(0xff);

  	r1 = SPI3_ReadWriteByte(0xff);                                 //等待SD卡的数据响应符号

  	if((r1&0x1F)!=0x05)                                           //如果为r1=0x05则数据写入成功
  	{
//     		SD_CS = 1;
		SD_CS_SET;
		return r1;                                                //否则释放总线并退出
  	}

  	retry = 0;                                                  	//等待操作完成

  	while(!SPI3_ReadWriteByte(0xff))                               //SD卡自编程时，数据线被拉低
  	{
		retry++;
		if(retry>65534)                                           //如果超时写入未完成，退出报错
		{
//   		SD_CS = 1;
			SD_CS_SET;
			return 1;                                             //写入超时，返回1
		}
  	}

//  	SD_CS = 1;                                               //写入完成，片选置1
	SD_CS_SET;
	SPI3_ReadWriteByte(0xff);
	return 0;
}

//@brief:multiblock写入
//@param:sector 数据地址（扇区地址）
//@param:*data 指向存储要写入SD卡的数据的缓冲区的指针
//@param:count 要写入的扇区数量
//@retval：0：正确 1：超时 count：未处理完扇区数 r1:命令响应
u8 SD_WriteSectors(u32 sector,const u8 *data, u8 count)
{
  	u8 r1;
  	u16 i;

  	SPI3_SetSpeed(SPI_BaudRatePrescaler_256);                       //SPI4时钟频率配置为45MHz

  	if(SD_Type != SD_TYPE_V2HC) sector = sector<<9;

  	/*if(SD_Type != SD_TYPE_MMC)
	{
		r1 = SD_SendCommand(ACMD23, count, 0x01);               //启用ACMD23指令使能预擦除
	}*/

	r1 = SD_SendCommand(CMD25, sector, 0x01);                  //发送CMD25 写多块命令

  	if(r1 != 0x00)	return r1;

//  	SD_CS = 0;                                                  //开始准备数据传输
	SD_CS_RESET;
		
  	SPI3_ReadWriteByte(0xff);                                       //发送3个空数据让SD卡准备好
  	SPI3_ReadWriteByte(0xff);
	SPI3_ReadWriteByte(0xff);

  	do                                                            //下面是N个sector循环写入的部分
  	{
		SPI3_ReadWriteByte(0xFC);                                //发送数据传输起始符号0xFC，表明是多块写入
		for(i=0;i<512;i++)                                      //发1个sector的数据
        	SPI3_ReadWriteByte(*data++);

		SPI3_ReadWriteByte(0xff);                                     //发2个伪CRC
		SPI3_ReadWriteByte(0xff);

		r1 = SPI3_ReadWriteByte(0xff);                           //等待SD卡回应

		if((r1&0x1F)!=0x05)                                     //如果r1=0x05则表示数据写入成功
		{
// 		SD_CS = 1;                                         //写入失败则释放总线退出
        	SD_CS_SET;
			return r1;
		}

		if(SD_WaitReady()==1)                                   //检测SD卡忙信号
		{
//   		SD_CS = 1;                                           //如果长时间写入未完成，释放总线并退出
        	SD_CS_SET;
			return 1;
		}
   }while(--count);

	SPI3_ReadWriteByte(0xFD);                                   //发送数据传输结束符号0xFD

	if(SD_WaitReady())                                         //等待准备好
	{
// 	SD_CS = 1;                                            //超时未退出繁忙则释放总线并退出
		SD_CS_SET;
		return 1;
	}

// 	SD_CS = 1;                                           //写入完成，片选置1
	SD_CS_SET;
	SPI3_ReadWriteByte(0xff);
	return count;                                              //返回count值，如果写完，则count=0,否则count=未写完的sector数
}

/*
2020-2-19 
添加的SD卡烧录Flash 程序

*/



/************文件系统头文件***********/
/*
#include "ff.h"
#include "SPI_SD.h"
#include "diskio.h"
#include "w25n01.h"
#include "w25qxx.h"
#include "pit.h"
#include "bsp.h"
#include "cpm_drv.h"
#include "qspi.h"

#include "bsp.h"
#include "reset_drv.h"


UINT8 Sd_To_Flash(void)
{
	BYTE buf[2048];
	FATFS fs;
	FIL fsrc;
	FRESULT res;
	UINT br;
	u8 num=0,sd_flag=0;
	u16 page=0;
	u32 k,addr = 0,size = 0,Block_Num;
	
	if(Horizontal_screen==0)
	{
		LT268_TFT_FillColor(0,0,320,480,Blue2);
		LT268_TFT_ShowAscii(50,200,24,0,Red,Blue2,(UINT8 *)"Automatically update ");
		LT268_TFT_ShowAscii(62,223,24,0,Red,Blue2,(UINT8 *)"flash after 3 s");
		DelayMS(1000);
		LT268_TFT_FillColor(200,223,24,24,Blue2);
		LT268_TFT_ShowAscii(205,223,24,0,Red,Blue2,(UINT8 *)"2");
		DelayMS(1000);
		LT268_TFT_FillColor(200,223,24,24,Blue2);
		LT268_TFT_ShowAscii(205,223,24,0,Red,Blue2,(UINT8 *)"1");
		DelayMS(500);	
	}
	else
	{
		LT268_TFT_FillColor(0,0,480,320,Blue2);
		LT268_TFT_ShowAscii(77,100,24,0,Red,Blue2,(UINT8 *)"Automatically update");
		LT268_TFT_ShowAscii(93,134,24,0,Red,Blue2,(UINT8 *)"flash after 3 s");
		DelayMS(1000);
		LT268_TFT_FillColor(237,134,24,24,Blue2);
		LT268_TFT_ShowAscii(237,134,24,0,Red,Blue2,(UINT8 *)"2");
		DelayMS(1000);
		LT268_TFT_FillColor(237,134,24,24,Blue2);
		LT268_TFT_ShowAscii(237,134,24,0,Red,Blue2,(UINT8 *)"1");
		DelayMS(500);	
	}
	
	while(1)
	{
	  if(!(CPM->CPM_PADWKINTCR>>25)) 
	  {	
			if(Horizontal_screen==0)
			{	
				LT268_TFT_FillColor(0,0,320,480,Blue2);
				LT268_TFT_ShowAscii(111,200,24,0,Red,Blue2,(UINT8 *)"updating");
				LT268_TFT_ShowAscii(220,200,24,0,Red,Blue2,(UINT8 *)" 0%");
			}
			else
			{
				LT268_TFT_FillColor(0,0,480,320,Blue2);
				LT268_TFT_ShowAscii(111,200,24,0,Red,Blue2,(UINT8 *)"updating");
				LT268_TFT_ShowAscii(220,200,24,0,Red,Blue2,(UINT8 *)" 0%");
			}
	 }
	else
	{
			Set_POR_Reset();
	}
	
//		FF_Update_Flag = 2;
	
		PIT1_Init_SD();
	
		SSI1_STD_Init(SSI1);
		Flash_ID=W25QXX_ReadID();
		if(NANDFlash_ReadID()==0xefaa21) {  Flash_Type=2; W25N01GV_Init(); }
		else 	                             {  Flash_Type=0; W25QXX_Init();   }
		//printf("Flash_ID==0X%x    \r\n",Flash_ID);
		
		f_mount(&fs,"0:",1);
		res=f_open(&fsrc,"0:/UartTFT_Flash/UartTFT_Flash.bin",FA_OPEN_EXISTING|FA_READ);

		if(res==0)
		{	
			size = f_size(&fsrc);
						
			if(Flash_Type!=2)
			{
				Block_Num=size/NorBlockSize;

				for(k=0;k<=Block_Num;k++)          //擦除Nor_Flash
				{
					W25QXX_BlockErase64KB(k*NorBlockSize);
				}
			}
			else
			{
				Block_Num=size/NandBlockSize;           
				for(k=0;k<=Block_Num;k++)          //擦除Nand_Flash
				{
					LT_W25N01GV_BlockErase128KB(k*NandBlockSize);
				}
			}
//			printf(" Erase flash ok         \r\n      ");

			
			while(1)
			{
				num = addr * 100 / size;

				if(20<=num&&num<40&&sd_flag==0)
				{   
					sd_flag=1;
					f_close(&fsrc);
					
					SPI_ConfigGpio(SPI3, SPI_SS, GPIO_OUTPUT);	//DB2						
					SPI_ConfigGpio(SPI3, SPI_SCK, GPIO_OUTPUT);	//DB2
					SPI_ConfigGpio(SPI3, SPI_MOSI, GPIO_OUTPUT);	//DB1
					SPI_ConfigGpio(SPI3, SPI_MISO, GPIO_OUTPUT);	//DB0
					LT268_TFT_FillColor(220,200,24,24,Blue2);
					LT268_TFT_ShowAscii(220,200,24,0,Red,Blue2,(UINT8 *)"20%");
					
				  f_mount(&fs,"0:",1);
					res=f_open(&fsrc,"0:/UartTFT_Flash/UartTFT_Flash.bin",FA_OPEN_EXISTING|FA_READ);
					f_lseek(&fsrc,addr);		 
				}
				else if(40<=num&&num<60&&sd_flag==1)
				{
					sd_flag=2;
					f_close(&fsrc);
					
					SPI_ConfigGpio(SPI3, SPI_SS, GPIO_OUTPUT);	//DB2						
					SPI_ConfigGpio(SPI3, SPI_SCK, GPIO_OUTPUT);	//DB2
					SPI_ConfigGpio(SPI3, SPI_MOSI, GPIO_OUTPUT);	//DB1
					SPI_ConfigGpio(SPI3, SPI_MISO, GPIO_OUTPUT);	//DB0
					LT268_TFT_FillColor(220,200,24,24,Blue2);
					LT268_TFT_ShowAscii(220,200,24,0,Red,Blue2,(UINT8 *)"40%");
					
				  f_mount(&fs,"0:",1);
					res=f_open(&fsrc,"0:/UartTFT_Flash/UartTFT_Flash.bin",FA_OPEN_EXISTING|FA_READ);
					f_lseek(&fsrc,addr);
				}		
				else if(60<=num&&num<80&&sd_flag==2)
				{
					sd_flag=3;
					f_close(&fsrc);
					
					SPI_ConfigGpio(SPI3, SPI_SS, GPIO_OUTPUT);	//DB2						
					SPI_ConfigGpio(SPI3, SPI_SCK, GPIO_OUTPUT);	//DB2
					SPI_ConfigGpio(SPI3, SPI_MOSI, GPIO_OUTPUT);	//DB1
					SPI_ConfigGpio(SPI3, SPI_MISO, GPIO_OUTPUT);	//DB0
					LT268_TFT_FillColor(220,200,24,24,Blue2);
					LT268_TFT_ShowAscii(220,200,24,0,Red,Blue2,(UINT8 *)"60%");
					
				  f_mount(&fs,"0:",1);
					res=f_open(&fsrc,"0:/UartTFT_Flash/UartTFT_Flash.bin",FA_OPEN_EXISTING|FA_READ);
					f_lseek(&fsrc,addr);
				}
				else if(80<=num&&num<100&&sd_flag==3)
				{
					sd_flag=4;
					f_close(&fsrc);

					SPI_ConfigGpio(SPI3, SPI_SS, GPIO_OUTPUT);	//DB2						
					SPI_ConfigGpio(SPI3, SPI_SCK, GPIO_OUTPUT);	//DB2
					SPI_ConfigGpio(SPI3, SPI_MOSI, GPIO_OUTPUT);	//DB1
					SPI_ConfigGpio(SPI3, SPI_MISO, GPIO_OUTPUT);	//DB0
					LT268_TFT_FillColor(220,200,24,24,Blue2);
					LT268_TFT_ShowAscii(220,200,24,0,Red,Blue2,(UINT8 *)"80%");
					
					f_mount(&fs,"0:",1);
					res=f_open(&fsrc,"0:/UartTFT_Flash/UartTFT_Flash.bin",FA_OPEN_EXISTING|FA_READ);
					f_lseek(&fsrc,addr);
				}
					
				
				res=f_read(&fsrc,buf,2048,&br); 
				if(res||(br == 0)){f_close(&fsrc);break;}
				if(Flash_Type!=2)
				{					
					W25QXX_Write_NoCheck(buf,addr,br);
				}
				else
				{
					//LT_W25N01GV_Write_Page(buf,page,2048); 
					LT_W25N01GV_Write_Page(buf,page,0,2048); 
					page++;					
				}
				addr += br;       //flash 地址累加

			}
		 }		
		Set_POR_Reset();				
	}
	return 0;
}
*/


