6 #include "FsDriveSdSpi.hpp"
7 #include "LibEndian.hpp"
10 FsDriveSdSpi* FsDriveSdSpi::sInstances[1];
12 FsDriveSdSpi::FsDriveSdSpi(DrvSpi* spi) {
17 FsDriveSdSpi::~FsDriveSdSpi() {
21 bool FsDriveSdSpi::internalInit() {
22 mSpi->setBaudrate(400000);
24 for (
int i = 0; i < 10; i++) {
25 mSpi->readWrite(0xFF);
27 if (sendCmd(CMD0_GO_IDLE_STATE, 0).value != RESP_R1_IDLE_VALUE) {
30 if (sendCmd(CMD8_SEND_IF_COND, 0x1AA).value != RESP_R1_IDLE_VALUE) {
34 mSpi->readWrite(0, 0, (uint8_t*) &respR7,
sizeof(respR7));
35 if (respR7.voltageAccepted != 1 || respR7.checkPattern != 0xAA) {
45 if (sendCmd(CMD55_APP_CMD, 0).value <= RESP_R1_IDLE_VALUE) {
46 if (sendCmd(ACMD41_SD_SEND_OP_COND, 0x40000000).value == 0) {
52 if (sendCmd(CMD9_SEND_CSD, 0).value != 0) {
57 if (!readDataBlock(csd,
sizeof(csd))) {
60 if ((csd[0] >> 6) == 1) {
61 uint32_t cs = csd[9] + ((uint32_t) csd[8] << 8) + 1;
62 mSectorsCount = cs << 10;
65 uint32_t n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
66 uint32_t cs = (csd[8] >> 6) + ((uint32_t) csd[7] << 2) + ((uint32_t) (csd[6] & 3) << 10) + 1;
67 mSectorsCount = cs << (n - 9);
69 mSpi->setBaudrate(FS_CFG_SPI_FULL_SPEED_BAUDRATE);
73 bool FsDriveSdSpi::init() {
74 bool result = internalInit();
79 bool FsDriveSdSpi::readDataBlock(uint8_t* buffer,
unsigned int size) {
84 if (mSpi->readWrite(0xFF) == 0xFE) {
92 mSpi->readWrite(0, 0, buffer, size);
94 mSpi->readWrite(0, 0, crc, 2);
98 bool FsDriveSdSpi::internalReadBlocks(FsDefs::SECTOR* buffer,
unsigned int blockNumber,
unsigned int blockCount) {
99 uint8_t* dst = (uint8_t*) buffer;
101 if (blockCount == 1) {
102 if (sendCmd(CMD17_READ_SINGLE_BLOCK, blockNumber).value != 0) {
105 if (!readDataBlock(dst, 512)) {
111 if (sendCmd(CMD18_READ_MULTIPLE_BLOCK, blockNumber).value != 0) {
115 while (blockCount-- > 0) {
116 if (!readDataBlock(dst, 512)) {
121 sendCmd(CMD12_STOP_TRANSMISSION, 0);
127 bool FsDriveSdSpi::readBlocks(FsDefs::SECTOR* buffer,
unsigned int blockNumber,
unsigned int blockCount) {
128 bool result = internalReadBlocks(buffer, blockNumber, blockCount);
133 bool FsDriveSdSpi::writeDataBlock(
const uint8_t* buffer,
unsigned int size,
bool isMultipleBlock) {
138 if (isMultipleBlock) {
139 mSpi->readWrite(START_MULTIPLE_BLOCK_WRITE);
142 mSpi->readWrite(START_SINGLE_BLOCK_WRITE);
144 mSpi->readWrite(buffer, size, 0, 0);
145 uint8_t tokenAndCrc[3];
146 mSpi->readWrite(0, 0, tokenAndCrc, 3);
147 if ((tokenAndCrc[0] & 0x1F) != 0x05) {
153 bool FsDriveSdSpi::internalWriteBlocks(
const FsDefs::SECTOR* buffer,
unsigned int blockNumber,
unsigned int blockCount) {
154 uint8_t* src = (uint8_t*) buffer;
155 if (blockCount == 1) {
156 if (sendCmd(CMD24_WRITE_BLOCK, blockNumber).value != 0) {
159 if (!writeDataBlock(src, 512,
false)) {
165 if (sendCmd(ACMD23_SET_WR_BLK_ERASE_COUNT, blockCount).value > RESP_R1_IDLE_VALUE) {
168 if (sendCmd(CMD25_WRITE_MULTIPLE_BLOCK, blockNumber).value != 0) {
171 while (blockCount-- > 0) {
172 if (!writeDataBlock(src, 512,
true)) {
181 mSpi->readWrite(STOP_TRANSMISSION);
186 bool FsDriveSdSpi::writeBlocks(
const FsDefs::SECTOR* buffer,
unsigned int blockNumber,
unsigned int blockCount) {
187 bool result = internalWriteBlocks(buffer, blockNumber, blockCount);
192 FsDriveSdSpi::RESP_R1 FsDriveSdSpi::sendCmd(uint8_t cmd, uint32_t arg) {
201 cmdResp.args[0] = (uint8_t) ((arg >> 24) & 0xFF);
202 cmdResp.args[1] = (uint8_t) ((arg >> 16) & 0xFF);
203 cmdResp.args[2] = (uint8_t) ((arg >> 8) & 0xFF);
204 cmdResp.args[3] = (uint8_t) (arg & 0xFF);
208 if (cmd == CMD0_GO_IDLE_STATE) {
211 if (cmd == CMD8_SEND_IF_COND) {
220 mSpi->readWrite((uint8_t*) &cmdResp,
sizeof(CMD_RESP), 0, 0);
221 if (cmd == CMD12_STOP_TRANSMISSION) {
225 for (
int i = 0; (i < 10); i++) {
226 resp.value = mSpi->readWrite(0xFF);
227 if (!resp.bits.zero) {
234 bool FsDriveSdSpi::waitReady() {
239 if (mSpi->readWrite(0xFF) == 0xFF) {