/*******************************************************************************
* 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;
}
Esempio n. 2
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;
}