|
|
@ -18,10 +18,12 @@ static void sd_mmc_send_clock(void);
|
|
|
|
static void sd_mmc_print_err(sd_mmc_err_t err);
|
|
|
|
static void sd_mmc_print_err(sd_mmc_err_t err);
|
|
|
|
static void sd_mmc_print_res1(uint8_t res);
|
|
|
|
static void sd_mmc_print_res1(uint8_t res);
|
|
|
|
static void sd_mmc_print_res7(const uint8_t* const res);
|
|
|
|
static void sd_mmc_print_res7(const uint8_t* const res);
|
|
|
|
|
|
|
|
static void sd_mmc_print_res3(const uint8_t* const res);
|
|
|
|
|
|
|
|
|
|
|
|
sd_mmc_err_t sd_mmc_init(void)
|
|
|
|
sd_mmc_err_t sd_mmc_init(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sd_mmc_err_t ret = SD_MMC_SUCCESS;
|
|
|
|
sd_mmc_err_t ret = SD_MMC_SUCCESS;
|
|
|
|
|
|
|
|
uint8_t ocr[5];
|
|
|
|
|
|
|
|
|
|
|
|
do
|
|
|
|
do
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -33,19 +35,25 @@ sd_mmc_err_t sd_mmc_init(void)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Power up sd card sequence
|
|
|
|
// Power up sd card sequence
|
|
|
|
if((ret != sd_mmc_power_up_sequence()) != SD_MMC_SUCCESS)
|
|
|
|
if((ret = sd_mmc_power_up_sequence()) != SD_MMC_SUCCESS)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// go idle
|
|
|
|
// go idle
|
|
|
|
if((ret != sd_mmc_idle_sequence()) != SD_MMC_SUCCESS)
|
|
|
|
if((ret = sd_mmc_idle_sequence()) != SD_MMC_SUCCESS)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// interface sequence
|
|
|
|
// interface sequence
|
|
|
|
if((ret != sd_mmc_if_sequence()) != SD_MMC_SUCCESS)
|
|
|
|
if((ret = sd_mmc_if_sequence()) != SD_MMC_SUCCESS)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// read operation conditions register
|
|
|
|
|
|
|
|
if((ret = sd_mmc_read_ocr(ocr)) != SD_MMC_SUCCESS)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -126,12 +134,12 @@ sd_mmc_err_t sd_mmc_read_res7(uint8_t* res7)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(res7[0] > 1)
|
|
|
|
/* if(res7[0] > 1) */
|
|
|
|
{
|
|
|
|
/* { */
|
|
|
|
// handle this error better later
|
|
|
|
/* // handle this error better later */
|
|
|
|
ret = SD_MMC_ERR_COMM;
|
|
|
|
/* ret = SD_MMC_ERR_COMM; */
|
|
|
|
break;
|
|
|
|
/* break; */
|
|
|
|
}
|
|
|
|
/* } */
|
|
|
|
}while(0);
|
|
|
|
}while(0);
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -141,18 +149,19 @@ sd_mmc_err_t sd_mmc_read_res3(uint8_t* res3)
|
|
|
|
sd_mmc_err_t ret = SD_MMC_SUCCESS;
|
|
|
|
sd_mmc_err_t ret = SD_MMC_SUCCESS;
|
|
|
|
do
|
|
|
|
do
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
SD_MMC_INTF_READ(res3, 1);
|
|
|
|
if(5 != SD_MMC_INTF_READ(res3, 5))
|
|
|
|
if(5 != SD_MMC_INTF_READ(res3, 5))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ret = SD_MMC_ERR_COMM;
|
|
|
|
ret = SD_MMC_ERR_COMM;
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(res3[0] > 1)
|
|
|
|
/* if(res3[0] > 1) */
|
|
|
|
{
|
|
|
|
/* { */
|
|
|
|
// handle this error better later
|
|
|
|
/* // handle this error better later */
|
|
|
|
ret = SD_MMC_ERR_COMM;
|
|
|
|
/* ret = SD_MMC_ERR_COMM; */
|
|
|
|
break;
|
|
|
|
/* break; */
|
|
|
|
}
|
|
|
|
/* } */
|
|
|
|
}while(0);
|
|
|
|
}while(0);
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|
|
|
|
|
|
|
|
@ -175,12 +184,12 @@ sd_mmc_err_t sd_mmc_idle_sequence()
|
|
|
|
do
|
|
|
|
do
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sd_mmc_select(0, 0, 0, true);
|
|
|
|
sd_mmc_select(0, 0, 0, true);
|
|
|
|
if((ret != sd_mmc_send_command(CMD0, CMD0_ARG, CMD0_CRC)) != SD_MMC_SUCCESS)
|
|
|
|
if((ret = sd_mmc_send_command(CMD0, CMD0_ARG, CMD0_CRC)) != SD_MMC_SUCCESS)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if((ret != sd_mmc_read_res1(&res1)) != SD_MMC_SUCCESS)
|
|
|
|
if((ret = sd_mmc_read_res1(&res1)) != SD_MMC_SUCCESS)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -272,6 +281,7 @@ void sd_mmc_print_err(sd_mmc_err_t err)
|
|
|
|
|
|
|
|
|
|
|
|
void sd_mmc_print_res1(uint8_t res)
|
|
|
|
void sd_mmc_print_res1(uint8_t res)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("RES1: 0x%02x\n", res);
|
|
|
|
if(res & 0b10000000)
|
|
|
|
if(res & 0b10000000)
|
|
|
|
{ printf("\tError: MSB = 1\r\n"); return; }
|
|
|
|
{ printf("\tError: MSB = 1\r\n"); return; }
|
|
|
|
if(res == 0)
|
|
|
|
if(res == 0)
|
|
|
@ -295,7 +305,7 @@ void sd_mmc_print_res1(uint8_t res)
|
|
|
|
void sd_mmc_print_res7(const uint8_t* const res)
|
|
|
|
void sd_mmc_print_res7(const uint8_t* const res)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sd_mmc_print_res1(res[0]);
|
|
|
|
sd_mmc_print_res1(res[0]);
|
|
|
|
if(res[0] > 1) return;
|
|
|
|
/* if(res[0] > 1) return; */
|
|
|
|
|
|
|
|
|
|
|
|
printf("\tCommand Version: 0x%02x\n", CMD_VER(res[1]));
|
|
|
|
printf("\tCommand Version: 0x%02x\n", CMD_VER(res[1]));
|
|
|
|
|
|
|
|
|
|
|
@ -307,6 +317,35 @@ void sd_mmc_print_res7(const uint8_t* const res)
|
|
|
|
printf("\tEcho: 0x%02x\n", res[4]);
|
|
|
|
printf("\tEcho: 0x%02x\n", res[4]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void sd_mmc_print_res3(const uint8_t* const res)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sd_mmc_print_res1(res[0]);
|
|
|
|
|
|
|
|
/* if(res[0] > 1) return; */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("\tCard Power Up Status: 0x%02x\n", res[1]);
|
|
|
|
|
|
|
|
if(POWER_UP_STATUS(res[1]))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("READY\n");
|
|
|
|
|
|
|
|
printf("\tCCS Status: %d\n", CCS_VAL(res[1]) ? 1 : 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
printf("BUSY\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
printf("\tVDD Window: ");
|
|
|
|
|
|
|
|
if(VDD_2728(res[3])) printf("2.7-2.8, ");
|
|
|
|
|
|
|
|
if(VDD_2829(res[2])) printf("2.8-2.9, ");
|
|
|
|
|
|
|
|
if(VDD_2930(res[2])) printf("2.9-3.0, ");
|
|
|
|
|
|
|
|
if(VDD_3031(res[2])) printf("3.0-3.1, ");
|
|
|
|
|
|
|
|
if(VDD_3132(res[2])) printf("3.1-3.2, ");
|
|
|
|
|
|
|
|
if(VDD_3233(res[2])) printf("3.2-3.3, ");
|
|
|
|
|
|
|
|
if(VDD_3334(res[2])) printf("3.3-3.4, ");
|
|
|
|
|
|
|
|
if(VDD_3435(res[2])) printf("3.4-3.5, ");
|
|
|
|
|
|
|
|
if(VDD_3536(res[2])) printf("3.5-3.6");
|
|
|
|
|
|
|
|
printf("\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool sd_mmc_check_cd(void)
|
|
|
|
bool sd_mmc_check_cd(void)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -347,8 +386,6 @@ void sd_mmc_send_clock()
|
|
|
|
sd_mmc_err_t sd_mmc_read_ocr(uint8_t* res)
|
|
|
|
sd_mmc_err_t sd_mmc_read_ocr(uint8_t* res)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
sd_mmc_err_t ret = SD_MMC_SUCCESS;
|
|
|
|
sd_mmc_err_t ret = SD_MMC_SUCCESS;
|
|
|
|
uint8_t res3[5];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sd_mmc_select(0, 0, 0, false);
|
|
|
|
sd_mmc_select(0, 0, 0, false);
|
|
|
|
do
|
|
|
|
do
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -357,10 +394,11 @@ sd_mmc_err_t sd_mmc_read_ocr(uint8_t* res)
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if((ret = sd_mmc_read_res3(res3)) != SD_MMC_SUCCESS)
|
|
|
|
if((ret = sd_mmc_read_res3(res)) != SD_MMC_SUCCESS)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sd_mmc_print_res3(res);
|
|
|
|
}while(0);
|
|
|
|
}while(0);
|
|
|
|
sd_mmc_deselect(0);
|
|
|
|
sd_mmc_deselect(0);
|
|
|
|
return ret;
|
|
|
|
return ret;
|
|
|
|