/******************************************************************************* * Function Name : MSD_Init * Description : SD Card initializtion * Input : None * Output : None * Return : None * Attention : None *******************************************************************************/ int MSD_Init(void) { uint8_t r1; uint8_t buff[6] = {0}; uint16_t retry; uint16_t retry_time = 5; // uint32 lu32SDStatus = 0; // uint8 err; gu8SDStatus = 0; /* Check , if no card insert */ //if( _card_insert() ) //{ /* FATFS error flag */ //return -1; //} /* Power on and delay some times */ for(retry = 0; retry < 0x100; retry++) { _card_power_on(); } /* Satrt send 74 clocks at least */ for(retry = 0; retry < 10; retry++) { _spi_read_write(DUMMY_BYTE); } /* Start send CMD0 till return 0x01 means in IDLE state */ /*begin:yangfei modified 2013-09-28 for SD卡重试次数太多,等待时间太长,SD卡正常的时候只需1次就能成功*/ #if 0 for(retry = 0; retry < 0xFFF; retry++) #else for(retry = 0; retry < retry_time; retry++) #endif { r1 = _send_command(CMD0, 0, 0x95); if(r1 == 0x01) { retry = 0; break; } } /* Timeout return */ #if 0 if(retry == 0xFFF) #else if(retry == retry_time) #endif { gu8SDStatus = 1; return 1; } /*end:yangfei modified 2013-09-28 for SD卡重试次数太多,等待时间太长,SD卡正常的时候只需1次就能成功*/ /* Get the card type, version */ r1 = _send_command_hold(CMD8, 0x1AA, 0x87); /* r1=0x05 -> V1.0 */ if(r1 == 0x05) { CardInfo.CardType = CARDTYPE_SDV1; /* End of CMD8, chip disable and dummy byte */ _card_disable(); _spi_read_write(DUMMY_BYTE); /* SD1.0/MMC start initialize */ /* Send CMD55+ACMD41, No-response is a MMC card, otherwise is a SD1.0 card */ for(retry = 0; retry < 0xFFF; retry++) { r1 = _send_command(CMD55, 0, 0); /* should be return 0x01 */ if(r1 != 0x01) { return r1; } r1 = _send_command(ACMD41, 0, 0); /* should be return 0x00 */ if(r1 == 0x00) { retry = 0; break; } } /* MMC card initialize start */ if(retry == 0xFFF) { for(retry = 0; retry < 0xFFF; retry++) { r1 = _send_command(CMD1, 0, 0); /* should be return 0x00 */ if(r1 == 0x00) { retry = 0; break; } } /* Timeout return */ if(retry == 0xFFF) { gu8SDStatus = 2; return 2; } CardInfo.CardType = CARDTYPE_MMC; } /* Set spi speed high */ MSD_SPIHighSpeed(1); /* CRC disable */ r1 = _send_command(CMD59, 0, 0x01); if(r1 != 0x00) { return r1; /* response error, return r1 */ } /* Set the block size */ r1 = _send_command(CMD16, MSD_BLOCKSIZE, 0xFF); if(r1 != 0x00) { return r1; /* response error, return r1 */ } } /* r1=0x01 -> V2.x, read OCR register, check version */ else if(r1 == 0x01) { /* 4Bytes returned after CMD8 sent */ buff[0] = _spi_read_write(DUMMY_BYTE); /* should be 0x00 */ buff[1] = _spi_read_write(DUMMY_BYTE); /* should be 0x00 */ buff[2] = _spi_read_write(DUMMY_BYTE); /* should be 0x01 */ buff[3] = _spi_read_write(DUMMY_BYTE); /* should be 0xAA */ /* End of CMD8, chip disable and dummy byte */ _card_disable(); _spi_read_write(DUMMY_BYTE); /* Check voltage range be 2.7-3.6V */ if(buff[2] == 0x01 && buff[3] == 0xAA) { for(retry = 0; retry < 0xFFF; retry++) { r1 = _send_command(CMD55, 0, 0); /* should be return 0x01 */ if(r1 != 0x01) { return r1; } r1 = _send_command(ACMD41, 0x40000000, 0); /* should be return 0x00 */ if(r1 == 0x00) { retry = 0; break; } } /* Timeout return */ if(retry == 0xFFF) { gu8SDStatus = 3; return 3; } /* Read OCR by CMD58 */ r1 = _send_command_hold(CMD58, 0, 0); if(r1 != 0x00) { return r1; /* response error, return r1 */ } buff[0] = _spi_read_write(DUMMY_BYTE); buff[1] = _spi_read_write(DUMMY_BYTE); buff[2] = _spi_read_write(DUMMY_BYTE); buff[3] = _spi_read_write(DUMMY_BYTE); /* End of CMD58, chip disable and dummy byte */ _card_disable(); _spi_read_write(DUMMY_BYTE); /* OCR -> CCS(bit30) 1: SDV2HC 0: SDV2 */ if(buff[0] & 0x40) { CardInfo.CardType = CARDTYPE_SDV2HC; } else { CardInfo.CardType = CARDTYPE_SDV2; } /* Set spi speed high */ MSD_SPIHighSpeed(1); } } return 0; }
/******************************************************************************* * Function Name : MSD_Init * Description : SD Card initializtion * Input : None * Output : None * Return : None * Attention : None *******************************************************************************/ int MSD_Init(void) { uint8_t r1; uint8_t buff[6] = {0}; uint16_t retry; /* Check , if no card insert if( _card_insert() ) { #ifdef PRINT_INFO printf("There is no card detected! \r\n"); #endif // FATFS error flag return -1; }*/ /* Power on and delay some times */ for(retry=0; retry<0x100; retry++) { _card_power_on(); } /* Satrt send 74 clocks at least */ for(retry=0; retry<10; retry++) { _spi_read_write(DUMMY_BYTE); } /* Start send CMD0 till return 0x01 means in IDLE state */ for(retry=0; retry<0xFFF; retry++) { r1 = _send_command(CMD0, 0, 0x95); if(r1 == 0x01) { retry = 0; break; } } /* Timeout return */ if(retry == 0xFFF) { #ifdef PRINT_INFO printf("Reset card into IDLE state failed!\r\n"); #endif return 1; } /* Get the card type, version */ r1 = _send_command_hold(CMD8, 0x1AA, 0x87); /* r1=0x05 -> V1.0 */ if(r1 == 0x05) { CardInfo.CardType = CARDTYPE_SDV1; /* End of CMD8, chip disable and dummy byte */ _card_disable(); _spi_read_write(DUMMY_BYTE); /* SD1.0/MMC start initialize */ /* Send CMD55+ACMD41, No-response is a MMC card, otherwise is a SD1.0 card */ for(retry=0; retry<0xFFF; retry++) { r1 = _send_command(CMD55, 0, 0); /* should be return 0x01 */ if(r1 != 0x01) { #ifdef PRINT_INFO printf("Send CMD55 should return 0x01, response=0x%02x\r\n", r1); #endif return r1; } r1 = _send_command(ACMD41, 0, 0); /* should be return 0x00 */ if(r1 == 0x00) { retry = 0; break; } } /* MMC card initialize start */ if(retry == 0xFFF) { for(retry=0; retry<0xFFF; retry++) { r1 = _send_command(CMD1, 0, 0); /* should be return 0x00 */ if(r1 == 0x00) { retry = 0; break; } } /* Timeout return */ if(retry == 0xFFF) { #ifdef PRINT_INFO printf("Send CMD1 should return 0x00, response=0x%02x\r\n", r1); #endif return 2; } CardInfo.CardType = CARDTYPE_MMC; #ifdef PRINT_INFO printf("Card Type : MMC\r\n"); #endif } /* SD1.0 card detected, print information */ #ifdef PRINT_INFO else { printf("Card Type : SD V1\r\n"); } #endif /* Set spi speed high */ MSD_SPIHighSpeed(1); /* CRC disable */ r1 = _send_command(CMD59, 0, 0x01); if(r1 != 0x00) { #ifdef PRINT_INFO printf("Send CMD59 should return 0x00, response=0x%02x\r\n", r1); #endif return r1; /* response error, return r1 */ } /* Set the block size */ r1 = _send_command(CMD16, MSD_BLOCKSIZE, 0xFF); if(r1 != 0x00) { #ifdef PRINT_INFO printf("Send CMD16 should return 0x00, response=0x%02x\r\n", r1); #endif return r1; /* response error, return r1 */ } /* r1=0x01 -> V2.x, read OCR register, check version */ } else if(r1 == 0x01) { /* 4Bytes returned after CMD8 sent */ buff[0] = _spi_read_write(DUMMY_BYTE); /* should be 0x00 */ buff[1] = _spi_read_write(DUMMY_BYTE); /* should be 0x00 */ buff[2] = _spi_read_write(DUMMY_BYTE); /* should be 0x01 */ buff[3] = _spi_read_write(DUMMY_BYTE); /* should be 0xAA */ /* End of CMD8, chip disable and dummy byte */ _card_disable(); _spi_read_write(DUMMY_BYTE); /* Check voltage range be 2.7-3.6V */ if(buff[2]==0x01 && buff[3]==0xAA) { for(retry=0; retry<0xFFF; retry++) { r1 = _send_command(CMD55, 0, 0); /* should be return 0x01 */ if(r1!=0x01) { #ifdef PRINT_INFO printf("Send CMD55 should return 0x01, response=0x%02x\r\n", r1); #endif return r1; } r1 = _send_command(ACMD41, 0x40000000, 0); /* should be return 0x00 */ if(r1 == 0x00) { retry = 0; break; } } /* Timeout return */ if(retry == 0xFFF) { #ifdef PRINT_INFO printf("Send ACMD41 should return 0x00, response=0x%02x\r\n", r1); #endif return 3; } /* Read OCR by CMD58 */ r1 = _send_command_hold(CMD58, 0, 0); if(r1!=0x00) { #ifdef PRINT_INFO printf("Send CMD58 should return 0x00, response=0x%02x\r\n", r1); #endif return r1; /* response error, return r1 */ } buff[0] = _spi_read_write(DUMMY_BYTE); buff[1] = _spi_read_write(DUMMY_BYTE); buff[2] = _spi_read_write(DUMMY_BYTE); buff[3] = _spi_read_write(DUMMY_BYTE); /* End of CMD58, chip disable and dummy byte */ _card_disable(); _spi_read_write(DUMMY_BYTE); /* OCR -> CCS(bit30) 1: SDV2HC 0: SDV2 */ if(buff[0] & 0x40) { CardInfo.CardType = CARDTYPE_SDV2HC; #ifdef PRINT_INFO printf("Card Type : SD V2HC\r\n"); #endif } else { CardInfo.CardType = CARDTYPE_SDV2; #ifdef PRINT_INFO printf("Card Type : SD V2\r\n"); #endif } /* Set spi speed high */ MSD_SPIHighSpeed(1); } } return 0; }