#include"LPC214X.H"
#include "PCF8833.h"
#include"SD.H"
#define TFE 0x01
#define TNF 0x02
#define RNE 0x04
#define RFF 0x08
#define BSY 0x10
#define SD_Disable() IO0SET |= 1 << 20 //SD Chip Select Pin is P0.7
#define SD_Enable() IO0CLR |= 1 << 20
INT8U CMD[]={0x40, 0x00, 0x00, 0x00, 0x00, 0x95};
INT8U CSD_buffer[16];
INT8U CID_buffer[16];
INT8U s[8];
INT8U SPI_RW(INT8U data)
{
SSPDR = data;
while((SSPSR & 0x01) == 0);
return(SSPDR);
}
void spi_init (void)
{
INT32U i;
/* SSEL is GPIO, output set to high. */
IODIR0 |= 1<<20;
IOSET0 = 1<<20;
/* SCK1, MISO1, MOSI1 are SSP pins. */
PINSEL1 = (PINSEL1 & ~0x000003FC) | 0x000000A8;
/* Enable SPI in Master Mode, CPOL=1, CPHA=1 (Clock low-active). */
SSPCR0 = 0x00C7;
SSPCR1 = 0x0002;
SSPCPSR = 0xFE;
/* Send SPI Command with card not selected at 400 KBit. */
for (i = 0; i < 16; i++) {
SPI_RW (0xFF);
}
/* Enable SSP auto select. */
}
INT8U Write_Command_SD(INT8U *CMD)
{
INT8U i = 0, response = 1, retry = 0;
SD_Disable();
SPI_RW(0xff);
SD_Enable();
for(i = 0; i < 0x06; i++)
{
SPI_RW(*CMD++);
}
SPI_RW(0xff);
do
{
response = SPI_RW(0xff);
retry++;
}
while((response== 0xff) && (retry < 100));
return(response);
}
adr_dispose(unsigned long ADR,INT8U CMDn)
{
CMD[0]=(CMDn&0x3f)|0x40;
CMD[1]=(ADR&0XFF000000)>>24;
CMD[2]=(ADR&0X00FF0000)>>16;
CMD[3]=(ADR&0X0000FF00)>>8;
CMD[4]=(ADR&0X000000FF)>>24;
CMD[5]=0XFF;
}
INT8U SD_write_sector(INT32U Number_Sector, INT8U* Buffer)
{
INT8U response,response_1,retry;
INT16U i;
//Command 24 is a writing blocks command for SD/SD-Card.
INT8U CMD[] = {0x58, 0x00, 0x00, 0x00, 0x00, 0xFF};
INT8U CMD_SET_BLOCKLEN[]={0x50,0x00,0x00,0x02,0x00,0xFF};
retry = 0;
do
{ //Retry 100 times to send command.
response = Write_Command_SD(CMD_SET_BLOCKLEN);
if(++retry >= 100)
return(1); //block read Error!
}
while(response != 0);
SPI_RW(0XFF);
Number_Sector <<= 9; //addr = addr * 512
CMD[1] = ((Number_Sector & 0xFF000000) >> 24 );
CMD[2] = ((Number_Sector & 0x00FF0000) >> 16 );
CMD[3] = ((Number_Sector & 0x0000FF00) >> 8 );
CMD[4] = ((Number_Sector & 0x000000FF) >> 0) ;
//Send Command CMD24 to SD/SD-Card (Write 1 Block/512 Bytes)
retry = 0;
do
{ //Retry 100 times to send command.
response = Write_Command_SD(CMD);
if(++retry >= 100)
{
return(1); //send commamd Error!
}
}
while(response != 0);
// for(i = 0; i < 20; i++)
SPI_RW(0xff);
//Send Start Byte to SD/SD-Card
SPI_RW(0xfe);
//Now send real data Bolck (512Bytes) to SD/SD-Card
for(i = 0; i < 512; i++)
SPI_RW(* Buffer++); //send 512 bytes to Card
//CRC-Byte
SPI_RW(0xFF); //Dummy CRC
SPI_RW(0xFF); //CRC Code
// retry=0;
do
{
response=SPI_RW(0xFF);//Read Response
}
while(response==0xff);
do
{
response_1=SPI_RW(0xFF);
}
while(response_1!=0xFF);
SD_Disable();
SPI_RW(0xff);
if ((response&0x1f)!=0x05) return(1);
return(0);
}
INT8U SD_Read_Block(INT8U *CMD, INT8U *Buffer, INT16U Bytes)
{
INT16U i;
INT8U retry,response;
INT16U Block_Len=0;
INT8U CMD_SET_BLOCKLEN[]={0x50,0x00,0x00,0x00,0x00,0xFF};
if(Bytes != Block_Len)
{
CMD_SET_BLOCKLEN[3] = (INT8U)((Bytes & 0x0000FF00) >> 8 );
CMD_SET_BLOCKLEN[4] = (INT8U)((Bytes & 0x000000FF) >> 0 );
retry = 0;
do
{ //Retry 100 times to send command.
response = Write_Command_SD(CMD_SET_BLOCKLEN);
if(++retry >= 100)
return(1); //block read Error!
}
while(response != 0);
Block_Len = Bytes;
}
//Send reads a block Command CMD to SD/SD-Card
retry = 0;
do
{
response = Write_Command_SD(CMD);
if(++retry >= 100)
return(1); //block read Error!
}
while(response != 0);
//Read Start Byte form SD/SD-Card (FEh/Start Byte)
// while(SPI_RW(0xff) != 0xfe) ;
retry=0;
for(i=0;i<1000;i++)
{
response=SPI_RW(0xff);
retry++;
if(response==0xfe)
i=1000;
if(retry==1000)
return(1);
}
//Write blocks(normal 512Bytes) to SD/SD-Card
for(i = 0; i < Bytes; i++)
*Buffer++ = SPI_RW(0xff);
//CRC-Byte
SPI_RW(0xff);//CRC - Byte
SPI_RW(0xff);//CRC - Byte
SD_Disable();
return(0);
}
SD_INIT()
{
INT8U retry, response;
INT16U i;
for(i=0;i<250;i++)
__asm
{
NOP
}
for(i = 0; i < 0x0f; i++)
{
SPI_RW(0xff);
}
//Send Command CMD0 to SD/SD Card
retry = 0;
do
{ //retry 200 times to send CMD0 command
response = Write_Command_SD(CMD); //CMD0 响应为01
retry++;
}
while((response != 1) && (retry < 200));
retry=0;
do
{
CMD[0]=0x77;
CMD[5]=0x55;
Write_Command_SD(CMD); //CMD55 响应为01
CMD[0]=0X69;
response=Write_Command_SD(CMD); //ACMD41 响应为00
retry++;
}
while((response!=0)&&(retry<200)) ;
if(response==0)
{
PutString(20,20,"SD_INIT OK",0xf800,0xffff);
}
else
{
if(response==1)
PutString(20,20,"SD_INIT WRONG",0xf800,0xffff);
else
PutString(20,20,"SD_INIT FAIL",0xf800,0xffff);
}
return(response);
}
READ_CSD()
{
INT8U retry, response;
INT8U CMD[] = {0x49,0x00,0x00,0x00,0x00,0xFF};
retry=0;
do
{
response=SD_Read_Block(CMD,CSD_buffer,16);
retry++;
}
while((response!=0x00)&&(retry<20)) ;
if(response==0)
{
PutString(20,40,"READ_CSD OK",0xf800,0xffff);
}
else
{
if(response==1)
PutString(20,40,"READ_CSD WRONG",0xf800,0xffff);
else
PutString(20,40,"READ_CSD FAIL",0xf800,0xffff);
}
return(response);
}
SD_WRITE(INT8U* Buffer,INT32U Number_Sector)
{
INT8U retry, response;
retry=0;
do
{
response=SD_write_sector(Number_Sector,Buffer);
retry++;
}
while((response!=0x00)&&(retry<20)) ;
if(response==0)
{
PutString(20,60,"SD_WRITE OK",0xf800,0xffff);
}
else
{
if(response==1)
PutString(20,60,"SD_WRITE WRONG",0xf800,0xffff);
else
{
PutString(20,60,"SD_WRITE fail",0xf800,0xffff);
}
}
return(response);
}
SD_READ(INT8U *Buffer, INT16U Bytes,INT16U Number_Sector)
{
INT8U response,retry;
INT8U CMD[]={0X51,0X00,0X00,0X00,0X00,0XFF};
// Number_Sector=Number_Sector*Bytes;
CMD[1] = ((Number_Sector & 0xFF000000) >> 24 );
CMD[2] = ((Number_Sector & 0x00FF0000) >> 16 );
CMD[3] = ((Number_Sector & 0x0000FF00) >> 8 );
CMD[4] = ((Number_Sector & 0x000000FF) >> 0) ;
retry=0;
do
{
response=SD_Read_Block(CMD,Buffer,Bytes);
retry++;
}
while((response!=0)&&(retry<100));
/* if(response==0)
{
PutString(20,80,"SD_READ OK",0xf800,0xffff);
PutString(0,96,Buffer,0xf800,0xffff);
}
else
{
if(response==1)
PutString(20,80,"SD_READ WRONG",0xf800,0xffff);
else
PutString(20,80,"SD_READ fail",0xf800,0xffff);
}
*/ return(response);
}
BOOT_READ(INT8U *Buffer, INT16U Bytes,INT16U Number_Sector)
{
INT8U response,retry;
INT8U CMD[]={0X51,0X00,0X00,0X00,0X00,0XFF};
Number_Sector=Number_Sector<<9;
CMD[1] = ((Number_Sector & 0xFF000000) >> 24 );
CMD[2] = ((Number_Sector & 0x00FF0000) >> 16 );
CMD[3] = ((Number_Sector & 0x0000FF00) >> 8 );
CMD[4] = ((Number_Sector & 0x000000FF) >> 0) ;