📄 sd.lst
字号:
248 * Description: Send command to SD/MMC.
249 *
250 * Arguments : CmdIndex: command index value
251 * CmdBuf : pointer to command coments buffer
252 *
253 * Returns : none
254 *********************************************************************************************************
255 */
256 STATUS SdSendCmd(BYTE CmdIndex, PBYTE CmdBuf)
257 {
258 1 BYTE RespType , RespLen , CmdType;
259 1 //BYTE Status;
260 1 BYTE i;
261 1 BYTE RetryCount = 0;
262 1
263 1 RespType = SdGetRespType(CmdIndex);
264 1
265 1
266 1 if((CmdIndex == READ_BLOCK)||
267 1 (CmdIndex == READ_MUL_BLOCK)||
268 1 (CmdIndex == SEND_SCR))//11.30 DEREK.
269 1 { //SEND_EXT_CSD命令,和读数据是同一类型的命令。处理方法一样。
270 2 RespLen = 6; //见MMC4.0 spec。page42-43
271 2 CmdType = SD_CMD_RX_DATA;
272 2 }
273 1 else if((CmdIndex == WRITE_BLOCK)||
274 1 (CmdIndex == WRITE_MUL_BLOCK))
275 1 {
276 2 RespLen = 6;
277 2 CmdType = SD_CMD_TX_DATA;
278 2 }
279 1 else if((CmdIndex == CMD6)&&(SdVer2Flag)) //2007.07.02
280 1 { //V1.10,V2.00 SD的CMD6,特殊处理
281 2 RespLen = 6;
282 2 CmdType = SD_CMD_RX_DATA; //V1.10,V2.00 SD CMD6有返回数据
283 2 }
284 1 else if(RespType == TYPE_RESP_NO)
285 1 {
286 2 RespLen = 0;
287 2 CmdType = SD_CMD_ONLY;
288 2 }
289 1 else if(RespType == TYPE_RESP_R2)
290 1 {
291 2 RespLen = 17;
292 2 CmdType = SD_CMD_LONG_RSP;
293 2 }
294 1
295 1 else
296 1 {
297 2 RespLen = 6;
298 2 CmdType = SD_CMD_SHORT_RSP;
299 2 }
300 1
301 1 if (CmdIndex == 0x5)
302 1 {
C51 COMPILER V7.02b SD 03/24/2008 15:52:29 PAGE 6
303 2 RespLen = 6;
304 2 CmdType = SD_CMD_SHORT_RSP;
305 2
306 2 }
307 1
308 1 for( ; RetryCount < 5; RetryCount++)
309 1 {
310 2 SDMCMDRESBUF00 = CARD_CMD_START | CmdIndex;
311 2 for(i = 1; i <= 4; i++) //The next 4 bytes
312 2 ((BYTE xdata *)(&SDMCMDRESBUF00))[i]=CmdBuf[i];
313 2 //CRC由硬件自动发送
314 2 SDMI_CMD=CmdType;
315 2
316 2 CmdTimer = 5; // 50ms
317 2 while(CmdTimer > 0)
318 2 {
319 3 if((SDMI_INT&bmSD_COMPLETE_INT)!=0) //等待命令执行完毕
320 3 {
321 4 SDMI_INT&=~bmSD_COMPLETE_INT;
322 4 break;
323 4 }
324 3 }//*/
325 2 if(CmdTimer == 0) // Timeout
326 2 {
327 3 SdCtrlReset(); // ???
328 3 continue;
329 3 }
330 2
331 2 if(RespType == TYPE_RESP_NO)
332 2 return STATUS_SUCCESS;
333 2
334 2 if(RespType == TYPE_RESP_R3)
335 2 {
336 3 // The response type of SD_SEND_OP_COND (ACMD41) and
337 3 // SEND_OP_COND (CMD1) are both R3, which is not protected
338 3 // by CRC7. But hardware could still report CRC7 error for
339 3 // these command's response. So, to prevent from affecting
340 3 // next command, we clear CRC7-ERR INT bit here.
341 3 SDMI_ST&=~bmSD_CRC7_ERR;
342 3 for(i = 0; i < RespLen; i++)
343 3 SdRespBuf[i] = ((BYTE xdata *)(&SDMCMDRESBUF00))[i];
344 3 return STATUS_SUCCESS;
345 3 }
346 2
347 2 if(SDMI_ST&bmSD_CRC7_ERR) // CRC7 Error
348 2 {
349 3 SDMI_ST&=~bmSD_CRC7_ERR; // Clear INT
350 3 continue;
351 3 }
352 2
353 2 for(i = 0; i < RespLen; i++)
354 2 SdRespBuf[i] = ((BYTE xdata *)(&SDMCMDRESBUF00))[i];
355 2
356 2 if(RespType == TYPE_RESP_R1)
357 2 {
358 3 // Check following error bits in Card Status:
359 3 // 31 OUT_OF_RANGE SdRespBuf[1].7
360 3 // 30 ADDRESS_ERROR SdRespBuf[1].6
361 3 // 29 BLOCK_LEN_ERROR SdRespBuf[1].5
362 3 // 28 ERASE_SEQ_ERROR SdRespBuf[1].4
363 3 // 27 ERASE_PARAM SdRespBuf[1].3
364 3 // 26 WP_VIOLATION SdRespBuf[1].2
C51 COMPILER V7.02b SD 03/24/2008 15:52:29 PAGE 7
365 3 // 24 LOCK_UNLOCK_FAILED SdRespBuf[1].0
366 3 // 23 COM_CRC_ERR SdRespBuf[2].7
367 3 // 22 ILLEGAL_COMMAND SdRespBuf[2].6
368 3 // 21 CARD_ECC_FAILED SdRespBuf[2].5
369 3 // 20 CC_ERROR SdRespBuf[2].4
370 3 // 19 ERROR SdRespBuf[2].3
371 3 if( ( (SdRespBuf[1] & 0xFD) == 0 ) && // 8'b1111_1101
372 3 ( (SdRespBuf[2] & 0xB8) == 0 ) ) // 从8'b1111_1000修正到8'b1011_1000,
373 3 //某些MMC卡,例如PQI,会出现ILLEGAL_COMMAND错误,将该位屏蔽。--Derek 2007.07.27
374 3 return STATUS_SUCCESS; // No error
375 3 else
376 3 if( ( SdRespBuf[1] == 0x80 ) && //ignor OUT_OF_RANGE error--2007.01.18
377 3 ( SdRespBuf[2] == 0 ) )// && // when multi read last block
378 3 //(( SectorStart >= SdAvailableBlocks-5)&&
379 3 // ( SectorStart <= SdAvailableBlocks))) //见MMC 4.0 SPEC--4.6.3(page 49)
380 3 return STATUS_SUCCESS; //不同的卡,出错的位置不同,这里确定为最后5个block.
381 3 else //如果想一劳永逸,可以屏蔽掉这个错误位.
382 3 continue;
383 3 }
384 2 else
385 2 return STATUS_SUCCESS;
386 2 }
387 1 return STATUS_FLASH_ERROR;
388 1
389 1 }
390
391 /*
392 *********************************************************************************************************
393 * SdSendAppCmd()
394 *
395 * Description: Send App command to SD.
396 *
397 * Arguments : AppCmdIndex: App command index value
398 * CmdBuf : pointer to App command coments buffer
399 *
400 * Returns : none
401 *********************************************************************************************************
402 */
403 STATUS SdSendAppCmd(BYTE AppCmdIndex, PBYTE AppCmdBuf)
404 {
405 1 STATUS Status;
406 1 int RetryCount;
407 1 BYTE CmdBuf55[MAX_CMD_LEN]; // for APP_CMD (CMD55)
408 1
409 1 for(RetryCount = 0; RetryCount < 3; RetryCount++)
410 1 {
411 2 *((UINT32 *)(&CmdBuf55[1])) = RCA;
412 2
413 2 Status = SdSendCmd(APP_CMD, CmdBuf55);
414 2
415 2 if(Status != STATUS_SUCCESS)
416 2 {
417 3 continue;
418 3 }
419 2
420 2 Status = SdSendCmd(AppCmdIndex, AppCmdBuf);
421 2
422 2 if(Status != STATUS_SUCCESS)
423 2 continue;
424 2 else
425 2 return STATUS_SUCCESS;
426 2 }
C51 COMPILER V7.02b SD 03/24/2008 15:52:29 PAGE 8
427 1 return STATUS_FLASH_ERROR;
428 1 }
429
430 /*
431 *********************************************************************************************************
432 * SdChangeBusWidth()
433 *
434 * Description: Change SD/MMC bus width.
435 *
436 * Arguments : BYTE busWidth.
437 * For SD card,1,4 are available.
438 * For MMC 4.0 card,1,4 and 8 are available.
439 *
440 * Returns : none
441 *********************************************************************************************************
442 */
443 STATUS SdChangeBusWidth(BYTE busWidth) //busWidth只能取值1或4或8
444 {
445 1 STATUS Status=0;
446 1
447 1 if(CardType == CARD_SD)
448 1 {
449 2 if(busWidth==4)
450 2 *((INT32U *)(&SdCmdBuf[1])) = RCA | 0x02; //4bits bus width
451 2 else
452 2 *((INT32U *)(&SdCmdBuf[1])) = RCA;
453 2
454 2 Status = SdSendAppCmd(SET_BUS_WIDTH,SdCmdBuf);
455 2 if(Status == STATUS_SUCCESS)
456 2 {
457 3 if(busWidth==4)
458 3 {
459 4 SDMI_CTL&=~bmSD_BUS_8BIT_EN;
460 4 SDMI_CTL|=bmSD_BUS_4BIT_EN;
461 4 }
462 3 else
463 3 {
464 4 SDMI_CTL&=~bmSD_BUS_8BIT_EN;
465 4 SDMI_CTL&=~bmSD_BUS_4BIT_EN;
466 4 }
467 3 }
468 2 }
469 1 else // MMC
470 1 {
471 2 if(MmcProtol) // MMC 4.0 支持1/4/8 bits mode//
472 2 {
473 3 if(busWidth==8) //8 BIT
474 3 *((INT32U *)(&SdCmdBuf[1])) = 0x03b70200;
475 3 else if(busWidth==4)//4 BIT
476 3 *((INT32U *)(&SdCmdBuf[1])) = 0x03b70100;
477 3 else //1 BIT
478 3 *((INT32U *)(&SdCmdBuf[1])) = 0x03b70000;
479 3
480 3 Status = SdSendCmd(SWITCH, SdCmdBuf);
481 3
482 3 if(Status == STATUS_SUCCESS)
483 3 {
484 4 *((INT32U *)(&SdCmdBuf[1])) = RCA;
485 4 Status = SdSendCmd(SEND_STATUS, SdCmdBuf);
486 4
487 4 if(Status == STATUS_SUCCESS)
488 4 {
C51 COMPILER V7.02b SD 03/24/2008 15:52:29 PAGE 9
489 5 if(busWidth==8)
490 5 {
491 6 SDMI_CTL|=bmSD_BUS_8BIT_EN;
492 6 SDMI_CTL&=~bmSD_BUS_4BIT_EN;
493 6 }
494 5 else if((busWidth==4))
495 5 {
496 6 SDMI_CTL&=~bmSD_BUS_8BIT_EN;
497 6 SDMI_CTL|=bmSD_BUS_4BIT_EN;
498 6 }
499 5 else
500 5 {
501 6 SDMI_CTL&=~bmSD_BUS_4BIT_EN;
502 6 SDMI_CTL&=~bmSD_BUS_8BIT_EN;
503 6 }
504 5 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -