/* 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; }