e

Dependents:   MusicShield

Files at this revision

API Documentation at this revision

Comitter:
Jackson_lv
Date:
Mon Jul 13 09:21:41 2015 +0000
Commit message:
sd

Changed in this revision

SDCard.c Show annotated file Show diff for this revision Revisions of this file
SDCard.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r 3fe14de7b0cf SDCard.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDCard.c	Mon Jul 13 09:21:41 2015 +0000
@@ -0,0 +1,359 @@
+#include "mbed.h"
+#include "mmc_sd.h"			   
+#include "spi.h"
+#include "Serial.h"	
+
+					   
+uint8_t  SD_Type=0;//SD Type
+
+//
+//data:the data to write
+//return:the data read back
+uint8_t SD_SPI_ReadWriteByte(uint8_t data)
+{
+	return SPI_ReadWriteByte(data);
+}	  
+
+//SD Card should init in low speed
+void SD_SPI_SpeedLow(void)
+{
+ 	SPI_SetSpeed(SPI_SPEED_256);//set in low speed
+}
+//SD Card work normally
+void SD_SPI_SpeedHigh(void)
+{
+ 	SPI_SetSpeed(SPI_SPEED_2);//set in high speed
+}
+//SPI hardware Init
+void SD_SPI_Init(void)
+{
+	SPI1_Init();
+	DigitalOut(SD_CS,1);
+}
+
+///////////////////////////////////////////////////////////////////////////////////
+//disable select ,release SPI BUS
+void SD_DisSelect(void)
+{
+	SD_CS=1;
+ 	SD_SPI_ReadWriteByte(0xff);//provide extra 8 clock
+}
+//select sd card,waiting card ready
+u8 SD_Select(void)
+{
+	SD_CS=0;
+	if(SD_WaitReady()==0)return 0;//waiting success
+	SD_DisSelect();
+	return 1;/waiting failed
+}
+//waiting card ready
+//return:0,ready;other,error code
+u8 SD_WaitReady(void)
+{
+	uint32_t t=0;
+	do
+	{
+		if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;//OK
+		t++;		  	
+	}while(t<0XFFFFFF);//wait
+	return 1;
+}
+//get SD card total sectors num
+//Response:0:get capacity error
+//other:SD card capacity(sectors num/512 bytes)
+//the num of byte of every sector must be 512,if ain't,the init can't pass
+uint8_t SD_GetResponse(uint8_t Response)
+{
+	u16 Count=0xFFFF;//waiting num count						  
+	while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//waiting for accurate respond
+	if (Count==0)return MSD_RESPONSE_FAILURE;//response failure
+	else return MSD_RESPONSE_NO_ERROR;//respond no error
+}
+//read a data package from SD card
+//buf:block buffer cache
+//len:length of data
+//return:0 success;other failed
+uint8_t SD_RecvData(uint8_t*buf,uint16_t len)
+{			  	  
+	if(SD_GetResponse(0xFE))return 1;//waiting SD card return start sign 0xfe
+    while(len--)//start recieve data
+    {
+        *buf=SPI_ReadWriteByte(0xFF);
+        buf++;
+    }
+    //two dummy CRC
+    SD_SPI_ReadWriteByte(0xFF);
+    SD_SPI_ReadWriteByte(0xFF);									  					    
+    return 0;//readding success
+}
+//write a data package to SD card 512 byte
+//buf:block buffer cache
+//cmd:order
+//retrun:0,success;1,failed
+uint8_t SD_SendBlock(uint8_t*buf,uint8_t cmd)
+{	
+	u16 t;		  	  
+	if(SD_WaitReady())return 1;//waiting ready failed
+	SD_SPI_ReadWriteByte(cmd);
+	if(cmd!=0XFD)//not endding order
+	{
+		for(t=0;t<512;t++)SPI2_ReadWriteByte(buf[t]);//add speed
+	    SD_SPI_ReadWriteByte(0xFF);//ignore crc
+	    SD_SPI_ReadWriteByte(0xFF);
+		t=SD_SPI_ReadWriteByte(0xFF);//receive respond
+		if((t&0x1F)!=0x05)return 2;//respond failure							  					    
+	}						 									  					    
+    return 0;//writing success
+}
+
+//write a order to sd card
+//input: u8 cmd   order
+//      u32 arg  order param
+//      u8 crc   crc  check Value  
+//return:SD card respond													  
+uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg, uint8_t crc)
+{
+    uint8_t r1;	
+	uint8_t Retry=0; 
+	SD_DisSelect();//disable last enable
+	if(SD_Select())return 0XFF;//select failed
+	//send
+    SD_SPI_ReadWriteByte(cmd | 0x40);//write order
+    SD_SPI_ReadWriteByte(arg >> 24);
+    SD_SPI_ReadWriteByte(arg >> 16);
+    SD_SPI_ReadWriteByte(arg >> 8);
+    SD_SPI_ReadWriteByte(arg);	  
+    SD_SPI_ReadWriteByte(crc); 
+	if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading
+    //wait for respond or cvertime quit
+	Retry=0X1F;
+	do
+	{
+		r1=SD_SPI_ReadWriteByte(0xFF);
+	}while((r1&0X80) && Retry--);	 
+	//return state value
+    return r1;
+}		    																			  
+//��ȡSD����CID��Ϣ��������������Ϣ
+//����: u8 *cid_data(����CID���ڴ棬����16Byte��	  
+//����ֵ:0��NO_ERR
+//		 1������														   
+uint8_t SD_GetCID(uint8_t *cid_data)
+{
+    uint8_t r1;	   
+    //��CMD10�����CID
+    r1=SD_SendCmd(CMD10,0,0x01);
+    if(r1==0x00)
+	{
+		r1=SD_RecvData(cid_data,16);//����16���ֽڵ�����	 
+    }
+	SD_DisSelect();//ȡ��Ƭѡ
+	if(r1)return 1;
+	else return 0;
+}																				  
+//��ȡSD����CSD��Ϣ�������������ٶ���Ϣ
+//����:u8 *cid_data(����CID���ڴ棬����16Byte��	    
+//����ֵ:0��NO_ERR
+//		 1������														   
+uint8_t SD_GetCSD(uint8_t *csd_data)
+{
+    uint8_t r1;	 
+    r1=SD_SendCmd(CMD9,0,0x01);//��CMD9�����CSD
+    if(r1==0)
+	{
+    	r1=SD_RecvData(csd_data, 16);//����16���ֽڵ����� 
+    }
+	SD_DisSelect();//ȡ��Ƭѡ
+	if(r1)return 1;
+	else return 0;
+}  
+//��ȡSD����������������������   
+//����ֵ:0�� ȡ�������� 
+//       ����:SD��������(������/512�ֽ�)
+//ÿ�������ֽ�����Ϊ512����Ϊ��������512������ʼ������ͨ��.														  
+uint32_t SD_GetSectorCount(void)
+{
+    uint8_t csd[16];
+    uint32_t Capacity;  
+    uint8_t n;
+	uint16_t csize;  					    
+	//ȡCSD��Ϣ�������ڼ�����������0
+    if(SD_GetCSD(csd)!=0) return 0;	    
+    //����ΪSDHC�����������淽ʽ����
+    if((csd[0]&0xC0)==0x40)	 //V2.00�Ŀ�
+    {	
+		csize = csd[9] + ((uint16_t)csd[8] << 8) + 1;
+		Capacity = (u32)csize << 10;//�õ�������	 		   
+    }else//V1.XX�Ŀ�
+    {	
+		n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
+		csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1;
+		Capacity= (uint32_t)csize << (n - 9);//�õ�������   
+    }
+    return Capacity;
+}
+//��ʼ��SD��
+uint8_t SD_Initialize(void)
+{
+    uint8_t r1;      // ����SD���ķ���ֵ
+    uint16_t retry;  // �������г�ʱ����
+    uint8_t buf[4];  
+	uint16_t i;
+
+	SD_SPI_Init();		//��ʼ��IO
+ 	SD_SPI_SpeedLow();	//���õ�����ģʽ 
+ 	for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//��������74������
+	retry=20;
+	do
+	{
+		r1=SD_SendCmd(CMD0,0,0x95);//����IDLE״̬
+	}while((r1!=0X01) && retry--);
+ 	SD_Type=0;//Ĭ���޿�
+	if(r1==0X01)
+	{
+		if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0
+		{
+			for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);	//Get trailing return value of R7 resp
+			if(buf[2]==0X01&&buf[3]==0XAA)//���Ƿ�֧��2.7~3.6V
+			{
+				retry=0XFFFE;
+				do
+				{
+					SD_SendCmd(CMD55,0,0X01);	//����CMD55
+					r1=SD_SendCmd(CMD41,0x40000000,0X01);//����CMD41
+				}while(r1&&retry--);
+				if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//����SD2.0���汾��ʼ
+				{
+					for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//�õ�OCRֵ
+					if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC;    //����CCS
+					else SD_Type=SD_TYPE_V2;   
+				}
+			}
+		}else//SD V1.x/ MMC	V3
+		{
+			SD_SendCmd(CMD55,0,0X01);		//����CMD55
+			r1=SD_SendCmd(CMD41,0,0X01);	//����CMD41
+			if(r1<=1)
+			{		
+				SD_Type=SD_TYPE_V1;
+				retry=0XFFFE;
+				do //�ȴ��˳�IDLEģʽ
+				{
+					SD_SendCmd(CMD55,0,0X01);	//����CMD55
+					r1=SD_SendCmd(CMD41,0,0X01);//����CMD41
+				}while(r1&&retry--);
+			}else//MMC����֧��CMD55+CMD41ʶ��
+			{
+				SD_Type=SD_TYPE_MMC;//MMC V3
+				retry=0XFFFE;
+				do //�ȴ��˳�IDLEģʽ
+				{											    
+					r1=SD_SendCmd(CMD1,0,0X01);//����CMD1
+				}while(r1&&retry--);  
+			}
+			if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//�����Ŀ�
+		}
+	}
+	SD_DisSelect();//ȡ��Ƭѡ
+	SD_SPI_SpeedHigh();//����
+	if(SD_Type)return 0;
+	else if(r1)return r1; 	   
+	return 0xaa;//��������
+}
+//��SD��
+//buf:���ݻ�����
+//sector:����
+//cnt:������
+//����ֵ:0,ok;����,ʧ��.
+uint8_t SD_ReadDisk(uint8_t*buf,uint32_t sector,u8 cnt)
+{
+	uint8_t r1;
+	if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//ת��Ϊ�ֽڵ�ַ
+	if(cnt==1)
+	{
+		r1=SD_SendCmd(CMD17,sector,0X01);//������
+		if(r1==0)//ָ��ͳɹ�
+		{
+			r1=SD_RecvData(buf,512);//����512���ֽ�	   
+		}
+	}else
+	{
+		r1=SD_SendCmd(CMD18,sector,0X01);//����������
+		do
+		{
+			r1=SD_RecvData(buf,512);//����512���ֽ�	 
+			buf+=512;  
+		}while(--cnt && r1==0); 	
+		SD_SendCmd(CMD12,0,0X01);	//����ֹͣ����
+	}   
+	SD_DisSelect();//ȡ��Ƭѡ
+	return r1;//
+}
+//дSD��
+//buf:���ݻ�����
+//sector:��ʼ����
+//cnt:������
+//����ֵ:0,ok;����,ʧ��.
+uint8_t SD_WriteDisk(uint8_t*buf,uint32_t sector,uint8_t cnt)
+{
+	uint8_t r1;
+	if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//ת��Ϊ�ֽڵ�ַ
+	if(cnt==1)
+	{
+		r1=SD_SendCmd(CMD24,sector,0X01);//������
+		if(r1==0)//ָ��ͳɹ�
+		{
+			r1=SD_SendBlock(buf,0xFE);//д512���ֽ�	   
+		}
+	}else
+	{
+		if(SD_Type!=SD_TYPE_MMC)
+		{
+			SD_SendCmd(CMD55,0,0X01);	
+			SD_SendCmd(CMD23,cnt,0X01);//����ָ��	
+		}
+ 		r1=SD_SendCmd(CMD25,sector,0X01);//����������
+		if(r1==0)
+		{
+			do
+			{
+				r1=SD_SendBlock(buf,0xFC);//����512���ֽ�	 
+				buf+=512;  
+			}while(--cnt && r1==0);
+			r1=SD_SendBlock(0,0xFD);//����512���ֽ� 
+		}
+	}   
+	SD_DisSelect();//ȡ��Ƭѡ
+	return r1;//
+}	   
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+	  
+
+
+
+
+
+
diff -r 000000000000 -r 3fe14de7b0cf SDCard.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDCard.h	Mon Jul 13 09:21:41 2015 +0000
@@ -0,0 +1,70 @@
+#ifndef _MMC_SD_H_
+#define _MMC_SD_H_		 
+
+#include "mbed.h"
+
+ 						    	 
+//the type of SD card
+#define SD_TYPE_ERR     0X00
+#define SD_TYPE_MMC     0X01
+#define SD_TYPE_V1      0X02
+#define SD_TYPE_V2      0X04
+#define SD_TYPE_V2HC    0X06	   
+//order of SD card    
+#define CMD0    0       //card reset
+#define CMD1    1
+#define CMD8    8       //order8,SEND_IF_COND
+#define CMD9    9       //order9,read CSD data
+#define CMD10   10      //order10,read CID data
+#define CMD12   12      //order12,stop data transfer
+#define CMD16   16      //order16,set SectorSize ,ought to return 0x00
+#define CMD17   17      //order17,read sector
+#define CMD18   18      //order18,read Multi sector
+#define CMD23   23      //order23,set multi setor erase N block before writting
+#define CMD24   24      //order24,write sector
+#define CMD25   25      //order25,write Multi sector
+#define CMD41   41      //order41,should return 0x00
+#define CMD55   55      //order55,should return 0x01
+#define CMD58   58      //order58,read information of OCR 
+#define CMD59   59      //order59,enable/disable CRC,should return 0x00
+//the meaning of return data after writing
+#define MSD_DATA_OK                0x05
+#define MSD_DATA_CRC_ERROR         0x0B
+#define MSD_DATA_WRITE_ERROR       0x0D
+#define MSD_DATA_OTHER_ERROR       0xFF
+//SD card respond sign
+#define MSD_RESPONSE_NO_ERROR      0x00
+#define MSD_IN_IDLE_STATE          0x01
+#define MSD_ERASE_RESET            0x02
+#define MSD_ILLEGAL_COMMAND        0x04
+#define MSD_COM_CRC_ERROR          0x08
+#define MSD_ERASE_SEQUENCE_ERROR   0x10
+#define MSD_ADDRESS_ERROR          0x20
+#define MSD_PARAMETER_ERROR        0x40
+#define MSD_RESPONSE_FAILURE       0xFF
+ 							   						 	 
+
+#define	SD_CS  PBout(2) //SD Card CS pin				    	  
+
+extern u8  SD_Type;//SD card type
+
+
+
+//functions
+u8 SD_SPI_ReadWriteByte(u8 data);
+void SD_SPI_SpeedLow(void);
+void SD_SPI_SpeedHigh(void);
+u8 SD_WaitReady(void);							//�ȴ�SD��׼��
+u8 SD_GetResponse(u8 Response);					//������Ӧ
+u8 SD_Initialize(void);							//��ʼ��
+u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt);		//����
+u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt);		//�
+u32 SD_GetSectorCount(void);   					//��������
+u8 SD_GetCID(u8 *cid_data);                     //��SD��CID
+u8 SD_GetCSD(u8 *csd_data);                     //��SD��CSD
+ 
+#endif
+
+
+
+