This commit is contained in:
topicchi
2024-09-24 16:54:39 +00:00
parent e3ca99e4db
commit c7a68c0205
332 changed files with 6098 additions and 4139 deletions

View File

@@ -27,14 +27,11 @@
class Timeout {
public:
Timeout() {}
explicit Timeout(uint16_t ms) {set(ms);}
uint16_t millis16() {return millis();}
void set(uint16_t ms) {
m_endTime = ms + millis16();
}
bool timedOut() {
return (int16_t)(m_endTime - millis16()) < 0;
}
explicit Timeout(uint16_t ms) { set(ms); }
uint16_t millis16() { return millis(); }
void set(uint16_t ms) { m_endTime = ms + millis16(); }
bool timedOut() { return (int16_t)(m_endTime - millis16()) < 0; }
private:
uint16_t m_endTime;
};
@@ -77,48 +74,44 @@ static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
// uses the x^16,x^12,x^5,x^1 polynomial.
#ifdef __AVR__
static const uint16_t crctab[] PROGMEM = {
#else // __AVR__
#else // __AVR__
static const uint16_t crctab[] = {
#endif // __AVR__
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
};
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7, 0x8108,
0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,
0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6, 0x9339, 0x8318, 0xB37B,
0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401,
0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE,
0xF5CF, 0xC5AC, 0xD58D, 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6,
0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D,
0xC7BC, 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B, 0x5AF5,
0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC,
0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A, 0x6CA6, 0x7C87, 0x4CE4,
0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD,
0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13,
0x2E32, 0x1E51, 0x0E70, 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A,
0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E,
0xE16F, 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E, 0x02B1,
0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB,
0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D, 0x34E2, 0x24C3, 0x14A0,
0x0481, 0x7466, 0x6447, 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8,
0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657,
0x7676, 0x4615, 0x5634, 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9,
0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882,
0x28A3, 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92, 0xFD2E,
0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1, 0xEF1F, 0xFF3E, 0xCF5D,
0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,
0x2E93, 0x3EB2, 0x0ED1, 0x1EF0};
static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
uint16_t crc = 0;
for (size_t i = 0; i < n; i++) {
#ifdef __AVR__
crc = pgm_read_word(&crctab[(crc >> 8 ^ data[i]) & 0XFF]) ^ (crc << 8);
#else // __AVR__
#else // __AVR__
crc = crctab[(crc >> 8 ^ data[i]) & 0XFF] ^ (crc << 8);
#endif // __AVR__
}
@@ -131,10 +124,9 @@ static uint16_t CRC_CCITT(const uint8_t* data, size_t n) {
//------------------------------------------------------------------------------
bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
Timeout timeout;
m_spiActive = false;
m_beginCalled = false;
// Restore state to creator.
initSharedSpiCard();
m_errorCode = SD_CARD_ERROR_NONE;
m_type = 0;
m_csPin = spiConfig.csPin;
#if SPI_DRIVER_SELECT >= 2
m_spiDriverPtr = spiConfig.spiPort;
@@ -145,32 +137,28 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
#endif // SPI_DRIVER_SELECT
sdCsInit(m_csPin);
spiUnselect();
spiSetSckSpeed(1000UL*SD_MAX_INIT_RATE_KHZ);
spiSetSckSpeed(1000UL * SD_MAX_INIT_RATE_KHZ);
spiBegin(spiConfig);
m_beginCalled = true;
uint32_t arg;
m_state = IDLE_STATE;
spiStart();
// must supply min of 74 clock cycles with CS high.
spiUnselect();
for (uint8_t i = 0; i < 10; i++) {
spiSend(0XFF);
spiReceive();
}
spiSelect();
// command to go idle in SPI mode
for (uint8_t i = 1;; i++) {
timeout.set(SD_INIT_TIMEOUT);
while (true) {
// command to go idle in SPI mode
if (cardCommand(CMD0, 0) == R1_IDLE_STATE) {
break;
}
if (i == SD_CMD0_RETRY) {
if (timeout.timedOut()) {
error(SD_CARD_ERROR_CMD0);
goto fail;
}
// Force any active transfer to end for an already initialized card.
for (uint8_t j = 0; j < 0XFF; j++) {
spiSend(0XFF);
}
}
#if USE_SD_CRC
if (cardCommand(CMD59, 1) != R1_IDLE_STATE) {
@@ -179,21 +167,26 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
}
#endif // USE_SD_CRC
// check SD version
if (!(cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
type(SD_CARD_TYPE_SD2);
while (true) {
if (cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND) {
type(SD_CARD_TYPE_SD1);
break;
}
// Skip first three bytes.
for (uint8_t i = 0; i < 4; i++) {
m_status = spiReceive();
}
if (m_status != 0XAA) {
if (m_status == 0XAA) {
type(SD_CARD_TYPE_SD2);
break;
}
if (timeout.timedOut()) {
error(SD_CARD_ERROR_CMD8);
goto fail;
}
} else {
type(SD_CARD_TYPE_SD1);
}
// initialize card and send host supports SDHC if SD2
arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;
timeout.set(SD_INIT_TIMEOUT);
while (cardAcmd(ACMD41, arg) != R1_READY_STATE) {
// check for timeout
if (timeout.timedOut()) {
@@ -201,7 +194,6 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
goto fail;
}
}
// if SD2 read OCR register to check for SDHC card
if (type() == SD_CARD_TYPE_SD2) {
if (cardCommand(CMD58, 0)) {
@@ -220,7 +212,7 @@ bool SharedSpiCard::begin(SdSpiConfig spiConfig) {
spiSetSckSpeed(spiConfig.maxSck);
return true;
fail:
fail:
spiStop();
return false;
}
@@ -236,7 +228,7 @@ bool SharedSpiCard::cardCMD6(uint32_t arg, uint8_t* status) {
spiStop();
return true;
fail:
fail:
spiStop();
return false;
}
@@ -267,7 +259,7 @@ uint8_t SharedSpiCard::cardCommand(uint8_t cmd, uint32_t arg) {
// send message
spiSend(buf, 6);
#else // USE_SD_CRC
#else // USE_SD_CRC
// send command
spiSend(cmd | 0x40);
@@ -285,7 +277,7 @@ uint8_t SharedSpiCard::cardCommand(uint8_t cmd, uint32_t arg) {
spiReceive();
// there are 1-8 fill bytes before response. fill bytes should be 0XFF.
uint16_t n = 0;
uint8_t n = 0;
do {
m_status = spiReceive();
} while (m_status & 0X80 && ++n < 10);
@@ -294,7 +286,7 @@ uint8_t SharedSpiCard::cardCommand(uint8_t cmd, uint32_t arg) {
//------------------------------------------------------------------------------
void SharedSpiCard::end() {
if (m_beginCalled) {
spiStop();
syncDevice();
spiEnd();
m_beginCalled = false;
}
@@ -319,9 +311,8 @@ bool SharedSpiCard::erase(uint32_t firstSector, uint32_t lastSector) {
firstSector <<= 9;
lastSector <<= 9;
}
if (cardCommand(CMD32, firstSector)
|| cardCommand(CMD33, lastSector)
|| cardCommand(CMD38, 0)) {
if (cardCommand(CMD32, firstSector) || cardCommand(CMD33, lastSector) ||
cardCommand(CMD38, 0)) {
error(SD_CARD_ERROR_ERASE);
goto fail;
}
@@ -332,7 +323,7 @@ bool SharedSpiCard::erase(uint32_t firstSector, uint32_t lastSector) {
spiStop();
return true;
fail:
fail:
spiStop();
return false;
}
@@ -357,9 +348,7 @@ bool SharedSpiCard::isBusy() {
return rtn;
}
//------------------------------------------------------------------------------
bool SharedSpiCard::readData(uint8_t* dst) {
return readData(dst, 512);
}
bool SharedSpiCard::readData(uint8_t* dst) { return readData(dst, 512); }
//------------------------------------------------------------------------------
bool SharedSpiCard::readData(uint8_t* dst, size_t count) {
#if USE_SD_CRC
@@ -391,14 +380,14 @@ bool SharedSpiCard::readData(uint8_t* dst, size_t count) {
error(SD_CARD_ERROR_READ_CRC);
goto fail;
}
#else // USE_SD_CRC
#else // USE_SD_CRC
// discard crc
spiReceive();
spiReceive();
#endif // USE_SD_CRC
return true;
fail:
fail:
spiStop();
return false;
}
@@ -412,14 +401,14 @@ bool SharedSpiCard::readOCR(uint32_t* ocr) {
for (uint8_t i = 0; i < 4; i++) {
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
p[3 - i] = spiReceive();
#else // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
#else // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
p[i] = spiReceive();
#endif // __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
}
spiStop();
return true;
fail:
fail:
spiStop();
return false;
}
@@ -437,7 +426,7 @@ bool SharedSpiCard::readRegister(uint8_t cmd, void* buf) {
spiStop();
return true;
fail:
fail:
spiStop();
return false;
}
@@ -454,7 +443,7 @@ bool SharedSpiCard::readSCR(scr_t* scr) {
spiStop();
return true;
fail:
fail:
spiStop();
return false;
}
@@ -474,7 +463,7 @@ bool SharedSpiCard::readSector(uint32_t sector, uint8_t* dst) {
spiStop();
return true;
fail:
fail:
spiStop();
return false;
}
@@ -489,7 +478,7 @@ bool SharedSpiCard::readSectors(uint32_t sector, uint8_t* dst, size_t ns) {
}
}
return readStop();
fail:
fail:
return false;
}
//------------------------------------------------------------------------------
@@ -504,25 +493,25 @@ bool SharedSpiCard::readStart(uint32_t sector) {
m_state = READ_STATE;
return true;
fail:
fail:
spiStop();
return false;
}
//------------------------------------------------------------------------------
bool SharedSpiCard::readStatus(SdStatus* status) {
uint8_t* dst = reinterpret_cast<uint8_t*>(status);
bool SharedSpiCard::readSDS(sds_t* sds) {
uint8_t* dst = reinterpret_cast<uint8_t*>(sds);
// retrun is R2 so read extra status byte.
if (cardAcmd(ACMD13, 0) || spiReceive()) {
error(SD_CARD_ERROR_ACMD13);
goto fail;
}
if (!readData(dst, 64)) {
if (!readData(dst, sizeof(sds_t))) {
goto fail;
}
spiStop();
return true;
fail:
fail:
spiStop();
return false;
}
@@ -536,7 +525,7 @@ bool SharedSpiCard::readStop() {
spiStop();
return true;
fail:
fail:
spiStop();
return false;
}
@@ -547,6 +536,7 @@ uint32_t SharedSpiCard::sectorCount() {
}
//------------------------------------------------------------------------------
void SharedSpiCard::spiStart() {
SPI_ASSERT_NOT_ACTIVE;
if (!m_spiActive) {
spiActivate();
m_spiActive = true;
@@ -557,6 +547,7 @@ void SharedSpiCard::spiStart() {
}
//------------------------------------------------------------------------------
void SharedSpiCard::spiStop() {
SPI_ASSERT_ACTIVE;
if (m_spiActive) {
spiUnselect();
// Insure MISO goes to low Z.
@@ -597,7 +588,7 @@ bool SharedSpiCard::writeData(const uint8_t* src) {
}
return true;
fail:
fail:
spiStop();
return false;
}
@@ -606,7 +597,7 @@ bool SharedSpiCard::writeData(const uint8_t* src) {
bool SharedSpiCard::writeData(uint8_t token, const uint8_t* src) {
#if USE_SD_CRC
uint16_t crc = CRC_CCITT(src, 512);
#else // USE_SD_CRC
#else // USE_SD_CRC
uint16_t crc = 0XFFFF;
#endif // USE_SD_CRC
spiSend(token);
@@ -621,7 +612,7 @@ bool SharedSpiCard::writeData(uint8_t token, const uint8_t* src) {
}
return true;
fail:
fail:
spiStop();
return false;
}
@@ -655,13 +646,13 @@ bool SharedSpiCard::writeSector(uint32_t sector, const uint8_t* src) {
spiStop();
return true;
fail:
fail:
spiStop();
return false;
}
//------------------------------------------------------------------------------
bool SharedSpiCard::writeSectors(uint32_t sector,
const uint8_t* src, size_t ns) {
bool SharedSpiCard::writeSectors(uint32_t sector, const uint8_t* src,
size_t ns) {
if (!writeStart(sector)) {
goto fail;
}
@@ -672,7 +663,7 @@ bool SharedSpiCard::writeSectors(uint32_t sector,
}
return writeStop();
fail:
fail:
spiStop();
return false;
}
@@ -689,7 +680,7 @@ bool SharedSpiCard::writeStart(uint32_t sector) {
m_state = WRITE_STATE;
return true;
fail:
fail:
spiStop();
return false;
}
@@ -703,7 +694,7 @@ bool SharedSpiCard::writeStop() {
m_state = IDLE_STATE;
return true;
fail:
fail:
error(SD_CARD_ERROR_STOP_TRAN);
spiStop();
return false;
@@ -721,8 +712,7 @@ bool DedicatedSpiCard::readSector(uint32_t sector, uint8_t* dst) {
return readSectors(sector, dst, 1);
}
//------------------------------------------------------------------------------
bool DedicatedSpiCard::readSectors(
uint32_t sector, uint8_t* dst, size_t ns) {
bool DedicatedSpiCard::readSectors(uint32_t sector, uint8_t* dst, size_t ns) {
if (sdState() != READ_STATE || sector != m_curSector) {
if (!readStart(sector)) {
goto fail;
@@ -737,7 +727,7 @@ bool DedicatedSpiCard::readSectors(
m_curSector += ns;
return m_dedicatedSpi ? true : readStop();
fail:
fail:
return false;
}
//------------------------------------------------------------------------------
@@ -756,8 +746,8 @@ bool DedicatedSpiCard::writeSector(uint32_t sector, const uint8_t* src) {
return SharedSpiCard::writeSector(sector, src);
}
//------------------------------------------------------------------------------
bool DedicatedSpiCard::writeSectors(
uint32_t sector, const uint8_t* src, size_t ns) {
bool DedicatedSpiCard::writeSectors(uint32_t sector, const uint8_t* src,
size_t ns) {
if (sdState() != WRITE_STATE || m_curSector != sector) {
if (!writeStart(sector)) {
goto fail;

View File

@@ -24,25 +24,43 @@
*/
/**
* \file
* \brief SdSpiCard class for V2 SD/SDHC cards
* \brief Classes for SPI access to SD/SDHC cards.
*/
#ifndef SdSpiCard_h
#define SdSpiCard_h
#include <stddef.h>
#include "../SpiDriver/SdSpiDriver.h"
#include "../common/SysCall.h"
#include "SdCardInfo.h"
#include "SdCardInterface.h"
#include "../SpiDriver/SdSpiDriver.h"
/** Verify correct SPI active if non-zero. */
#define CHECK_SPI_ACTIVE 0
#if CHECK_SPI_ACTIVE
/** Check SPI active. */
#define SPI_ASSERT_ACTIVE {if (!m_spiActive) {\
Serial.print(F("SPI_ASSERTACTIVE"));\
Serial.println(__LINE__);}}
#define SPI_ASSERT_ACTIVE \
{ \
if (!m_spiActive) { \
Serial.print(F("SPI_ASSERT_ACTIVE")); \
Serial.println(__LINE__); \
while (true) \
; \
} \
}
#define SPI_ASSERT_NOT_ACTIVE \
{ \
if (m_spiActive) { \
Serial.print(F("SPI_ASSERT_NOT_ACTIVE")); \
Serial.println(__LINE__); \
while (true) \
; \
} \
}
#else // CHECK_SPI_ACTIVE
/** Do not check SPI active. */
/** Check for SPI active. */
#define SPI_ASSERT_ACTIVE
/** Check for SPI not active. */
#define SPI_ASSERT_NOT_ACTIVE
#endif // CHECK_SPI_ACTIVE
//==============================================================================
/**
@@ -53,7 +71,7 @@
class SharedSpiCard : public SdCardInterface {
#elif USE_BLOCK_DEVICE_INTERFACE
class SharedSpiCard : public FsBlockDeviceInterface {
#else // HAS_SDIO_CLASS
#else // HAS_SDIO_CLASS
class SharedSpiCard {
#endif // HAS_SDIO_CLASS
public:
@@ -64,7 +82,7 @@ class SharedSpiCard {
/** SD is in multi-sector write state. */
static const uint8_t WRITE_STATE = 2;
/** Construct an instance of SharedSpiCard. */
SharedSpiCard() {}
SharedSpiCard() { initSharedSpiCard(); }
/** Initialize the SD card.
* \param[in] spiConfig SPI card configuration.
* \return true for success or false for failure.
@@ -103,21 +121,18 @@ class SharedSpiCard {
* \param[in] code value for error code.
*/
void error(uint8_t code) {
// (void)code;
// (void)code;
m_errorCode = code;
}
/**
* \return code for the last error. See SdCardInfo.h for a list of error codes.
* \return code for the last error. See SdCardInfo.h for a list of error
* codes.
*/
uint8_t errorCode() const {
return m_errorCode;
}
uint8_t errorCode() const { return m_errorCode; }
/** \return error data for last error. */
uint32_t errorData() const {
return m_status;
}
uint32_t errorData() const { return m_status; }
/** \return false for shared class. */
bool hasDedicatedSpi() {return false;}
bool hasDedicatedSpi() { return false; }
/**
* Check for busy. MISO low indicates the card is busy.
*
@@ -125,7 +140,7 @@ class SharedSpiCard {
*/
bool isBusy();
/** \return false, can't be in dedicated state. */
bool isDedicatedSpi() {return false;}
bool isDedicatedSpi() { return false; }
/**
* Read a card's CID register. The CID contains card identification
* information such as Manufacturer ID, Product name, Product serial
@@ -135,9 +150,7 @@ class SharedSpiCard {
*
* \return true for success or false for failure.
*/
bool readCID(cid_t* cid) {
return readRegister(CMD10, cid);
}
bool readCID(cid_t* cid) { return readRegister(CMD10, cid); }
/**
* Read a card's CSD register. The CSD contains Card-Specific Data that
* provides information regarding access to the card's contents.
@@ -146,9 +159,7 @@ class SharedSpiCard {
*
* \return true for success or false for failure.
*/
bool readCSD(csd_t* csd) {
return readRegister(CMD9, csd);
}
bool readCSD(csd_t* csd) { return readRegister(CMD9, csd); }
/** Read one data sector in a multiple sector read sequence
*
* \param[out] dst Pointer to the location for the data to be read.
@@ -196,18 +207,18 @@ class SharedSpiCard {
* \return true for success or false for failure.
*/
bool readStart(uint32_t sector);
/** Return the 64 byte card status
/** Return the 64 byte SD Status register.
* \param[out] status location for 64 status bytes.
* \return true for success or false for failure.
*/
bool readStatus(SdStatus* status);
bool readSDS(sds_t* status);
/** End a read multiple sectors sequence.
*
* \return true for success or false for failure.
*/
bool readStop();
/** \return SD multi-sector read/write state */
uint8_t sdState() {return m_state;}
uint8_t sdState() { return m_state; }
/**
* Determine the size of an SD flash memory card.
*
@@ -237,9 +248,7 @@ class SharedSpiCard {
/** Return the card type: SD V1, SD V2 or SDHC/SDXC
* \return 0 - SD V1, 1 - SD V2, or 3 - SDHC/SDXC.
*/
uint8_t type() const {
return m_type;
}
uint8_t type() const { return m_type; }
/**
* Write a 512 byte sector to an SD card.
*
@@ -288,32 +297,18 @@ class SharedSpiCard {
uint8_t cardCommand(uint8_t cmd, uint32_t arg);
bool readData(uint8_t* dst, size_t count);
bool readRegister(uint8_t cmd, void* buf);
void spiSelect() {
sdCsWrite(m_csPin, false);
}
void spiSelect() { sdCsWrite(m_csPin, false); }
void spiStart();
void spiStop();
void spiUnselect() {
sdCsWrite(m_csPin, true);
}
void type(uint8_t value) {
m_type = value;
}
void spiUnselect() { sdCsWrite(m_csPin, true); }
void type(uint8_t value) { m_type = value; }
bool waitReady(uint16_t ms);
bool writeData(uint8_t token, const uint8_t* src);
#if SPI_DRIVER_SELECT < 2
void spiActivate() {
m_spiDriver.activate();
}
void spiBegin(SdSpiConfig spiConfig) {
m_spiDriver.begin(spiConfig);
}
void spiDeactivate() {
m_spiDriver.deactivate();
}
void spiEnd() {
m_spiDriver.end();
}
void spiActivate() { m_spiDriver.activate(); }
void spiBegin(SdSpiConfig spiConfig) { m_spiDriver.begin(spiConfig); }
void spiDeactivate() { m_spiDriver.deactivate(); }
void spiEnd() { m_spiDriver.end(); }
uint8_t spiReceive() {
SPI_ASSERT_ACTIVE;
return m_spiDriver.receive();
@@ -330,23 +325,13 @@ class SharedSpiCard {
SPI_ASSERT_ACTIVE;
m_spiDriver.send(buf, n);
}
void spiSetSckSpeed(uint32_t maxSck) {
m_spiDriver.setSckSpeed(maxSck);
}
void spiSetSckSpeed(uint32_t maxSck) { m_spiDriver.setSckSpeed(maxSck); }
SdSpiDriver m_spiDriver;
#else // SPI_DRIVER_SELECT < 2
void spiActivate() {
m_spiDriverPtr->activate();
}
void spiBegin(SdSpiConfig spiConfig) {
m_spiDriverPtr->begin(spiConfig);
}
void spiDeactivate() {
m_spiDriverPtr->deactivate();
}
void spiEnd() {
m_spiDriverPtr->end();
}
void spiActivate() { m_spiDriverPtr->activate(); }
void spiBegin(SdSpiConfig spiConfig) { m_spiDriverPtr->begin(spiConfig); }
void spiDeactivate() { m_spiDriverPtr->deactivate(); }
void spiEnd() { m_spiDriverPtr->end(); }
uint8_t spiReceive() {
SPI_ASSERT_ACTIVE;
return m_spiDriverPtr->receive();
@@ -363,21 +348,27 @@ class SharedSpiCard {
SPI_ASSERT_ACTIVE;
m_spiDriverPtr->send(buf, n);
}
void spiSetSckSpeed(uint32_t maxSck) {
m_spiDriverPtr->setSckSpeed(maxSck);
}
void spiSetSckSpeed(uint32_t maxSck) { m_spiDriverPtr->setSckSpeed(maxSck); }
SdSpiDriver* m_spiDriverPtr;
#endif // SPI_DRIVER_SELECT < 2
bool m_beginCalled = false;
void initSharedSpiCard() {
m_beginCalled = false;
m_csPin = 0;
m_errorCode = SD_CARD_ERROR_INIT_NOT_CALLED;
m_spiActive = false;
m_state = IDLE_STATE;
m_status = 0;
m_type = 0;
}
bool m_beginCalled;
SdCsPin_t m_csPin;
uint8_t m_errorCode = SD_CARD_ERROR_INIT_NOT_CALLED;
bool m_spiActive;
uint8_t m_errorCode;
bool m_spiActive;
uint8_t m_state;
uint8_t m_status;
uint8_t m_type = 0;
uint8_t m_type;
};
//==============================================================================
/**
* \class DedicatedSpiCard
@@ -386,16 +377,16 @@ class SharedSpiCard {
class DedicatedSpiCard : public SharedSpiCard {
public:
/** Construct an instance of DedicatedSpiCard. */
DedicatedSpiCard() {}
DedicatedSpiCard() = default;
/** Initialize the SD card.
* \param[in] spiConfig SPI card configuration.
* \return true for success or false for failure.
*/
bool begin(SdSpiConfig spiConfig);
/** \return true, can be in dedicaded state. */
bool hasDedicatedSpi() {return true;}
bool hasDedicatedSpi() { return true; }
/** \return true if in dedicated SPI state. */
bool isDedicatedSpi() {return m_dedicatedSpi;}
bool isDedicatedSpi() { return m_dedicatedSpi; }
/**
* Read a 512 byte sector from an SD card.
*
@@ -437,7 +428,7 @@ class DedicatedSpiCard : public SharedSpiCard {
bool writeSectors(uint32_t sector, const uint8_t* src, size_t ns);
private:
uint32_t m_curSector;
uint32_t m_curSector = 0;
bool m_dedicatedSpi = false;
};
//==============================================================================

View File

@@ -22,12 +22,17 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/**
* \file
* \brief Classes for SDIO cards.
*/
#ifndef SdioCard_h
#define SdioCard_h
#include "../common/SysCall.h"
#include "SdCardInterface.h"
/** Use programmed I/O with FIFO. */
#define FIFO_SDIO 0
/** Use programmed I/O with DMA. */
#define DMA_SDIO 1
/**
* \class SdioConfig
@@ -42,9 +47,10 @@ class SdioConfig {
*/
explicit SdioConfig(uint8_t opt) : m_options(opt) {}
/** \return SDIO card options. */
uint8_t options() {return m_options;}
uint8_t options() { return m_options; }
/** \return true if DMA_SDIO. */
bool useDma() {return m_options & DMA_SDIO;}
bool useDma() { return m_options & DMA_SDIO; }
private:
uint8_t m_options = FIFO_SDIO;
};
@@ -73,7 +79,7 @@ class SdioCard : public SdCardInterface {
void end() {}
#ifndef DOXYGEN_SHOULD_SKIP_THIS
uint32_t __attribute__((error("use sectorCount()"))) cardSize();
uint32_t __attribute__((error("use sectorCount()"))) cardSize();
#endif // DOXYGEN_SHOULD_SKIP_THIS
/** Erase a range of sectors.
*
@@ -89,7 +95,8 @@ class SdioCard : public SdCardInterface {
*/
bool erase(uint32_t firstSector, uint32_t lastSector);
/**
* \return code for the last error. See SdCardInfo.h for a list of error codes.
* \return code for the last error. See SdCardInfo.h for a list of error
* codes.
*/
uint8_t errorCode() const;
/** \return error data for last error. */
@@ -158,7 +165,12 @@ class SdioCard : public SdCardInterface {
* \param[out] scr Value of SCR register.
* \return true for success or false for failure.
*/
bool readSCR(scr_t *scr);
bool readSCR(scr_t* scr);
/** Return the 64 byte SD Status register.
* \param[out] sds location for 64 status bytes.
* \return true for success or false for failure.
*/
bool readSDS(sds_t* sds);
/** Start a read multiple sectors sequence.
*
* \param[in] sector Address of first sector in sequence.
@@ -186,7 +198,7 @@ class SdioCard : public SdCardInterface {
bool readStop();
/** \return SDIO card status. */
uint32_t status();
/**
/**
* Determine the size of an SD flash memory card.
*
* \return The number of 512 byte data sectors in the card

View File

@@ -24,6 +24,7 @@
*/
#if defined(__MK64FX512__) || defined(__MK66FX1M0__) || defined(__IMXRT1062__)
#include "SdioTeensy.h"
#include "SdCardInfo.h"
#include "SdioCard.h"
//==============================================================================
@@ -36,39 +37,34 @@ const uint32_t CMD8_RETRIES = 3;
const uint32_t BUSY_TIMEOUT_MICROS = 1000000;
//==============================================================================
const uint32_t SDHC_IRQSTATEN_MASK =
SDHC_IRQSTATEN_DMAESEN | SDHC_IRQSTATEN_AC12ESEN |
SDHC_IRQSTATEN_DEBESEN | SDHC_IRQSTATEN_DCESEN |
SDHC_IRQSTATEN_DTOESEN | SDHC_IRQSTATEN_CIESEN |
SDHC_IRQSTATEN_CEBESEN | SDHC_IRQSTATEN_CCESEN |
SDHC_IRQSTATEN_CTOESEN | SDHC_IRQSTATEN_DINTSEN |
SDHC_IRQSTATEN_TCSEN | SDHC_IRQSTATEN_CCSEN;
SDHC_IRQSTATEN_DMAESEN | SDHC_IRQSTATEN_AC12ESEN | SDHC_IRQSTATEN_DEBESEN |
SDHC_IRQSTATEN_DCESEN | SDHC_IRQSTATEN_DTOESEN | SDHC_IRQSTATEN_CIESEN |
SDHC_IRQSTATEN_CEBESEN | SDHC_IRQSTATEN_CCESEN | SDHC_IRQSTATEN_CTOESEN |
SDHC_IRQSTATEN_DINTSEN | SDHC_IRQSTATEN_TCSEN | SDHC_IRQSTATEN_CCSEN;
const uint32_t SDHC_IRQSTAT_CMD_ERROR =
SDHC_IRQSTAT_CIE | SDHC_IRQSTAT_CEBE |
SDHC_IRQSTAT_CCE | SDHC_IRQSTAT_CTOE;
SDHC_IRQSTAT_CIE | SDHC_IRQSTAT_CEBE | SDHC_IRQSTAT_CCE | SDHC_IRQSTAT_CTOE;
const uint32_t SDHC_IRQSTAT_DATA_ERROR =
SDHC_IRQSTAT_AC12E | SDHC_IRQSTAT_DEBE |
SDHC_IRQSTAT_DCE | SDHC_IRQSTAT_DTOE;
const uint32_t SDHC_IRQSTAT_DATA_ERROR = SDHC_IRQSTAT_AC12E |
SDHC_IRQSTAT_DEBE | SDHC_IRQSTAT_DCE |
SDHC_IRQSTAT_DTOE;
const uint32_t SDHC_IRQSTAT_ERROR =
SDHC_IRQSTAT_DMAE | SDHC_IRQSTAT_CMD_ERROR |
SDHC_IRQSTAT_DATA_ERROR;
SDHC_IRQSTAT_DMAE | SDHC_IRQSTAT_CMD_ERROR | SDHC_IRQSTAT_DATA_ERROR;
const uint32_t SDHC_IRQSIGEN_MASK =
SDHC_IRQSIGEN_DMAEIEN | SDHC_IRQSIGEN_AC12EIEN |
SDHC_IRQSIGEN_DEBEIEN | SDHC_IRQSIGEN_DCEIEN |
SDHC_IRQSIGEN_DTOEIEN | SDHC_IRQSIGEN_CIEIEN |
SDHC_IRQSIGEN_CEBEIEN | SDHC_IRQSIGEN_CCEIEN |
SDHC_IRQSIGEN_CTOEIEN | SDHC_IRQSIGEN_TCIEN;
SDHC_IRQSIGEN_DMAEIEN | SDHC_IRQSIGEN_AC12EIEN | SDHC_IRQSIGEN_DEBEIEN |
SDHC_IRQSIGEN_DCEIEN | SDHC_IRQSIGEN_DTOEIEN | SDHC_IRQSIGEN_CIEIEN |
SDHC_IRQSIGEN_CEBEIEN | SDHC_IRQSIGEN_CCEIEN | SDHC_IRQSIGEN_CTOEIEN |
SDHC_IRQSIGEN_TCIEN;
//==============================================================================
const uint32_t CMD_RESP_NONE = SDHC_XFERTYP_RSPTYP(0);
const uint32_t CMD_RESP_R1 = SDHC_XFERTYP_CICEN | SDHC_XFERTYP_CCCEN |
SDHC_XFERTYP_RSPTYP(2);
const uint32_t CMD_RESP_R1 =
SDHC_XFERTYP_CICEN | SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(2);
const uint32_t CMD_RESP_R1b = SDHC_XFERTYP_CICEN | SDHC_XFERTYP_CCCEN |
SDHC_XFERTYP_RSPTYP(3);
const uint32_t CMD_RESP_R1b =
SDHC_XFERTYP_CICEN | SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(3);
const uint32_t CMD_RESP_R2 = SDHC_XFERTYP_CCCEN | SDHC_XFERTYP_RSPTYP(1);
@@ -86,26 +82,23 @@ const uint32_t DATA_READ_DMA = DATA_READ | SDHC_XFERTYP_DMAEN;
const uint32_t DATA_READ_MULTI_DMA = DATA_READ_DMA | SDHC_XFERTYP_MSBSEL |
SDHC_XFERTYP_AC12EN | SDHC_XFERTYP_BCEN;
const uint32_t DATA_READ_MULTI_PGM = DATA_READ | SDHC_XFERTYP_MSBSEL |
SDHC_XFERTYP_BCEN;
const uint32_t DATA_READ_MULTI_PGM =
DATA_READ | SDHC_XFERTYP_MSBSEL | SDHC_XFERTYP_BCEN;
const uint32_t DATA_WRITE_DMA = SDHC_XFERTYP_DPSEL | SDHC_XFERTYP_DMAEN;
const uint32_t DATA_WRITE_MULTI_DMA = DATA_WRITE_DMA | SDHC_XFERTYP_MSBSEL |
SDHC_XFERTYP_AC12EN | SDHC_XFERTYP_BCEN;
const uint32_t DATA_WRITE_MULTI_PGM = SDHC_XFERTYP_DPSEL | SDHC_XFERTYP_MSBSEL |
SDHC_XFERTYP_BCEN;
const uint32_t DATA_WRITE_MULTI_PGM =
SDHC_XFERTYP_DPSEL | SDHC_XFERTYP_MSBSEL | SDHC_XFERTYP_BCEN;
#elif defined(__IMXRT1062__)
// Use low bits for SDHC_MIX_CTRL since bits 15-0 of SDHC_XFERTYP are reserved.
const uint32_t SDHC_MIX_CTRL_MASK = SDHC_MIX_CTRL_DMAEN | SDHC_MIX_CTRL_BCEN |
SDHC_MIX_CTRL_AC12EN |
SDHC_MIX_CTRL_DDR_EN |
SDHC_MIX_CTRL_DTDSEL |
SDHC_MIX_CTRL_MSBSEL |
SDHC_MIX_CTRL_NIBBLE_POS |
SDHC_MIX_CTRL_AC23EN;
const uint32_t SDHC_MIX_CTRL_MASK =
SDHC_MIX_CTRL_DMAEN | SDHC_MIX_CTRL_BCEN | SDHC_MIX_CTRL_AC12EN |
SDHC_MIX_CTRL_DDR_EN | SDHC_MIX_CTRL_DTDSEL | SDHC_MIX_CTRL_MSBSEL |
SDHC_MIX_CTRL_NIBBLE_POS | SDHC_MIX_CTRL_AC23EN;
const uint32_t DATA_READ = SDHC_MIX_CTRL_DTDSEL | SDHC_XFERTYP_DPSEL;
@@ -116,7 +109,6 @@ const uint32_t DATA_READ_MULTI_DMA = DATA_READ_DMA | SDHC_MIX_CTRL_MSBSEL |
const uint32_t DATA_READ_MULTI_PGM = DATA_READ | SDHC_MIX_CTRL_MSBSEL;
const uint32_t DATA_WRITE_DMA = SDHC_XFERTYP_DPSEL | SDHC_MIX_CTRL_DMAEN;
const uint32_t DATA_WRITE_MULTI_DMA = DATA_WRITE_DMA | SDHC_MIX_CTRL_MSBSEL |
@@ -128,10 +120,13 @@ const uint32_t DATA_WRITE_MULTI_PGM = SDHC_XFERTYP_DPSEL | SDHC_MIX_CTRL_MSBSEL;
const uint32_t ACMD6_XFERTYP = SDHC_XFERTYP_CMDINX(ACMD6) | CMD_RESP_R1;
const uint32_t ACMD13_XFERTYP =
SDHC_XFERTYP_CMDINX(ACMD13) | CMD_RESP_R1 | DATA_READ_DMA;
const uint32_t ACMD41_XFERTYP = SDHC_XFERTYP_CMDINX(ACMD41) | CMD_RESP_R3;
const uint32_t ACMD51_XFERTYP = SDHC_XFERTYP_CMDINX(ACMD51) | CMD_RESP_R1 |
DATA_READ_DMA;
const uint32_t ACMD51_XFERTYP =
SDHC_XFERTYP_CMDINX(ACMD51) | CMD_RESP_R1 | DATA_READ_DMA;
const uint32_t CMD0_XFERTYP = SDHC_XFERTYP_CMDINX(CMD0) | CMD_RESP_NONE;
@@ -139,8 +134,8 @@ const uint32_t CMD2_XFERTYP = SDHC_XFERTYP_CMDINX(CMD2) | CMD_RESP_R2;
const uint32_t CMD3_XFERTYP = SDHC_XFERTYP_CMDINX(CMD3) | CMD_RESP_R6;
const uint32_t CMD6_XFERTYP = SDHC_XFERTYP_CMDINX(CMD6) | CMD_RESP_R1 |
DATA_READ_DMA;
const uint32_t CMD6_XFERTYP =
SDHC_XFERTYP_CMDINX(CMD6) | CMD_RESP_R1 | DATA_READ_DMA;
const uint32_t CMD7_XFERTYP = SDHC_XFERTYP_CMDINX(CMD7) | CMD_RESP_R1b;
@@ -152,28 +147,28 @@ const uint32_t CMD10_XFERTYP = SDHC_XFERTYP_CMDINX(CMD10) | CMD_RESP_R2;
const uint32_t CMD11_XFERTYP = SDHC_XFERTYP_CMDINX(CMD11) | CMD_RESP_R1;
const uint32_t CMD12_XFERTYP = SDHC_XFERTYP_CMDINX(CMD12) | CMD_RESP_R1b |
SDHC_XFERTYP_CMDTYP(3);
const uint32_t CMD12_XFERTYP =
SDHC_XFERTYP_CMDINX(CMD12) | CMD_RESP_R1b | SDHC_XFERTYP_CMDTYP(3);
const uint32_t CMD13_XFERTYP = SDHC_XFERTYP_CMDINX(CMD13) | CMD_RESP_R1;
const uint32_t CMD17_DMA_XFERTYP = SDHC_XFERTYP_CMDINX(CMD17) | CMD_RESP_R1 |
DATA_READ_DMA;
const uint32_t CMD17_DMA_XFERTYP =
SDHC_XFERTYP_CMDINX(CMD17) | CMD_RESP_R1 | DATA_READ_DMA;
const uint32_t CMD18_DMA_XFERTYP = SDHC_XFERTYP_CMDINX(CMD18) | CMD_RESP_R1 |
DATA_READ_MULTI_DMA;
const uint32_t CMD18_DMA_XFERTYP =
SDHC_XFERTYP_CMDINX(CMD18) | CMD_RESP_R1 | DATA_READ_MULTI_DMA;
const uint32_t CMD18_PGM_XFERTYP = SDHC_XFERTYP_CMDINX(CMD18) | CMD_RESP_R1 |
DATA_READ_MULTI_PGM;
const uint32_t CMD18_PGM_XFERTYP =
SDHC_XFERTYP_CMDINX(CMD18) | CMD_RESP_R1 | DATA_READ_MULTI_PGM;
const uint32_t CMD24_DMA_XFERTYP = SDHC_XFERTYP_CMDINX(CMD24) | CMD_RESP_R1 |
DATA_WRITE_DMA;
const uint32_t CMD24_DMA_XFERTYP =
SDHC_XFERTYP_CMDINX(CMD24) | CMD_RESP_R1 | DATA_WRITE_DMA;
const uint32_t CMD25_DMA_XFERTYP = SDHC_XFERTYP_CMDINX(CMD25) | CMD_RESP_R1 |
DATA_WRITE_MULTI_DMA;
const uint32_t CMD25_DMA_XFERTYP =
SDHC_XFERTYP_CMDINX(CMD25) | CMD_RESP_R1 | DATA_WRITE_MULTI_DMA;
const uint32_t CMD25_PGM_XFERTYP = SDHC_XFERTYP_CMDINX(CMD25) | CMD_RESP_R1 |
DATA_WRITE_MULTI_PGM;
const uint32_t CMD25_PGM_XFERTYP =
SDHC_XFERTYP_CMDINX(CMD25) | CMD_RESP_R1 | DATA_WRITE_MULTI_PGM;
const uint32_t CMD32_XFERTYP = SDHC_XFERTYP_CMDINX(CMD32) | CMD_RESP_R1;
@@ -212,12 +207,20 @@ static uint32_t m_ocr;
static cid_t m_cid;
static csd_t m_csd;
static scr_t m_scr;
static sds_t m_sds;
//==============================================================================
#define DBG_TRACE Serial.print("TRACE."); Serial.println(__LINE__); delay(200);
#define DBG_TRACE \
Serial.print("TRACE."); \
Serial.println(__LINE__); \
delay(200);
#define USE_DEBUG_MODE 0
#if USE_DEBUG_MODE
#define DBG_IRQSTAT() if (SDHC_IRQSTAT) {Serial.print(__LINE__);\
Serial.print(" IRQSTAT "); Serial.println(SDHC_IRQSTAT, HEX);}
#define DBG_IRQSTAT() \
if (SDHC_IRQSTAT) { \
Serial.print(__LINE__); \
Serial.print(" IRQSTAT "); \
Serial.println(SDHC_IRQSTAT, HEX); \
}
static void printRegs(uint32_t line) {
uint32_t blkattr = SDHC_BLKATTR;
uint32_t xfertyp = SDHC_XFERTYP;
@@ -234,36 +237,68 @@ static void printRegs(uint32_t line) {
Serial.print(xfertyp >> 24);
Serial.print(" TYP");
Serial.print((xfertyp >> 2) & 3);
if (xfertyp & SDHC_XFERTYP_DPSEL) {Serial.print(" DPSEL");}
if (xfertyp & SDHC_XFERTYP_DPSEL) {
Serial.print(" DPSEL");
}
Serial.println();
Serial.print("PRSSTAT ");
Serial.print(prsstat, HEX);
if (prsstat & SDHC_PRSSTAT_BREN) {Serial.print(" BREN");}
if (prsstat & SDHC_PRSSTAT_BWEN) {Serial.print(" BWEN");}
if (prsstat & SDHC_PRSSTAT_RTA) {Serial.print(" RTA");}
if (prsstat & SDHC_PRSSTAT_WTA) {Serial.print(" WTA");}
if (prsstat & SDHC_PRSSTAT_SDOFF) {Serial.print(" SDOFF");}
if (prsstat & SDHC_PRSSTAT_PEROFF) {Serial.print(" PEROFF");}
if (prsstat & SDHC_PRSSTAT_HCKOFF) {Serial.print(" HCKOFF");}
if (prsstat & SDHC_PRSSTAT_IPGOFF) {Serial.print(" IPGOFF");}
if (prsstat & SDHC_PRSSTAT_SDSTB) {Serial.print(" SDSTB");}
if (prsstat & SDHC_PRSSTAT_DLA) {Serial.print(" DLA");}
if (prsstat & SDHC_PRSSTAT_CDIHB) {Serial.print(" CDIHB");}
if (prsstat & SDHC_PRSSTAT_CIHB) {Serial.print(" CIHB");}
if (prsstat & SDHC_PRSSTAT_BREN) {
Serial.print(" BREN");
}
if (prsstat & SDHC_PRSSTAT_BWEN) {
Serial.print(" BWEN");
}
if (prsstat & SDHC_PRSSTAT_RTA) {
Serial.print(" RTA");
}
if (prsstat & SDHC_PRSSTAT_WTA) {
Serial.print(" WTA");
}
if (prsstat & SDHC_PRSSTAT_SDOFF) {
Serial.print(" SDOFF");
}
if (prsstat & SDHC_PRSSTAT_PEROFF) {
Serial.print(" PEROFF");
}
if (prsstat & SDHC_PRSSTAT_HCKOFF) {
Serial.print(" HCKOFF");
}
if (prsstat & SDHC_PRSSTAT_IPGOFF) {
Serial.print(" IPGOFF");
}
if (prsstat & SDHC_PRSSTAT_SDSTB) {
Serial.print(" SDSTB");
}
if (prsstat & SDHC_PRSSTAT_DLA) {
Serial.print(" DLA");
}
if (prsstat & SDHC_PRSSTAT_CDIHB) {
Serial.print(" CDIHB");
}
if (prsstat & SDHC_PRSSTAT_CIHB) {
Serial.print(" CIHB");
}
Serial.println();
Serial.print("PROCTL ");
Serial.print(proctl, HEX);
if (proctl & SDHC_PROCTL_SABGREQ) Serial.print(" SABGREQ");
Serial.print(" EMODE");
Serial.print((proctl >>4) & 3);
Serial.print((proctl >> 4) & 3);
Serial.print(" DWT");
Serial.print((proctl >>1) & 3);
Serial.print((proctl >> 1) & 3);
Serial.println();
Serial.print("IRQSTAT ");
Serial.print(irqstat, HEX);
if (irqstat & SDHC_IRQSTAT_BGE) {Serial.print(" BGE");}
if (irqstat & SDHC_IRQSTAT_TC) {Serial.print(" TC");}
if (irqstat & SDHC_IRQSTAT_CC) {Serial.print(" CC");}
if (irqstat & SDHC_IRQSTAT_BGE) {
Serial.print(" BGE");
}
if (irqstat & SDHC_IRQSTAT_TC) {
Serial.print(" TC");
}
if (irqstat & SDHC_IRQSTAT_CC) {
Serial.print(" CC");
}
Serial.print("\nm_irqstat ");
Serial.println(m_irqstat, HEX);
}
@@ -298,12 +333,12 @@ static void sdIrs() {
//------------------------------------------------------------------------------
static void enableGPIO(bool enable) {
const uint32_t PORT_CLK = PORT_PCR_MUX(4) | PORT_PCR_DSE;
const uint32_t PORT_CMD_DATA = PORT_CLK | PORT_PCR_PE | PORT_PCR_PS;
const uint32_t PORT_CMD_DATA = PORT_CLK | PORT_PCR_PE | PORT_PCR_PS;
const uint32_t PORT_PUP = PORT_PCR_MUX(1) | PORT_PCR_PE | PORT_PCR_PS;
PORTE_PCR0 = enable ? PORT_CMD_DATA : PORT_PUP; // SDHC_D1
PORTE_PCR1 = enable ? PORT_CMD_DATA : PORT_PUP; // SDHC_D0
PORTE_PCR2 = enable ? PORT_CLK : PORT_PUP; // SDHC_CLK
PORTE_PCR2 = enable ? PORT_CLK : PORT_PUP; // SDHC_CLK
PORTE_PCR3 = enable ? PORT_CMD_DATA : PORT_PUP; // SDHC_CMD
PORTE_PCR4 = enable ? PORT_CMD_DATA : PORT_PUP; // SDHC_D3
PORTE_PCR5 = enable ? PORT_CMD_DATA : PORT_PUP; // SDHC_D2
@@ -317,7 +352,7 @@ static void initClock() {
// Enable SDHC clock.
SIM_SCGC3 |= SIM_SCGC3_SDHC;
}
static uint32_t baseClock() { return F_CPU;}
static uint32_t baseClock() { return F_CPU; }
#elif defined(__IMXRT1062__)
//------------------------------------------------------------------------------
@@ -335,13 +370,13 @@ static void enableGPIO(bool enable) {
const uint32_t CLOCK_MASK = IOMUXC_SW_PAD_CTL_PAD_PKE |
#if defined(ARDUINO_TEENSY41)
IOMUXC_SW_PAD_CTL_PAD_DSE(7) |
#else // defined(ARDUINO_TEENSY41)
#else // defined(ARDUINO_TEENSY41)
IOMUXC_SW_PAD_CTL_PAD_DSE(4) | ///// WHG
#endif // defined(ARDUINO_TEENSY41)
IOMUXC_SW_PAD_CTL_PAD_SPEED(2);
const uint32_t DATA_MASK = CLOCK_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE |
IOMUXC_SW_PAD_CTL_PAD_PUS(1);
const uint32_t DATA_MASK =
CLOCK_MASK | IOMUXC_SW_PAD_CTL_PAD_PUE | IOMUXC_SW_PAD_CTL_PAD_PUS(1);
if (enable) {
gpioMux(0);
IOMUXC_SW_PAD_CTL_PAD_GPIO_SD_B0_04 = DATA_MASK; // DAT2
@@ -365,20 +400,20 @@ static void initClock() {
/* Enable USDHC clock. */
CCM_CCGR6 |= CCM_CCGR6_USDHC1(CCM_CCGR_ON);
CCM_CSCDR1 &= ~(CCM_CSCDR1_USDHC1_CLK_PODF_MASK);
CCM_CSCMR1 |= CCM_CSCMR1_USDHC1_CLK_SEL; // PLL2PFD0
// CCM_CSCDR1 |= CCM_CSCDR1_USDHC1_CLK_PODF((7)); / &0x7 WHG
CCM_CSCMR1 |= CCM_CSCMR1_USDHC1_CLK_SEL; // PLL2PFD0
// CCM_CSCDR1 |= CCM_CSCDR1_USDHC1_CLK_PODF((7)); / &0x7 WHG
CCM_CSCDR1 |= CCM_CSCDR1_USDHC1_CLK_PODF((1));
}
//------------------------------------------------------------------------------
static uint32_t baseClock() {
uint32_t divider = ((CCM_CSCDR1 >> 11) & 0x7) + 1;
return (528000000U * 3)/((CCM_ANALOG_PFD_528 & 0x3F)/6)/divider;
return (528000000U * 3) / ((CCM_ANALOG_PFD_528 & 0x3F) / 6) / divider;
}
#endif // defined(__MK64FX512__) || defined(__MK66FX1M0__)
//==============================================================================
// Static functions.
static bool cardAcmd(uint32_t rca, uint32_t xfertyp, uint32_t arg) {
return cardCommand(CMD55_XFERTYP, rca) && cardCommand (xfertyp, arg);
return cardCommand(CMD55_XFERTYP, rca) && cardCommand(xfertyp, arg);
}
//------------------------------------------------------------------------------
static bool cardCommand(uint32_t xfertyp, uint32_t arg) {
@@ -402,8 +437,25 @@ static bool cardCommand(uint32_t xfertyp, uint32_t arg) {
m_irqstat = SDHC_IRQSTAT;
SDHC_IRQSTAT = m_irqstat;
return (m_irqstat & SDHC_IRQSTAT_CC) &&
!(m_irqstat & SDHC_IRQSTAT_CMD_ERROR);
return (m_irqstat & SDHC_IRQSTAT_CC) && !(m_irqstat & SDHC_IRQSTAT_CMD_ERROR);
}
//------------------------------------------------------------------------------
static bool cardACMD13(sds_t* scr) {
// ACMD13 returns 64 bytes.
if (waitTimeout(isBusyCMD13)) {
return sdError(SD_CARD_ERROR_CMD13);
}
enableDmaIrs();
SDHC_DSADDR = (uint32_t)scr;
SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(64);
SDHC_IRQSIGEN = SDHC_IRQSIGEN_MASK;
if (!cardAcmd(m_rca, ACMD13_XFERTYP, 0)) {
return sdError(SD_CARD_ERROR_ACMD13);
}
if (!waitDmaStatus()) {
return sdError(SD_CARD_ERROR_DMA);
}
return true;
}
//------------------------------------------------------------------------------
static bool cardACMD51(scr_t* scr) {
@@ -412,7 +464,7 @@ static bool cardACMD51(scr_t* scr) {
return sdError(SD_CARD_ERROR_CMD13);
}
enableDmaIrs();
SDHC_DSADDR = (uint32_t)scr;
SDHC_DSADDR = (uint32_t)scr;
SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(8);
SDHC_IRQSIGEN = SDHC_IRQSIGEN_MASK;
if (!cardAcmd(m_rca, ACMD51_XFERTYP, 0)) {
@@ -435,7 +487,7 @@ static void initSDHC() {
// Disable GPIO clock.
enableGPIO(false);
#if defined (__IMXRT1062__)
#if defined(__IMXRT1062__)
SDHC_MIX_CTRL |= 0x80000000;
#endif // (__IMXRT1062__)
@@ -454,7 +506,7 @@ static void initSDHC() {
SDHC_IRQSTATEN = SDHC_IRQSTATEN_MASK;
attachInterruptVector(IRQ_SDHC, sdIrs);
NVIC_SET_PRIORITY(IRQ_SDHC, 6*16);
NVIC_SET_PRIORITY(IRQ_SDHC, 6 * 16);
NVIC_ENABLE_IRQ(IRQ_SDHC);
// Send 80 clocks to card.
@@ -475,32 +527,22 @@ static bool isBusyCommandComplete() {
return !(SDHC_IRQSTAT & (SDHC_IRQSTAT_CC | SDHC_IRQSTAT_CMD_ERROR));
}
//------------------------------------------------------------------------------
static bool isBusyCommandInhibit() {
return SDHC_PRSSTAT & SDHC_PRSSTAT_CIHB;
}
static bool isBusyCommandInhibit() { return SDHC_PRSSTAT & SDHC_PRSSTAT_CIHB; }
//------------------------------------------------------------------------------
static bool isBusyDat() {
return SDHC_PRSSTAT & (1 << 24) ? false : true;
}
static bool isBusyDat() { return SDHC_PRSSTAT & (1 << 24) ? false : true; }
//------------------------------------------------------------------------------
static bool isBusyDMA() {
return m_dmaBusy;
}
static bool isBusyDMA() { return m_dmaBusy; }
//------------------------------------------------------------------------------
static bool isBusyFifoRead() {
return !(SDHC_PRSSTAT & SDHC_PRSSTAT_BREN);
}
static bool isBusyFifoRead() { return !(SDHC_PRSSTAT & SDHC_PRSSTAT_BREN); }
//------------------------------------------------------------------------------
static bool isBusyFifoWrite() {
return !(SDHC_PRSSTAT & SDHC_PRSSTAT_BWEN);
}
static bool isBusyFifoWrite() { return !(SDHC_PRSSTAT & SDHC_PRSSTAT_BWEN); }
//------------------------------------------------------------------------------
static bool isBusyTransferComplete() {
return !(SDHC_IRQSTAT & (SDHC_IRQSTAT_TC | SDHC_IRQSTAT_ERROR));
}
//------------------------------------------------------------------------------
static bool rdWrSectors(uint32_t xfertyp,
uint32_t sector, uint8_t* buf, size_t n) {
static bool rdWrSectors(uint32_t xfertyp, uint32_t sector, uint8_t* buf,
size_t n) {
if ((3 & (uint32_t)buf) || n == 0) {
return sdError(SD_CARD_ERROR_DMA);
}
@@ -508,10 +550,10 @@ static bool rdWrSectors(uint32_t xfertyp,
return sdError(SD_CARD_ERROR_CMD13);
}
enableDmaIrs();
SDHC_DSADDR = (uint32_t)buf;
SDHC_DSADDR = (uint32_t)buf;
SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(n) | SDHC_BLKATTR_BLKSIZE(512);
SDHC_IRQSIGEN = SDHC_IRQSIGEN_MASK;
if (!cardCommand(xfertyp, m_highCapacity ? sector : 512*sector)) {
if (!cardCommand(xfertyp, m_highCapacity ? sector : 512 * sector)) {
return false;
}
return waitDmaStatus();
@@ -525,7 +567,7 @@ static bool readReg16(uint32_t xfertyp, void* data) {
}
uint32_t sr[] = {SDHC_CMDRSP0, SDHC_CMDRSP1, SDHC_CMDRSP2, SDHC_CMDRSP3};
for (int i = 0; i < 15; i++) {
d[14 - i] = sr[i/4] >> 8*(i%4);
d[14 - i] = sr[i / 4] >> 8 * (i % 4);
}
d[15] = 0;
return true;
@@ -536,16 +578,17 @@ static void setSdclk(uint32_t kHzMax) {
const uint32_t SDCLKFS_LIMIT = 0X100;
uint32_t dvs = 1;
uint32_t sdclkfs = 1;
uint32_t maxSdclk = 1000*kHzMax;
uint32_t maxSdclk = 1000 * kHzMax;
uint32_t base = baseClock();
while ((base/(sdclkfs*DVS_LIMIT) > maxSdclk) && (sdclkfs < SDCLKFS_LIMIT)) {
while ((base / (sdclkfs * DVS_LIMIT) > maxSdclk) &&
(sdclkfs < SDCLKFS_LIMIT)) {
sdclkfs <<= 1;
}
while ((base/(sdclkfs*dvs) > maxSdclk) && (dvs < DVS_LIMIT)) {
while ((base / (sdclkfs * dvs) > maxSdclk) && (dvs < DVS_LIMIT)) {
dvs++;
}
m_sdClkKhz = base/(1000*sdclkfs*dvs);
m_sdClkKhz = base / (1000 * sdclkfs * dvs);
sdclkfs >>= 1;
dvs--;
#if defined(__MK64FX512__) || defined(__MK66FX1M0__)
@@ -554,11 +597,12 @@ static void setSdclk(uint32_t kHzMax) {
#endif // defined(__MK64FX512__) || defined(__MK66FX1M0__)
// Change dividers.
uint32_t sysctl = SDHC_SYSCTL & ~(SDHC_SYSCTL_DTOCV_MASK
| SDHC_SYSCTL_DVS_MASK | SDHC_SYSCTL_SDCLKFS_MASK);
uint32_t sysctl =
SDHC_SYSCTL & ~(SDHC_SYSCTL_DTOCV_MASK | SDHC_SYSCTL_DVS_MASK |
SDHC_SYSCTL_SDCLKFS_MASK);
SDHC_SYSCTL = sysctl | SDHC_SYSCTL_DTOCV(0x0E) | SDHC_SYSCTL_DVS(dvs)
| SDHC_SYSCTL_SDCLKFS(sdclkfs);
SDHC_SYSCTL = sysctl | SDHC_SYSCTL_DTOCV(0x0E) | SDHC_SYSCTL_DVS(dvs) |
SDHC_SYSCTL_SDCLKFS(sdclkfs);
// Wait until the SDHC clock is stable.
while (!(SDHC_PRSSTAT & SDHC_PRSSTAT_SDSTB)) {
@@ -667,14 +711,15 @@ bool SdioCard::begin(SdioConfig sdioConfig) {
break;
}
SDHC_SYSCTL |= SDHC_SYSCTL_RSTA;
while (SDHC_SYSCTL & SDHC_SYSCTL_RSTA) {}
while (SDHC_SYSCTL & SDHC_SYSCTL_RSTA) {
}
}
// Must support 3.2-3.4 Volts
arg = m_version2 ? 0X40300000 : 0x00300000;
int m = micros();
do {
if (!cardAcmd(0, ACMD41_XFERTYP, arg) ||
((micros() - m) > BUSY_TIMEOUT_MICROS)) {
((micros() - m) > BUSY_TIMEOUT_MICROS)) {
return sdError(SD_CARD_ERROR_ACMD41);
}
} while ((SDHC_CMDRSP0 & 0x80000000) == 0);
@@ -713,11 +758,13 @@ bool SdioCard::begin(SdioConfig sdioConfig) {
if (!cardACMD51(&m_scr)) {
return false;
}
if (!cardACMD13(&m_sds)) {
return false;
}
// Determine if High Speed mode is supported and set frequency.
// Check status[16] for error 0XF or status[16] for new mode 0X1.
uint8_t status[64];
if (m_scr.sdSpec() > 0 &&
cardCMD6(0X00FFFFFF, status) && (2 & status[13]) &&
if (m_scr.sdSpec() > 0 && cardCMD6(0X00FFFFFF, status) && (2 & status[13]) &&
cardCMD6(0X80FFFFF1, status) && (status[16] & 0XF) == 1) {
kHzSdClk = 50000;
} else {
@@ -741,7 +788,7 @@ bool SdioCard::cardCMD6(uint32_t arg, uint8_t* status) {
return sdError(SD_CARD_ERROR_CMD13);
}
enableDmaIrs();
SDHC_DSADDR = (uint32_t)status;
SDHC_DSADDR = (uint32_t)status;
SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(1) | SDHC_BLKATTR_BLKSIZE(64);
SDHC_IRQSIGEN = SDHC_IRQSIGEN_MASK;
if (!cardCommand(CMD6_XFERTYP, arg)) {
@@ -774,7 +821,7 @@ bool SdioCard::erase(uint32_t firstSector, uint32_t lastSector) {
return sdError(SD_CARD_ERROR_CMD32);
}
if (!cardCommand(CMD33_XFERTYP, lastSector)) {
return sdError(SD_CARD_ERROR_CMD33);
return sdError(SD_CARD_ERROR_CMD33);
}
if (!cardCommand(CMD38_XFERTYP, 0)) {
return sdError(SD_CARD_ERROR_CMD38);
@@ -785,17 +832,11 @@ bool SdioCard::erase(uint32_t firstSector, uint32_t lastSector) {
return true;
}
//------------------------------------------------------------------------------
uint8_t SdioCard::errorCode() const {
return m_errorCode;
}
uint8_t SdioCard::errorCode() const { return m_errorCode; }
//------------------------------------------------------------------------------
uint32_t SdioCard::errorData() const {
return m_irqstat;
}
uint32_t SdioCard::errorData() const { return m_irqstat; }
//------------------------------------------------------------------------------
uint32_t SdioCard::errorLine() const {
return m_errorLine;
}
uint32_t SdioCard::errorLine() const { return m_errorLine; }
//------------------------------------------------------------------------------
bool SdioCard::isBusy() {
if (m_sdioConfig.useDma()) {
@@ -812,7 +853,7 @@ bool SdioCard::isBusy() {
m_transferActive = false;
stopTransmission(false);
return true;
#else // defined(__MK64FX512__) || defined(__MK66FX1M0__)
#else // defined(__MK64FX512__) || defined(__MK66FX1M0__)
return false;
#endif // defined(__MK64FX512__) || defined(__MK66FX1M0__)
}
@@ -821,17 +862,15 @@ bool SdioCard::isBusy() {
}
}
//------------------------------------------------------------------------------
uint32_t SdioCard::kHzSdClk() {
return m_sdClkKhz;
}
uint32_t SdioCard::kHzSdClk() { return m_sdClkKhz; }
//------------------------------------------------------------------------------
bool SdioCard::readCID(cid_t* cid) {
memcpy(cid, &m_cid, 16);
memcpy(cid, &m_cid, sizeof(cid_t));
return true;
}
//------------------------------------------------------------------------------
bool SdioCard::readCSD(csd_t* csd) {
memcpy(csd, &m_csd, 16);
memcpy(csd, &m_csd, sizeof(csd_t));
return true;
}
//------------------------------------------------------------------------------
@@ -849,7 +888,7 @@ bool SdioCard::readData(uint8_t* dst) {
if (waitTimeout(isBusyFifoRead)) {
return sdError(SD_CARD_ERROR_READ_FIFO);
}
for (uint32_t iw = 0 ; iw < 512/(4*FIFO_WML); iw++) {
for (uint32_t iw = 0; iw < 512 / (4 * FIFO_WML); iw++) {
while (0 == (SDHC_PRSSTAT & SDHC_PRSSTAT_BREN)) {
}
for (uint32_t i = 0; i < FIFO_WML; i++) {
@@ -871,7 +910,12 @@ bool SdioCard::readOCR(uint32_t* ocr) {
}
//------------------------------------------------------------------------------
bool SdioCard::readSCR(scr_t* scr) {
memcpy(scr, &m_scr, 8);
memcpy(scr, &m_scr, sizeof(scr_t));
return true;
}
//------------------------------------------------------------------------------
bool SdioCard::readSDS(sds_t* sds) {
memcpy(sds, &m_sds, sizeof(sds_t));
return true;
}
//------------------------------------------------------------------------------
@@ -931,7 +975,7 @@ bool SdioCard::readSectors(uint32_t sector, uint8_t* dst, size_t n) {
}
} else {
for (size_t i = 0; i < n; i++) {
if (!readSector(sector + i, dst + i*512UL)) {
if (!readSector(sector + i, dst + i * 512UL)) {
return false;
}
}
@@ -949,28 +993,22 @@ bool SdioCard::readStart(uint32_t sector) {
#if defined(__IMXRT1062__)
// Infinite transfer.
SDHC_BLKATTR = SDHC_BLKATTR_BLKSIZE(512);
#else // defined(__IMXRT1062__)
#else // defined(__IMXRT1062__)
// Errata - can't do infinite transfer.
SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(MAX_BLKCNT) | SDHC_BLKATTR_BLKSIZE(512);
#endif // defined(__IMXRT1062__)
if (!cardCommand(CMD18_PGM_XFERTYP, m_highCapacity ? sector : 512*sector)) {
if (!cardCommand(CMD18_PGM_XFERTYP, m_highCapacity ? sector : 512 * sector)) {
return sdError(SD_CARD_ERROR_CMD18);
}
return true;
}
//------------------------------------------------------------------------------
bool SdioCard::readStop() {
return transferStop();
}
bool SdioCard::readStop() { return transferStop(); }
//------------------------------------------------------------------------------
uint32_t SdioCard::sectorCount() {
return m_csd.capacity();
}
uint32_t SdioCard::sectorCount() { return m_csd.capacity(); }
//------------------------------------------------------------------------------
uint32_t SdioCard::status() {
return statusCMD13();
}
uint32_t SdioCard::status() { return statusCMD13(); }
//------------------------------------------------------------------------------
bool SdioCard::stopTransmission(bool blocking) {
m_curState = IDLE_STATE;
@@ -998,8 +1036,8 @@ bool SdioCard::syncDevice() {
}
//------------------------------------------------------------------------------
uint8_t SdioCard::type() const {
return m_version2 ? m_highCapacity ?
SD_CARD_TYPE_SDHC : SD_CARD_TYPE_SD2 : SD_CARD_TYPE_SD1;
return m_version2 ? m_highCapacity ? SD_CARD_TYPE_SDHC : SD_CARD_TYPE_SD2
: SD_CARD_TYPE_SD1;
}
//------------------------------------------------------------------------------
bool SdioCard::writeData(const uint8_t* src) {
@@ -1016,7 +1054,7 @@ bool SdioCard::writeData(const uint8_t* src) {
if (waitTimeout(isBusyFifoWrite)) {
return sdError(SD_CARD_ERROR_WRITE_FIFO);
}
for (uint32_t iw = 0 ; iw < 512/(4*FIFO_WML); iw++) {
for (uint32_t iw = 0; iw < 512 / (4 * FIFO_WML); iw++) {
while (0 == (SDHC_PRSSTAT & SDHC_PRSSTAT_BWEN)) {
}
for (uint32_t i = 0; i < FIFO_WML; i++) {
@@ -1057,7 +1095,7 @@ bool SdioCard::writeSector(uint32_t sector, const uint8_t* src) {
if (!syncDevice()) {
return false;
}
if (!writeStart(sector )) {
if (!writeStart(sector)) {
return false;
}
m_curSector = sector;
@@ -1087,7 +1125,7 @@ bool SdioCard::writeSectors(uint32_t sector, const uint8_t* src, size_t n) {
}
} else {
for (size_t i = 0; i < n; i++) {
if (!writeSector(sector + i, src + i*512UL)) {
if (!writeSector(sector + i, src + i * 512UL)) {
return false;
}
}
@@ -1104,17 +1142,15 @@ bool SdioCard::writeStart(uint32_t sector) {
#if defined(__IMXRT1062__)
// Infinite transfer.
SDHC_BLKATTR = SDHC_BLKATTR_BLKSIZE(512);
#else // defined(__IMXRT1062__)
#else // defined(__IMXRT1062__)
// Errata - can't do infinite transfer.
SDHC_BLKATTR = SDHC_BLKATTR_BLKCNT(MAX_BLKCNT) | SDHC_BLKATTR_BLKSIZE(512);
#endif // defined(__IMXRT1062__)
if (!cardCommand(CMD25_PGM_XFERTYP, m_highCapacity ? sector : 512*sector)) {
if (!cardCommand(CMD25_PGM_XFERTYP, m_highCapacity ? sector : 512 * sector)) {
return sdError(SD_CARD_ERROR_CMD25);
}
return true;
}
//------------------------------------------------------------------------------
bool SdioCard::writeStop() {
return transferStop();
}
bool SdioCard::writeStop() { return transferStop(); }
#endif // defined(__MK64FX512__) defined(__MK66FX1M0__) defined(__IMXRT1062__)