/*
initialize SD card
*/
unsigned char initSD()
{
   uint8_t i, response;
   SD_SPI_Init();
   SD_CS_DIS();
    
   //send 80 clock pulse
   for(i=0;i<10;i++)
      SD_SPI_Send(0xff);
   SD_CS_EN();
   SD_sendCMD(0x40,0,0x95); // send CMD0 command;
   while ((response = SD_GET_Response())== 0x01)
   { 
      SD_CS_DIS();
      SD_SPI_Send(0xff);    
      SD_CS_EN();
      SD_sendCMD(0x41,0,0x95); //send CMD1
      
   }
   SD_CS_DIS();
   return 0;  
}
//------------------------------------------------------------------------------
/// Run the SDcard initialization sequence. This function runs the initialisation
/// procedure and the identification process, then it sets the SD card in transfer
/// state to set the block length and the bus width.
/// Returns 0 if successful; otherwise returns an SD_ERROR code.
/// \param pSd  Pointer to a SD card driver instance.
/// \param pSdDriver  Pointer to SD driver already initialized.
/// \param mode  Select SD or SPI access mode
//------------------------------------------------------------------------------
unsigned char SD_Init(SdCard *pSd, SdDriver *pSdDriver)
{
    unsigned char error;

    //TRACE_DEBUG("SD_Init()\n\r");

    // Initialize SdCard structure
    pSd->pSdDriver = pSdDriver;
    pSd->cardAddress = 0;
    pSd->preBlock = 0xffffffff;
    pSd->state = SD_STATE_STBY;
    pSd->cardType = UNKNOWN_CARD;
    memset(&(pSd->command), 0, sizeof(SdCmd));

    // Initialization delay: The maximum of 1 msec, 74 clock cycles and supply ramp up time
    // ‘Supply ramp up time’ provides the time that the power is built up to the operating level (the bus
    // master supply voltage) and the time to wait until the SD card can accept the first command

    // Power On Init Special Command
    //TRACE_DEBUG("Pon()\n\r");
    error = Pon(pSd);
    if (error) {
        TRACE_ERROR("Error during initialization (%d)\n\r", error);
        return error;
    }

    // After power-on or CMD0, all cards’ CMD lines are in input mode, waiting for start bit of the next command.
    // The cards are initialized with a default relative card address (RCA=0x0000) and with a default
    // driver stage register setting (lowest speed, highest driving current capability).

    error = SD_SPI_Init(pSd, pSdDriver);
    if (error) {
        TRACE_ERROR("Error during initialization (%d)\n\r", error);
        return error;
    }

    // In the case of a Standard Capacity SD Memory Card, this command sets the
    // block length (in bytes) for all following block commands (read, write, lock).
    // Default block length is fixed to 512 Bytes.
    // Set length is valid for memory access commands only if partial block read
    // operation are allowed in CSD.
    // In the case of a High Capacity SD Memory Card, block length set by CMD16
    // command does not affect the memory read and write commands. Always 512
    // Bytes fixed block length is used. This command is effective for LOCK_UNLOCK command.
    // In both cases, if block length is set larger than 512Bytes, the card sets the
    // BLOCK_LEN_ERROR bit.
    if (pSd->cardType == CARD_SD) {
        error = Cmd16(pSd, SD_BLOCK_SIZE);
        if (error) {
            TRACE_ERROR("Error during initialization (%d)\n\r", error);
            return error;
        }
    }

    // If SD CSD v2.0
    if((pSd->cardType != CARD_MMC) && (SD_CSD_STRUCTURE(pSd) == 1)) {
        pSd->totalSize = SD_CSD_TOTAL_SIZE_HC(pSd);
        pSd->blockNr = SD_CSD_BLOCKNR_HC(pSd);
    }
    else {
        pSd->totalSize = SD_CSD_TOTAL_SIZE(pSd);
        pSd->blockNr = SD_CSD_BLOCKNR(pSd);
    }

    if (pSd->cardType == UNKNOWN_CARD) {
        return SD_ERROR_NOT_INITIALIZED;
    }
    else {
        return 0;
    }
}
/*
initialize SD card
*/
unsigned char initSD()
{
	
	uint8_t i, response;
	SD_SPI_Init();


    //set clock freq to 100kHz<312.50kHz<400kHz
	//SD Card spec says that card init needs to happen with a clock in this range
	//Fcy = 40M
	//Primary = 64:1, Secondary = 2:1 --> 312.50 kHz
	//PPRE = 0b00, SPRE = 0b110
	SPICON1bits.PPRE=0;
	SPICON1bits.SPRE=6;


	SD_CS_DIS();
	volatile uint8_t dummy; 
	//send 80 clock pulse
	for(i=0;i<10;i++)
	{
		SD_SPI_Send(0xff);
		dummy = SD_SPIBUF;
	}
	SD_CS_EN();
	SD_sendCMD(SD_GO_IDLE_STATE,0,0x95); // send CMD0 command == reset and enter idle state
	SD_GET_Response();
	SD_sendCMD(SD_APP_CMD,0,0x00); // next cmd is app specific
	SD_GET_Response();
	SD_sendCMD(SD_ACMD_41,0,0x00); // send "send interface condition"


	i=255;
	while ((response = SD_GET_Response())== 0x01 && i > 0)
	{ 
		SD_CS_DIS();
		SD_SPI_Send(0xff);
		dummy = SD_SPIBUF;    
		SD_CS_EN();
		SD_sendCMD(SD_APP_CMD,0,0x00); // next cmd is app specific
		SD_GET_Response();
		SD_sendCMD(SD_ACMD_41,0,0x00); // send "send interface condition"
		i--;
	}
	SD_CS_DIS();

	//SD Card spec says cards must work up to 25Mhz
    //step clock freq up to max < 25MHz
	//Fcy = 40M

	//Primary = 4:1, Secondary = 1:1 --> 10 MHz
	//PPRE = 0b10, SPRE = 0b111
//	SPICON1bits.PPRE=2;
//	SPICON1bits.SPRE=7;


	//Primary = 1:1, Sec = 2:1 --> 20MHz
	//PPRE = 0b11, SPRE = 0b110
	SPICON1bits.PPRE=3;
	SPICON1bits.SPRE=6;


	return i == 0 ? 0 : 1;  
}