Example #1
0
/***********************************************************************
 *
 *    SD_Init
 *
 *  Description: Configures the SPI2 module and the File system to handle
 *                 an SD Card.
 *
 *  Returns:     OK if SPI configured, SD card is present, CMD0 true, 
 *                  SD card initialised, block length set to 512, 
 *                  SPI clock set to 4MHz.
 *               NO_SD_CARD if no SD card is present.
 *               INIT_FAILS if CMD0 (idle) fails, block length set fails.
 *               
 *               .
 *
 *************************************************************************/
UINT8 SD_Init(void) {

	UINT8 Count;
	UINT8 res;
	UINT8 CRC7_BYTE;
	UINT8 j;
	UINT8 i = 0;

	/* Configure the SD Card inserted detection pin */_SD_PRESENT = _IN; // Configure the data direction as IN.
	SD_PRESENT_PU = 1; // Enable Internal Pull-UP Resistor

	/* Initialise SPI Module */InitSPI(); // SS high, 375kHz clock.

	/* Delay SD card requires a delay of at least 1mSec after power up */
	for (j = 0; j < 200; j++) {
		for (Count = 0; Count < 255; Count++) {
			i += 1;
		}
	}

	/* Check for SD */
	if (SD_PRESENT) // Pin is low when SD Card present
//        return(NO_SD_CARD);
		return (0x11);

	/*** Start SD card Init ***/
	/* Minimum of 74 dummy clock cycles with MOSI high & SS enabled (low) */
//    SPI_SS = ENABLE;           // Enable SS
//    SD_CLKDelay(10);            // Send 80 clocks
//    SPI_SS_Disable_Delay(); 
//    SPI_SS = DISABLE;
	SD_CLKDelay(10); // Send 80 clocks with SS disabled
	SPI_SS_Disable_Delay();

	/* CMD0 - GO_IDLE_STATE
	 Reset the sd card & place it in SPI mode.
	 CRC must be valid.
	 Valid reset command is 0x40, 0x00, 0x00, 0x00, 0x00, 0x95.
	 Correct response is R1 (1 byte) = SD_IDLE (0x01).  
	 Note that the command frame starts with 
	 bits 47:46=0:1 (start & transmission bits) 
	 so the CMD byte has b6 set. */

	SPI_SS = ENABLE;
	gu8SD_Argument.lword = 0; // CMD0 argument is 0x00, 0x00, 0x00, 0x00.
	if (SD_SendCommand(SD_CMD0 | 0x40, SD_IDLE)) // returns OK (0x00) if OK
			{
		SPI_SS = DISABLE;
//        return(INIT_FAILS);
		return (0x12);
	}
	/* Card is in Idle State */
	SPI_SS_Disable_Delay();
	SPI_SS = DISABLE;

	SD_CLKDelay(1); // 8 dummy clocks

	/* Check if card is Ver2 compliant.
	 Send a SEND_IF_COND (CMD8) with supply voltage (VHS) set to 2.7-3.6volts.
	 Argument will be 0x000001AA and CRC7 + end bit 0x87.
	 CMD8 response is R7 (5 bytes - R1 + argument). */

	SPI_SS = ENABLE;
	gu8SD_Argument.lword = 0x000001AA;
	CRC7_BYTE = 0x87;
	if (SD_SendCommandR7(SD_CMD8, CRC7_BYTE)) {
		SPI_SS = DISABLE;
//        return(INIT_FAILS);
		return (0x13);
	}
	/* Card is version 2 compliant */
	SPI_SS_Disable_Delay();
	SPI_SS = DISABLE;

	SD_CLKDelay(1); // 8 dummy clocks

	/* Read the Operation Conditions Register OCR & check for correct voltage range.
	 Valid voltage range of 2.7-3.6 volts is indicated by 
	 gu8SD_Response[2:3] = 0xFF:0x80. Ref Table 5-1 P92.
	 Send READ_OCR CMD58.
	 CMD58 response R3 (5bytes - R1 + OCR). */SPI_SS = ENABLE;
	gu8SD_Argument.lword = 0x00000000;
	CRC7_BYTE = 0xFD;
	if (SD_SendCommandR3(SD_CMD58, SD_IDLE, CRC7_BYTE)) // Correct R1 is SD_IDLE (0x01)
			{
		SPI_SS = DISABLE;
//        return(INIT_FAILS);
		return (0x14);
	}
	/* Valid response received */
	SPI_SS_Disable_Delay();
	SPI_SS = DISABLE;
	SD_CLKDelay(1); // 8 dummy clocks
	/* Check for correct voltage range */
	if ((gu8SD_Response[2] != 0xFF) && (gu8SD_Response[3] != 0x80)) {
//      return(INIT_FAILS);
		return (0x15);
	}

	/* Initialise Card */
	/* Send continuous SD_SEND_OP_COND (ACMD41) until R1 b0 clears. */

	j = 0; // Clear loop counter
	do {
		j++;
		/* The next command is an application-specific command */
		do { // Wait for a successful CMD55
			/* The next command is an application-specific command */
			SPI_SS = ENABLE; // Enable SS
			gu8SD_Argument.lword = 0x00000000;
//        res = SD_SendCommand(SD_CMD55|0x40,0x80);  // returns OK (0x00) if  
			res = SD_SendCommand(SD_CMD55 | 0x40, SD_IDLE); // returns OK (0x00) if
															//  any valid response received
			SPI_SS_Disable_Delay();
			SPI_SS = DISABLE;
			SD_CLKDelay(1); // 8 dummy clocks
		} while (res);

		/* Send SD_SEND_OP_COND (ACMD41) */
		do {

			SPI_SS = ENABLE; // Enable SS
			/* High Capacity Support (HCS - argument b30) is set if host supports
			 SDHC or SDXC, wgich it does not in this case. */
//        gu8SD_Argument.lword = 0x40000000;            // HCS set
			gu8SD_Argument.lword = 0x00000000; // HCS clear
			res = SD_SendCommand(SD_CMD41 | 0x40, 0x80); // returns OK (0x00) if
//        res = SD_SendCommand(SD_CMD41|0x40,SD_OK);     // returns OK (0x00) if
					//  any valid response received
			SPI_SS_Disable_Delay();
			SPI_SS = DISABLE;
			SD_CLKDelay(1); // 8 dummy clocks
		} while (res);
	} while ((gu8SD_Response[0] != SD_OK) && (j < SD_IDLE_WAIT_MAX));

	/* Assume we're OK if we didn't hit the timeout */
	if (j >= SD_IDLE_WAIT_MAX)
//       return(INIT_FAILS);
		return (0x16);

	/* Read the Operation Conditions Register OCR & 
	 check the Card Power Up Status bit b31 and Card Capacity Status (CCS) b30. 
	 b31 & b30 of the OCR which is gu8SD_Response[1] b6. 
	 Power Up Status Bit will be 1 when the card is finished powering up.
	 CCS is 0 for a SDSC. Ref Table 5-1 P92.
	 Send READ_OCR CMD58.
	 CMD58 response R3 (5bytes - R1 + OCR). */SPI_SS = ENABLE;
	gu8SD_Argument.lword = 0x00000000;
	CRC7_BYTE = 0xFD;
	if (SD_SendCommandR3(SD_CMD58, SD_OK, CRC7_BYTE)) // Correct R1 response is SD_OK (0x00)
			{
		SPI_SS = DISABLE;
//        return(INIT_FAILS);
		return (0x17);
	}
	/* Valid response received */
	SPI_SS_Disable_Delay();
	SPI_SS = DISABLE;
	SD_CLKDelay(1); // 8 dummy clocks

	/* Check Power Up Status */
	if ((gu8SD_Response[1] & 0x80) == 0x00)
		return (0x19); // return Power Up not finished.

	/* Check CCS  */
	if (gu8SD_Response[1] & 0x40)
		return (0x1A); // return Card is not SDSC.

	/*  Set the Block Length to 512 bytes */SPI_SS = ENABLE;

	gu8SD_Argument.lword = SD_BLOCK_SIZE; // 512 bytes
	if (SD_SendCommand(SD_CMD16 | 0x40, SD_OK)) {
		SPI_SS = DISABLE;
//        return(INIT_FAILS);
		return (0x18);
	}

	SPI_SS_Disable_Delay();
	SPI_SS = DISABLE;
	SD_CLKDelay(1); // 8 dummy clocks

//    WriteSPIByte(0x00);
//    WriteSPIByte(0x00);

	/* Read the Card-Specific Data register (CSD) to gu8SD_CSD[16] */
	if (SD_Read_CSD()) {
		return (0x1B); // error 11. CSD read fail
	}

	HighSpeedSPI();

	return (OK);
}
Example #2
0
File: SD.c Project: ifreecarve/Main
UINT8 
SD_Init(void) 
{
    T32_8 gu8SD_Argument;
    
    SD_PRESENT_INIT;
    SD_PROTECTED_INIT;
    
    /* Check for SD */
    if(SD_PRESENT)
    {
       return(NO_SD_CARD);
    }        
    
    /* Initialize SPI Module */
    SD_DISABLE;/*First init*/
    
    /**********************FSL: SPI start-up*******************************/
    //if SPIhandle NULL, serial cannot be used!!!
    SDhandle = xSPIinit((eSPIPort)SD_CARD_SPI_PORT/*BSP being used*/, 
                             spi300,/*300KHz baudrate*/ 
                             serIDLEslow, 
                             serMiddleSample, 
                             serMaster,
                             serInterrupt,
                             SPI_SDCARD_BUFFER_LIMIT/*defined at header file*/);

    /* Start SD card Init */
    SD_ENABLE;
    SD_CLKDelay(10);            // Send 80 clocks 
    SD_DISABLE;
  
    gu8SD_Argument.lword=0;
    SD_CLKDelay(8);  
    
    /* IDLE Command */
    
    SD_ENABLE;
    if(SD_SendCommand(SD_CMD0|0x40,gu8SD_Argument,SD_IDLE))
    {
        SD_DISABLE;
        return(INIT_FAILS);      
    }
    SD_DISABLE;
    
    (void)ReadSPIByte(SDhandle);  // Dummy SPI cycle
    
    /*  Initialize SD Command */
    SD_ENABLE;
    while(SD_SendCommand(SD_CMD1|0x40,gu8SD_Argument,SD_OK))
    ;
    SD_DISABLE;
    
    (void)ReadSPIByte(SDhandle);  // Dummy SPI cycle

    /*  Block Length */
    SD_ENABLE;
      
    gu8SD_Argument.lword=SD_BLOCK_SIZE;
    if(SD_SendCommand(SD_CMD16|0x40,gu8SD_Argument,SD_OK))
    {
        SD_DISABLE;
        return(INIT_FAILS);      
    }
    
    SD_DISABLE;
    
    xSPIChangeToPolling(SDhandle);
    
    HighSpeedSPI(SD_CARD_SPI_PORT);

    WriteSPIByte(SDhandle,0x00);
    WriteSPIByte(SDhandle,0x00);
    return(OK);
}