// *************** // getCSD() tests // *************** TEST(GetRegisters, GetCSD_SuccessfulRead) { uint8_t csd[16]; initSDHC(); // CMD9 input data. setupDataForCmd("00"); // 0xFE starts read data block. m_sd.spi().setInboundFromString("FE"); // Data block will contain 16 bytes of 0xAD + valid CRC. setupDataBlock(0xAD, 16); // Clear buffer to 0x00 before reading into it. memset(csd, 0, sizeof(csd)); LONGS_EQUAL(RES_OK, m_sd.getCSD(csd, sizeof(csd))); validateSelect(); // Should send CMD9 to start read. validateCmdPacket(9); // Should send multiple FF bytes to read in register data block: // 1 to read in header. // 16 to read data. // 2 to read CRC. validateFFBytes(1+16+2); validateDeselect(); // Verify that register contents were read into supplied buffer. validateBuffer(csd, 16, 0xAD); }
TEST(GetRegisters, GetOCR_FailCommand_ShouldFail) { uint32_t ocr = 0; initSDHC(); // CMD58 input data with error response. setupDataForCmd("04"); LONGS_EQUAL(RES_ERROR, m_sd.getOCR(&ocr)); // Should send CMD58 to read OCR. validateCmd(58, 0); // Verify that register contents weren't read into supplied buffer. LONGS_EQUAL(0, ocr); // Verify error log output. m_sd.dumpErrorLog(stderr); char expectedOutput[256]; snprintf(expectedOutput, sizeof(expectedOutput), "getOCR(%08X) - Register read failed. Response=0x04\n", (uint32_t)(size_t)&ocr); STRCMP_EQUAL(expectedOutput, printfSpy_GetLastOutput()); }
TEST(GetRegisters, GetCID_FailCommand_ShouldFail) { uint8_t cid[16]; initSDHC(); // CMD10 input data. setupDataForCmd("04"); // Clear buffer to 0x00 before reading into it. memset(cid, 0, sizeof(cid)); LONGS_EQUAL(RES_ERROR, m_sd.getCID(cid, sizeof(cid))); validateSelect(); // Should send CMD10 to start read. validateCmdPacket(10); validateDeselect(); // Verify that register contents weren't modified. validateBuffer(cid, 16, 0x00); // Verify error log output. m_sd.dumpErrorLog(stderr); char expectedOutput[256]; snprintf(expectedOutput, sizeof(expectedOutput), "sendCommandAndReceiveDataBlock(CMD10,0,%08X,16) - CMD10 returned 0x04\n" "getCID(%08X,16) - Register read failed\n", (uint32_t)(size_t)cid, (uint32_t)(size_t)cid); STRCMP_EQUAL(expectedOutput, printfSpy_GetLastOutput()); }
// *************** // getOCR() tests // *************** TEST(GetRegisters, GetOCR_SuccessfulRead) { uint32_t ocr = 0; initSDHC(); // CMD58 input data with 4-byte OCR value. setupDataForCmd("00"); m_sd.spi().setInboundFromString("12345678"); LONGS_EQUAL(RES_OK, m_sd.getOCR(&ocr)); // Should send CMD58 to read OCR. validateCmd(58, 0, 4); // Verify that register contents were read into supplied buffer. LONGS_EQUAL(0x12345678, ocr); }
//============================================================================= bool SdioCard::begin() { uint32_t kHzSdClk; uint32_t arg; m_initDone = false; m_errorCode = SD_CARD_ERROR_NONE; m_highCapacity = false; m_version2 = false; // initialize controller. initSDHC(); if (!cardCommand(CMD0_XFERTYP, 0)) { return sdError(SD_CARD_ERROR_CMD0); } // Try several times for case of reset delay. for (uint32_t i = 0; i < CMD8_RETRIES; i++) { if (cardCommand(CMD8_XFERTYP, 0X1AA)) { if (SDHC_CMDRSP0 != 0X1AA) { return sdError(SD_CARD_ERROR_CMD8); } m_version2 = true; break; } } arg = m_version2 ? 0X40300000 : 0x00300000; uint32_t m = micros(); do { if (!cardAcmd(0, ACMD41_XFERTYP, arg) || ((micros() - m) > BUSY_TIMEOUT_MICROS)) { return sdError(SD_CARD_ERROR_ACMD41); } } while ((SDHC_CMDRSP0 & 0x80000000) == 0); m_ocr = SDHC_CMDRSP0; if (SDHC_CMDRSP0 & 0x40000000) { // Is high capacity. m_highCapacity = true; } if (!cardCommand(CMD2_XFERTYP, 0)) { return sdError(SD_CARD_ERROR_CMD2); } if (!cardCommand(CMD3_XFERTYP, 0)) { return sdError(SD_CARD_ERROR_CMD3); } m_rca = SDHC_CMDRSP0 & 0xFFFF0000; if (!readReg16(CMD9_XFERTYP, &m_csd)) { return sdError(SD_CARD_ERROR_CMD9); } if (!readReg16(CMD10_XFERTYP, &m_cid)) { return sdError(SD_CARD_ERROR_CMD10); } if (!cardCommand(CMD7_XFERTYP, m_rca)) { return sdError(SD_CARD_ERROR_CMD7); } // Set card to bus width four. if (!cardAcmd(m_rca, ACMD6_XFERTYP, 2)) { return sdError(SD_CARD_ERROR_ACMD6); } // Set SDHC to bus width four. SDHC_PROCTL &= ~SDHC_PROCTL_DTW_MASK; SDHC_PROCTL |= SDHC_PROCTL_DTW(SDHC_PROCTL_DTW_4BIT); SDHC_WML = SDHC_WML_RDWML(FIFO_WML) | SDHC_WML_WRWML(FIFO_WML); // Determine if High Speed mode is supported and set frequency. uint8_t status[64]; if (cardCMD6(0X00FFFFFF, status) && (2 & status[13]) && cardCMD6(0X80FFFFF1, status) && (status[16] & 0XF) == 1) { kHzSdClk = 50000; } else { kHzSdClk = 25000; } // disable GPIO enableGPIO(false); // Set the SDHC SCK frequency. setSdclk(kHzSdClk); // enable GPIO enableGPIO(true); m_initDone = true; return true; }