e
SDCard.c@0:3fe14de7b0cf, 2015-07-13 (annotated)
- Committer:
- Jackson_lv
- Date:
- Mon Jul 13 09:21:41 2015 +0000
- Revision:
- 0:3fe14de7b0cf
sd
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jackson_lv | 0:3fe14de7b0cf | 1 | #include "mbed.h" |
Jackson_lv | 0:3fe14de7b0cf | 2 | #include "mmc_sd.h" |
Jackson_lv | 0:3fe14de7b0cf | 3 | #include "spi.h" |
Jackson_lv | 0:3fe14de7b0cf | 4 | #include "Serial.h" |
Jackson_lv | 0:3fe14de7b0cf | 5 | |
Jackson_lv | 0:3fe14de7b0cf | 6 | |
Jackson_lv | 0:3fe14de7b0cf | 7 | uint8_t SD_Type=0;//SD Type |
Jackson_lv | 0:3fe14de7b0cf | 8 | |
Jackson_lv | 0:3fe14de7b0cf | 9 | // |
Jackson_lv | 0:3fe14de7b0cf | 10 | //data:the data to write |
Jackson_lv | 0:3fe14de7b0cf | 11 | //return:the data read back |
Jackson_lv | 0:3fe14de7b0cf | 12 | uint8_t SD_SPI_ReadWriteByte(uint8_t data) |
Jackson_lv | 0:3fe14de7b0cf | 13 | { |
Jackson_lv | 0:3fe14de7b0cf | 14 | return SPI_ReadWriteByte(data); |
Jackson_lv | 0:3fe14de7b0cf | 15 | } |
Jackson_lv | 0:3fe14de7b0cf | 16 | |
Jackson_lv | 0:3fe14de7b0cf | 17 | //SD Card should init in low speed |
Jackson_lv | 0:3fe14de7b0cf | 18 | void SD_SPI_SpeedLow(void) |
Jackson_lv | 0:3fe14de7b0cf | 19 | { |
Jackson_lv | 0:3fe14de7b0cf | 20 | SPI_SetSpeed(SPI_SPEED_256);//set in low speed |
Jackson_lv | 0:3fe14de7b0cf | 21 | } |
Jackson_lv | 0:3fe14de7b0cf | 22 | //SD Card work normally |
Jackson_lv | 0:3fe14de7b0cf | 23 | void SD_SPI_SpeedHigh(void) |
Jackson_lv | 0:3fe14de7b0cf | 24 | { |
Jackson_lv | 0:3fe14de7b0cf | 25 | SPI_SetSpeed(SPI_SPEED_2);//set in high speed |
Jackson_lv | 0:3fe14de7b0cf | 26 | } |
Jackson_lv | 0:3fe14de7b0cf | 27 | //SPI hardware Init |
Jackson_lv | 0:3fe14de7b0cf | 28 | void SD_SPI_Init(void) |
Jackson_lv | 0:3fe14de7b0cf | 29 | { |
Jackson_lv | 0:3fe14de7b0cf | 30 | SPI1_Init(); |
Jackson_lv | 0:3fe14de7b0cf | 31 | DigitalOut(SD_CS,1); |
Jackson_lv | 0:3fe14de7b0cf | 32 | } |
Jackson_lv | 0:3fe14de7b0cf | 33 | |
Jackson_lv | 0:3fe14de7b0cf | 34 | /////////////////////////////////////////////////////////////////////////////////// |
Jackson_lv | 0:3fe14de7b0cf | 35 | //disable select ,release SPI BUS |
Jackson_lv | 0:3fe14de7b0cf | 36 | void SD_DisSelect(void) |
Jackson_lv | 0:3fe14de7b0cf | 37 | { |
Jackson_lv | 0:3fe14de7b0cf | 38 | SD_CS=1; |
Jackson_lv | 0:3fe14de7b0cf | 39 | SD_SPI_ReadWriteByte(0xff);//provide extra 8 clock |
Jackson_lv | 0:3fe14de7b0cf | 40 | } |
Jackson_lv | 0:3fe14de7b0cf | 41 | //select sd card,waiting card ready |
Jackson_lv | 0:3fe14de7b0cf | 42 | u8 SD_Select(void) |
Jackson_lv | 0:3fe14de7b0cf | 43 | { |
Jackson_lv | 0:3fe14de7b0cf | 44 | SD_CS=0; |
Jackson_lv | 0:3fe14de7b0cf | 45 | if(SD_WaitReady()==0)return 0;//waiting success |
Jackson_lv | 0:3fe14de7b0cf | 46 | SD_DisSelect(); |
Jackson_lv | 0:3fe14de7b0cf | 47 | return 1;/waiting failed |
Jackson_lv | 0:3fe14de7b0cf | 48 | } |
Jackson_lv | 0:3fe14de7b0cf | 49 | //waiting card ready |
Jackson_lv | 0:3fe14de7b0cf | 50 | //return:0,ready;other,error code |
Jackson_lv | 0:3fe14de7b0cf | 51 | u8 SD_WaitReady(void) |
Jackson_lv | 0:3fe14de7b0cf | 52 | { |
Jackson_lv | 0:3fe14de7b0cf | 53 | uint32_t t=0; |
Jackson_lv | 0:3fe14de7b0cf | 54 | do |
Jackson_lv | 0:3fe14de7b0cf | 55 | { |
Jackson_lv | 0:3fe14de7b0cf | 56 | if(SD_SPI_ReadWriteByte(0XFF)==0XFF)return 0;//OK |
Jackson_lv | 0:3fe14de7b0cf | 57 | t++; |
Jackson_lv | 0:3fe14de7b0cf | 58 | }while(t<0XFFFFFF);//wait |
Jackson_lv | 0:3fe14de7b0cf | 59 | return 1; |
Jackson_lv | 0:3fe14de7b0cf | 60 | } |
Jackson_lv | 0:3fe14de7b0cf | 61 | //get SD card total sectors num |
Jackson_lv | 0:3fe14de7b0cf | 62 | //Response:0:get capacity error |
Jackson_lv | 0:3fe14de7b0cf | 63 | //other:SD card capacity(sectors num/512 bytes) |
Jackson_lv | 0:3fe14de7b0cf | 64 | //the num of byte of every sector must be 512,if ain't,the init can't pass |
Jackson_lv | 0:3fe14de7b0cf | 65 | uint8_t SD_GetResponse(uint8_t Response) |
Jackson_lv | 0:3fe14de7b0cf | 66 | { |
Jackson_lv | 0:3fe14de7b0cf | 67 | u16 Count=0xFFFF;//waiting num count |
Jackson_lv | 0:3fe14de7b0cf | 68 | while ((SD_SPI_ReadWriteByte(0XFF)!=Response)&&Count)Count--;//waiting for accurate respond |
Jackson_lv | 0:3fe14de7b0cf | 69 | if (Count==0)return MSD_RESPONSE_FAILURE;//response failure |
Jackson_lv | 0:3fe14de7b0cf | 70 | else return MSD_RESPONSE_NO_ERROR;//respond no error |
Jackson_lv | 0:3fe14de7b0cf | 71 | } |
Jackson_lv | 0:3fe14de7b0cf | 72 | //read a data package from SD card |
Jackson_lv | 0:3fe14de7b0cf | 73 | //buf:block buffer cache |
Jackson_lv | 0:3fe14de7b0cf | 74 | //len:length of data |
Jackson_lv | 0:3fe14de7b0cf | 75 | //return:0 success;other failed |
Jackson_lv | 0:3fe14de7b0cf | 76 | uint8_t SD_RecvData(uint8_t*buf,uint16_t len) |
Jackson_lv | 0:3fe14de7b0cf | 77 | { |
Jackson_lv | 0:3fe14de7b0cf | 78 | if(SD_GetResponse(0xFE))return 1;//waiting SD card return start sign 0xfe |
Jackson_lv | 0:3fe14de7b0cf | 79 | while(len--)//start recieve data |
Jackson_lv | 0:3fe14de7b0cf | 80 | { |
Jackson_lv | 0:3fe14de7b0cf | 81 | *buf=SPI_ReadWriteByte(0xFF); |
Jackson_lv | 0:3fe14de7b0cf | 82 | buf++; |
Jackson_lv | 0:3fe14de7b0cf | 83 | } |
Jackson_lv | 0:3fe14de7b0cf | 84 | //two dummy CRC |
Jackson_lv | 0:3fe14de7b0cf | 85 | SD_SPI_ReadWriteByte(0xFF); |
Jackson_lv | 0:3fe14de7b0cf | 86 | SD_SPI_ReadWriteByte(0xFF); |
Jackson_lv | 0:3fe14de7b0cf | 87 | return 0;//readding success |
Jackson_lv | 0:3fe14de7b0cf | 88 | } |
Jackson_lv | 0:3fe14de7b0cf | 89 | //write a data package to SD card 512 byte |
Jackson_lv | 0:3fe14de7b0cf | 90 | //buf:block buffer cache |
Jackson_lv | 0:3fe14de7b0cf | 91 | //cmd:order |
Jackson_lv | 0:3fe14de7b0cf | 92 | //retrun:0,success;1,failed |
Jackson_lv | 0:3fe14de7b0cf | 93 | uint8_t SD_SendBlock(uint8_t*buf,uint8_t cmd) |
Jackson_lv | 0:3fe14de7b0cf | 94 | { |
Jackson_lv | 0:3fe14de7b0cf | 95 | u16 t; |
Jackson_lv | 0:3fe14de7b0cf | 96 | if(SD_WaitReady())return 1;//waiting ready failed |
Jackson_lv | 0:3fe14de7b0cf | 97 | SD_SPI_ReadWriteByte(cmd); |
Jackson_lv | 0:3fe14de7b0cf | 98 | if(cmd!=0XFD)//not endding order |
Jackson_lv | 0:3fe14de7b0cf | 99 | { |
Jackson_lv | 0:3fe14de7b0cf | 100 | for(t=0;t<512;t++)SPI2_ReadWriteByte(buf[t]);//add speed |
Jackson_lv | 0:3fe14de7b0cf | 101 | SD_SPI_ReadWriteByte(0xFF);//ignore crc |
Jackson_lv | 0:3fe14de7b0cf | 102 | SD_SPI_ReadWriteByte(0xFF); |
Jackson_lv | 0:3fe14de7b0cf | 103 | t=SD_SPI_ReadWriteByte(0xFF);//receive respond |
Jackson_lv | 0:3fe14de7b0cf | 104 | if((t&0x1F)!=0x05)return 2;//respond failure |
Jackson_lv | 0:3fe14de7b0cf | 105 | } |
Jackson_lv | 0:3fe14de7b0cf | 106 | return 0;//writing success |
Jackson_lv | 0:3fe14de7b0cf | 107 | } |
Jackson_lv | 0:3fe14de7b0cf | 108 | |
Jackson_lv | 0:3fe14de7b0cf | 109 | //write a order to sd card |
Jackson_lv | 0:3fe14de7b0cf | 110 | //input: u8 cmd order |
Jackson_lv | 0:3fe14de7b0cf | 111 | // u32 arg order param |
Jackson_lv | 0:3fe14de7b0cf | 112 | // u8 crc crc check Value |
Jackson_lv | 0:3fe14de7b0cf | 113 | //return:SD card respond |
Jackson_lv | 0:3fe14de7b0cf | 114 | uint8_t SD_SendCmd(uint8_t cmd, uint32_t arg, uint8_t crc) |
Jackson_lv | 0:3fe14de7b0cf | 115 | { |
Jackson_lv | 0:3fe14de7b0cf | 116 | uint8_t r1; |
Jackson_lv | 0:3fe14de7b0cf | 117 | uint8_t Retry=0; |
Jackson_lv | 0:3fe14de7b0cf | 118 | SD_DisSelect();//disable last enable |
Jackson_lv | 0:3fe14de7b0cf | 119 | if(SD_Select())return 0XFF;//select failed |
Jackson_lv | 0:3fe14de7b0cf | 120 | //send |
Jackson_lv | 0:3fe14de7b0cf | 121 | SD_SPI_ReadWriteByte(cmd | 0x40);//write order |
Jackson_lv | 0:3fe14de7b0cf | 122 | SD_SPI_ReadWriteByte(arg >> 24); |
Jackson_lv | 0:3fe14de7b0cf | 123 | SD_SPI_ReadWriteByte(arg >> 16); |
Jackson_lv | 0:3fe14de7b0cf | 124 | SD_SPI_ReadWriteByte(arg >> 8); |
Jackson_lv | 0:3fe14de7b0cf | 125 | SD_SPI_ReadWriteByte(arg); |
Jackson_lv | 0:3fe14de7b0cf | 126 | SD_SPI_ReadWriteByte(crc); |
Jackson_lv | 0:3fe14de7b0cf | 127 | if(cmd==CMD12)SD_SPI_ReadWriteByte(0xff);//Skip a stuff byte when stop reading |
Jackson_lv | 0:3fe14de7b0cf | 128 | //wait for respond or cvertime quit |
Jackson_lv | 0:3fe14de7b0cf | 129 | Retry=0X1F; |
Jackson_lv | 0:3fe14de7b0cf | 130 | do |
Jackson_lv | 0:3fe14de7b0cf | 131 | { |
Jackson_lv | 0:3fe14de7b0cf | 132 | r1=SD_SPI_ReadWriteByte(0xFF); |
Jackson_lv | 0:3fe14de7b0cf | 133 | }while((r1&0X80) && Retry--); |
Jackson_lv | 0:3fe14de7b0cf | 134 | //return state value |
Jackson_lv | 0:3fe14de7b0cf | 135 | return r1; |
Jackson_lv | 0:3fe14de7b0cf | 136 | } |
Jackson_lv | 0:3fe14de7b0cf | 137 | //��ȡSD����CID��Ϣ��������������Ϣ |
Jackson_lv | 0:3fe14de7b0cf | 138 | //����: u8 *cid_data(����CID���ڴ棬����16Byte�� |
Jackson_lv | 0:3fe14de7b0cf | 139 | //����ֵ:0��NO_ERR |
Jackson_lv | 0:3fe14de7b0cf | 140 | // 1������ |
Jackson_lv | 0:3fe14de7b0cf | 141 | uint8_t SD_GetCID(uint8_t *cid_data) |
Jackson_lv | 0:3fe14de7b0cf | 142 | { |
Jackson_lv | 0:3fe14de7b0cf | 143 | uint8_t r1; |
Jackson_lv | 0:3fe14de7b0cf | 144 | //��CMD10�����CID |
Jackson_lv | 0:3fe14de7b0cf | 145 | r1=SD_SendCmd(CMD10,0,0x01); |
Jackson_lv | 0:3fe14de7b0cf | 146 | if(r1==0x00) |
Jackson_lv | 0:3fe14de7b0cf | 147 | { |
Jackson_lv | 0:3fe14de7b0cf | 148 | r1=SD_RecvData(cid_data,16);//����16���ֽڵ����� |
Jackson_lv | 0:3fe14de7b0cf | 149 | } |
Jackson_lv | 0:3fe14de7b0cf | 150 | SD_DisSelect();//ȡ��Ƭѡ |
Jackson_lv | 0:3fe14de7b0cf | 151 | if(r1)return 1; |
Jackson_lv | 0:3fe14de7b0cf | 152 | else return 0; |
Jackson_lv | 0:3fe14de7b0cf | 153 | } |
Jackson_lv | 0:3fe14de7b0cf | 154 | //��ȡSD����CSD��Ϣ�������������ٶ���Ϣ |
Jackson_lv | 0:3fe14de7b0cf | 155 | //����:u8 *cid_data(����CID���ڴ棬����16Byte�� |
Jackson_lv | 0:3fe14de7b0cf | 156 | //����ֵ:0��NO_ERR |
Jackson_lv | 0:3fe14de7b0cf | 157 | // 1������ |
Jackson_lv | 0:3fe14de7b0cf | 158 | uint8_t SD_GetCSD(uint8_t *csd_data) |
Jackson_lv | 0:3fe14de7b0cf | 159 | { |
Jackson_lv | 0:3fe14de7b0cf | 160 | uint8_t r1; |
Jackson_lv | 0:3fe14de7b0cf | 161 | r1=SD_SendCmd(CMD9,0,0x01);//��CMD9�����CSD |
Jackson_lv | 0:3fe14de7b0cf | 162 | if(r1==0) |
Jackson_lv | 0:3fe14de7b0cf | 163 | { |
Jackson_lv | 0:3fe14de7b0cf | 164 | r1=SD_RecvData(csd_data, 16);//����16���ֽڵ����� |
Jackson_lv | 0:3fe14de7b0cf | 165 | } |
Jackson_lv | 0:3fe14de7b0cf | 166 | SD_DisSelect();//ȡ��Ƭѡ |
Jackson_lv | 0:3fe14de7b0cf | 167 | if(r1)return 1; |
Jackson_lv | 0:3fe14de7b0cf | 168 | else return 0; |
Jackson_lv | 0:3fe14de7b0cf | 169 | } |
Jackson_lv | 0:3fe14de7b0cf | 170 | //��ȡSD���������������������� |
Jackson_lv | 0:3fe14de7b0cf | 171 | //����ֵ:0�� ȡ�������� |
Jackson_lv | 0:3fe14de7b0cf | 172 | // ����:SD��������(������/512�ֽ�) |
Jackson_lv | 0:3fe14de7b0cf | 173 | //ÿ�������ֽ�����Ϊ512����Ϊ��������512������ʼ������ͨ��. |
Jackson_lv | 0:3fe14de7b0cf | 174 | uint32_t SD_GetSectorCount(void) |
Jackson_lv | 0:3fe14de7b0cf | 175 | { |
Jackson_lv | 0:3fe14de7b0cf | 176 | uint8_t csd[16]; |
Jackson_lv | 0:3fe14de7b0cf | 177 | uint32_t Capacity; |
Jackson_lv | 0:3fe14de7b0cf | 178 | uint8_t n; |
Jackson_lv | 0:3fe14de7b0cf | 179 | uint16_t csize; |
Jackson_lv | 0:3fe14de7b0cf | 180 | //ȡCSD��Ϣ�������ڼ�����������0 |
Jackson_lv | 0:3fe14de7b0cf | 181 | if(SD_GetCSD(csd)!=0) return 0; |
Jackson_lv | 0:3fe14de7b0cf | 182 | //����ΪSDHC�����������淽ʽ���� |
Jackson_lv | 0:3fe14de7b0cf | 183 | if((csd[0]&0xC0)==0x40) //V2.00�Ŀ� |
Jackson_lv | 0:3fe14de7b0cf | 184 | { |
Jackson_lv | 0:3fe14de7b0cf | 185 | csize = csd[9] + ((uint16_t)csd[8] << 8) + 1; |
Jackson_lv | 0:3fe14de7b0cf | 186 | Capacity = (u32)csize << 10;//�õ������� |
Jackson_lv | 0:3fe14de7b0cf | 187 | }else//V1.XX�Ŀ� |
Jackson_lv | 0:3fe14de7b0cf | 188 | { |
Jackson_lv | 0:3fe14de7b0cf | 189 | n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2; |
Jackson_lv | 0:3fe14de7b0cf | 190 | csize = (csd[8] >> 6) + ((uint16_t)csd[7] << 2) + ((uint16_t)(csd[6] & 3) << 10) + 1; |
Jackson_lv | 0:3fe14de7b0cf | 191 | Capacity= (uint32_t)csize << (n - 9);//�õ������� |
Jackson_lv | 0:3fe14de7b0cf | 192 | } |
Jackson_lv | 0:3fe14de7b0cf | 193 | return Capacity; |
Jackson_lv | 0:3fe14de7b0cf | 194 | } |
Jackson_lv | 0:3fe14de7b0cf | 195 | //��ʼ��SD�� |
Jackson_lv | 0:3fe14de7b0cf | 196 | uint8_t SD_Initialize(void) |
Jackson_lv | 0:3fe14de7b0cf | 197 | { |
Jackson_lv | 0:3fe14de7b0cf | 198 | uint8_t r1; // ����SD���ķ���ֵ |
Jackson_lv | 0:3fe14de7b0cf | 199 | uint16_t retry; // �������г�ʱ���� |
Jackson_lv | 0:3fe14de7b0cf | 200 | uint8_t buf[4]; |
Jackson_lv | 0:3fe14de7b0cf | 201 | uint16_t i; |
Jackson_lv | 0:3fe14de7b0cf | 202 | |
Jackson_lv | 0:3fe14de7b0cf | 203 | SD_SPI_Init(); //��ʼ��IO |
Jackson_lv | 0:3fe14de7b0cf | 204 | SD_SPI_SpeedLow(); //���õ�����ģʽ |
Jackson_lv | 0:3fe14de7b0cf | 205 | for(i=0;i<10;i++)SD_SPI_ReadWriteByte(0XFF);//��������74������ |
Jackson_lv | 0:3fe14de7b0cf | 206 | retry=20; |
Jackson_lv | 0:3fe14de7b0cf | 207 | do |
Jackson_lv | 0:3fe14de7b0cf | 208 | { |
Jackson_lv | 0:3fe14de7b0cf | 209 | r1=SD_SendCmd(CMD0,0,0x95);//����IDLE״̬ |
Jackson_lv | 0:3fe14de7b0cf | 210 | }while((r1!=0X01) && retry--); |
Jackson_lv | 0:3fe14de7b0cf | 211 | SD_Type=0;//Ĭ���� |
Jackson_lv | 0:3fe14de7b0cf | 212 | if(r1==0X01) |
Jackson_lv | 0:3fe14de7b0cf | 213 | { |
Jackson_lv | 0:3fe14de7b0cf | 214 | if(SD_SendCmd(CMD8,0x1AA,0x87)==1)//SD V2.0 |
Jackson_lv | 0:3fe14de7b0cf | 215 | { |
Jackson_lv | 0:3fe14de7b0cf | 216 | for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF); //Get trailing return value of R7 resp |
Jackson_lv | 0:3fe14de7b0cf | 217 | if(buf[2]==0X01&&buf[3]==0XAA)//���Ƿ�֧��2.7~3.6V |
Jackson_lv | 0:3fe14de7b0cf | 218 | { |
Jackson_lv | 0:3fe14de7b0cf | 219 | retry=0XFFFE; |
Jackson_lv | 0:3fe14de7b0cf | 220 | do |
Jackson_lv | 0:3fe14de7b0cf | 221 | { |
Jackson_lv | 0:3fe14de7b0cf | 222 | SD_SendCmd(CMD55,0,0X01); //����CMD55 |
Jackson_lv | 0:3fe14de7b0cf | 223 | r1=SD_SendCmd(CMD41,0x40000000,0X01);//����CMD41 |
Jackson_lv | 0:3fe14de7b0cf | 224 | }while(r1&&retry--); |
Jackson_lv | 0:3fe14de7b0cf | 225 | if(retry&&SD_SendCmd(CMD58,0,0X01)==0)//����SD2.0���汾��ʼ |
Jackson_lv | 0:3fe14de7b0cf | 226 | { |
Jackson_lv | 0:3fe14de7b0cf | 227 | for(i=0;i<4;i++)buf[i]=SD_SPI_ReadWriteByte(0XFF);//�õ�OCRֵ |
Jackson_lv | 0:3fe14de7b0cf | 228 | if(buf[0]&0x40)SD_Type=SD_TYPE_V2HC; //����CCS |
Jackson_lv | 0:3fe14de7b0cf | 229 | else SD_Type=SD_TYPE_V2; |
Jackson_lv | 0:3fe14de7b0cf | 230 | } |
Jackson_lv | 0:3fe14de7b0cf | 231 | } |
Jackson_lv | 0:3fe14de7b0cf | 232 | }else//SD V1.x/ MMC V3 |
Jackson_lv | 0:3fe14de7b0cf | 233 | { |
Jackson_lv | 0:3fe14de7b0cf | 234 | SD_SendCmd(CMD55,0,0X01); //����CMD55 |
Jackson_lv | 0:3fe14de7b0cf | 235 | r1=SD_SendCmd(CMD41,0,0X01); //����CMD41 |
Jackson_lv | 0:3fe14de7b0cf | 236 | if(r1<=1) |
Jackson_lv | 0:3fe14de7b0cf | 237 | { |
Jackson_lv | 0:3fe14de7b0cf | 238 | SD_Type=SD_TYPE_V1; |
Jackson_lv | 0:3fe14de7b0cf | 239 | retry=0XFFFE; |
Jackson_lv | 0:3fe14de7b0cf | 240 | do //�ȴ��˳�IDLEģʽ |
Jackson_lv | 0:3fe14de7b0cf | 241 | { |
Jackson_lv | 0:3fe14de7b0cf | 242 | SD_SendCmd(CMD55,0,0X01); //����CMD55 |
Jackson_lv | 0:3fe14de7b0cf | 243 | r1=SD_SendCmd(CMD41,0,0X01);//����CMD41 |
Jackson_lv | 0:3fe14de7b0cf | 244 | }while(r1&&retry--); |
Jackson_lv | 0:3fe14de7b0cf | 245 | }else//MMC����֧��CMD55+CMD41ʶ�� |
Jackson_lv | 0:3fe14de7b0cf | 246 | { |
Jackson_lv | 0:3fe14de7b0cf | 247 | SD_Type=SD_TYPE_MMC;//MMC V3 |
Jackson_lv | 0:3fe14de7b0cf | 248 | retry=0XFFFE; |
Jackson_lv | 0:3fe14de7b0cf | 249 | do //�ȴ��˳�IDLEģʽ |
Jackson_lv | 0:3fe14de7b0cf | 250 | { |
Jackson_lv | 0:3fe14de7b0cf | 251 | r1=SD_SendCmd(CMD1,0,0X01);//����CMD1 |
Jackson_lv | 0:3fe14de7b0cf | 252 | }while(r1&&retry--); |
Jackson_lv | 0:3fe14de7b0cf | 253 | } |
Jackson_lv | 0:3fe14de7b0cf | 254 | if(retry==0||SD_SendCmd(CMD16,512,0X01)!=0)SD_Type=SD_TYPE_ERR;//�����Ŀ� |
Jackson_lv | 0:3fe14de7b0cf | 255 | } |
Jackson_lv | 0:3fe14de7b0cf | 256 | } |
Jackson_lv | 0:3fe14de7b0cf | 257 | SD_DisSelect();//ȡ��Ƭѡ |
Jackson_lv | 0:3fe14de7b0cf | 258 | SD_SPI_SpeedHigh();//���� |
Jackson_lv | 0:3fe14de7b0cf | 259 | if(SD_Type)return 0; |
Jackson_lv | 0:3fe14de7b0cf | 260 | else if(r1)return r1; |
Jackson_lv | 0:3fe14de7b0cf | 261 | return 0xaa;//�������� |
Jackson_lv | 0:3fe14de7b0cf | 262 | } |
Jackson_lv | 0:3fe14de7b0cf | 263 | //��SD�� |
Jackson_lv | 0:3fe14de7b0cf | 264 | //buf:���ݻ����� |
Jackson_lv | 0:3fe14de7b0cf | 265 | //sector:���� |
Jackson_lv | 0:3fe14de7b0cf | 266 | //cnt:������ |
Jackson_lv | 0:3fe14de7b0cf | 267 | //����ֵ:0,ok;����,ʧ��. |
Jackson_lv | 0:3fe14de7b0cf | 268 | uint8_t SD_ReadDisk(uint8_t*buf,uint32_t sector,u8 cnt) |
Jackson_lv | 0:3fe14de7b0cf | 269 | { |
Jackson_lv | 0:3fe14de7b0cf | 270 | uint8_t r1; |
Jackson_lv | 0:3fe14de7b0cf | 271 | if(SD_Type!=SD_TYPE_V2HC)sector <<= 9;//ת��Ϊ�ֽڵ�ַ |
Jackson_lv | 0:3fe14de7b0cf | 272 | if(cnt==1) |
Jackson_lv | 0:3fe14de7b0cf | 273 | { |
Jackson_lv | 0:3fe14de7b0cf | 274 | r1=SD_SendCmd(CMD17,sector,0X01);//������ |
Jackson_lv | 0:3fe14de7b0cf | 275 | if(r1==0)//ָ��ͳɹ� |
Jackson_lv | 0:3fe14de7b0cf | 276 | { |
Jackson_lv | 0:3fe14de7b0cf | 277 | r1=SD_RecvData(buf,512);//����512���ֽ� |
Jackson_lv | 0:3fe14de7b0cf | 278 | } |
Jackson_lv | 0:3fe14de7b0cf | 279 | }else |
Jackson_lv | 0:3fe14de7b0cf | 280 | { |
Jackson_lv | 0:3fe14de7b0cf | 281 | r1=SD_SendCmd(CMD18,sector,0X01);//���������� |
Jackson_lv | 0:3fe14de7b0cf | 282 | do |
Jackson_lv | 0:3fe14de7b0cf | 283 | { |
Jackson_lv | 0:3fe14de7b0cf | 284 | r1=SD_RecvData(buf,512);//����512���ֽ� |
Jackson_lv | 0:3fe14de7b0cf | 285 | buf+=512; |
Jackson_lv | 0:3fe14de7b0cf | 286 | }while(--cnt && r1==0); |
Jackson_lv | 0:3fe14de7b0cf | 287 | SD_SendCmd(CMD12,0,0X01); //����ֹͣ���� |
Jackson_lv | 0:3fe14de7b0cf | 288 | } |
Jackson_lv | 0:3fe14de7b0cf | 289 | SD_DisSelect();//ȡ��Ƭѡ |
Jackson_lv | 0:3fe14de7b0cf | 290 | return r1;// |
Jackson_lv | 0:3fe14de7b0cf | 291 | } |
Jackson_lv | 0:3fe14de7b0cf | 292 | //дSD�� |
Jackson_lv | 0:3fe14de7b0cf | 293 | //buf:���ݻ����� |
Jackson_lv | 0:3fe14de7b0cf | 294 | //sector:��ʼ���� |
Jackson_lv | 0:3fe14de7b0cf | 295 | //cnt:������ |
Jackson_lv | 0:3fe14de7b0cf | 296 | //����ֵ:0,ok;����,ʧ��. |
Jackson_lv | 0:3fe14de7b0cf | 297 | uint8_t SD_WriteDisk(uint8_t*buf,uint32_t sector,uint8_t cnt) |
Jackson_lv | 0:3fe14de7b0cf | 298 | { |
Jackson_lv | 0:3fe14de7b0cf | 299 | uint8_t r1; |
Jackson_lv | 0:3fe14de7b0cf | 300 | if(SD_Type!=SD_TYPE_V2HC)sector *= 512;//ת��Ϊ�ֽڵ�ַ |
Jackson_lv | 0:3fe14de7b0cf | 301 | if(cnt==1) |
Jackson_lv | 0:3fe14de7b0cf | 302 | { |
Jackson_lv | 0:3fe14de7b0cf | 303 | r1=SD_SendCmd(CMD24,sector,0X01);//������ |
Jackson_lv | 0:3fe14de7b0cf | 304 | if(r1==0)//ָ��ͳɹ� |
Jackson_lv | 0:3fe14de7b0cf | 305 | { |
Jackson_lv | 0:3fe14de7b0cf | 306 | r1=SD_SendBlock(buf,0xFE);//д512���ֽ� |
Jackson_lv | 0:3fe14de7b0cf | 307 | } |
Jackson_lv | 0:3fe14de7b0cf | 308 | }else |
Jackson_lv | 0:3fe14de7b0cf | 309 | { |
Jackson_lv | 0:3fe14de7b0cf | 310 | if(SD_Type!=SD_TYPE_MMC) |
Jackson_lv | 0:3fe14de7b0cf | 311 | { |
Jackson_lv | 0:3fe14de7b0cf | 312 | SD_SendCmd(CMD55,0,0X01); |
Jackson_lv | 0:3fe14de7b0cf | 313 | SD_SendCmd(CMD23,cnt,0X01);//����ָ�� |
Jackson_lv | 0:3fe14de7b0cf | 314 | } |
Jackson_lv | 0:3fe14de7b0cf | 315 | r1=SD_SendCmd(CMD25,sector,0X01);//���������� |
Jackson_lv | 0:3fe14de7b0cf | 316 | if(r1==0) |
Jackson_lv | 0:3fe14de7b0cf | 317 | { |
Jackson_lv | 0:3fe14de7b0cf | 318 | do |
Jackson_lv | 0:3fe14de7b0cf | 319 | { |
Jackson_lv | 0:3fe14de7b0cf | 320 | r1=SD_SendBlock(buf,0xFC);//����512���ֽ� |
Jackson_lv | 0:3fe14de7b0cf | 321 | buf+=512; |
Jackson_lv | 0:3fe14de7b0cf | 322 | }while(--cnt && r1==0); |
Jackson_lv | 0:3fe14de7b0cf | 323 | r1=SD_SendBlock(0,0xFD);//����512���ֽ� |
Jackson_lv | 0:3fe14de7b0cf | 324 | } |
Jackson_lv | 0:3fe14de7b0cf | 325 | } |
Jackson_lv | 0:3fe14de7b0cf | 326 | SD_DisSelect();//ȡ��Ƭѡ |
Jackson_lv | 0:3fe14de7b0cf | 327 | return r1;// |
Jackson_lv | 0:3fe14de7b0cf | 328 | } |
Jackson_lv | 0:3fe14de7b0cf | 329 | |
Jackson_lv | 0:3fe14de7b0cf | 330 | |
Jackson_lv | 0:3fe14de7b0cf | 331 | |
Jackson_lv | 0:3fe14de7b0cf | 332 | |
Jackson_lv | 0:3fe14de7b0cf | 333 | |
Jackson_lv | 0:3fe14de7b0cf | 334 | |
Jackson_lv | 0:3fe14de7b0cf | 335 | |
Jackson_lv | 0:3fe14de7b0cf | 336 | |
Jackson_lv | 0:3fe14de7b0cf | 337 | |
Jackson_lv | 0:3fe14de7b0cf | 338 | |
Jackson_lv | 0:3fe14de7b0cf | 339 | |
Jackson_lv | 0:3fe14de7b0cf | 340 | |
Jackson_lv | 0:3fe14de7b0cf | 341 | |
Jackson_lv | 0:3fe14de7b0cf | 342 | |
Jackson_lv | 0:3fe14de7b0cf | 343 | |
Jackson_lv | 0:3fe14de7b0cf | 344 | |
Jackson_lv | 0:3fe14de7b0cf | 345 | |
Jackson_lv | 0:3fe14de7b0cf | 346 | |
Jackson_lv | 0:3fe14de7b0cf | 347 | |
Jackson_lv | 0:3fe14de7b0cf | 348 | |
Jackson_lv | 0:3fe14de7b0cf | 349 | |
Jackson_lv | 0:3fe14de7b0cf | 350 | |
Jackson_lv | 0:3fe14de7b0cf | 351 | |
Jackson_lv | 0:3fe14de7b0cf | 352 | |
Jackson_lv | 0:3fe14de7b0cf | 353 | |
Jackson_lv | 0:3fe14de7b0cf | 354 | |
Jackson_lv | 0:3fe14de7b0cf | 355 | |
Jackson_lv | 0:3fe14de7b0cf | 356 | |
Jackson_lv | 0:3fe14de7b0cf | 357 | |
Jackson_lv | 0:3fe14de7b0cf | 358 | |
Jackson_lv | 0:3fe14de7b0cf | 359 |