Merge pull request #10558 from iNavFlight/MrD_Correct-comments-on-OSD-symbols
[inav.git] / src / main / drivers / sdcard / sdcard_spi.c
blob1b374e70e6bb0ef6e2ac44ee689631c541f1f467
1 /*
2 * This file is part of INAV, Cleanflight and Betaflight.
4 * INAV, Cleanflight and Betaflight are free software. You can redistribute
5 * this software and/or modify this software under the terms of the
6 * GNU General Public License as published by the Free Software
7 * Foundation, either version 3 of the License, or (at your option)
8 * any later version.
10 * Cleanflight and Betaflight are distributed in the hope that they
11 * will be useful, but WITHOUT ANY WARRANTY; without even the implied
12 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 * See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this software.
18 * If not, see <http://www.gnu.org/licenses/>.
21 #include <stdbool.h>
22 #include <stdint.h>
24 #include "platform.h"
26 #include "build/debug.h"
27 #include "common/utils.h"
29 #include "drivers/time.h"
30 #include "drivers/nvic.h"
31 #include "drivers/io.h"
32 #include "drivers/bus.h"
33 #include "drivers/bus_spi.h"
35 #include "drivers/sdcard/sdcard.h"
36 #include "drivers/sdcard/sdcard_impl.h"
37 #include "drivers/sdcard/sdcard_standard.h"
39 #include "scheduler/protothreads.h"
41 #ifdef USE_SDCARD_SPI
43 #define SDCARD_INIT_NUM_DUMMY_BYTES 10
44 #define SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY 8
45 // Chosen so that CMD8 will have the same CRC as CMD0:
46 #define SDCARD_IF_COND_CHECK_PATTERN 0xAB
48 /* Break up 512-byte SD card sectors into chunks of this size to reduce the peak overhead per call to sdcard_poll(). */
49 #define SDCARD_BLOCK_CHUNK_SIZE 128
51 #ifndef SDCARD_BUS_SPEED
52 #define SDCARD_BUS_SPEED BUS_SPEED_STANDARD
53 #endif
55 static void sdcardSpi_select(void)
57 busSelectDevice(sdcard.dev);
60 static void sdcardSpi_deselect(void)
62 // As per the SD-card spec, give the card 8 dummy clocks so it can finish its operation
63 //spiTransferByte(SDCARD_SPI_INSTANCE, 0xFF);
65 while (busIsBusy(sdcard.dev)) { __NOP(); }
67 busDeselectDevice(sdcard.dev);
71 /**
72 * Returns true if the card has already been, or is currently, initializing and hasn't encountered enough errors to
73 * trip our error threshold and be disabled (i.e. our card is in and working!)
75 bool sdcardSpi_isFunctional(void)
77 return sdcard.state != SDCARD_STATE_NOT_PRESENT;
80 /**
81 * Handle a failure of an SD card operation by resetting the card back to its initialization phase.
83 * Increments the failure counter, and when the failure threshold is reached, disables the card until
84 * the next call to sdcard_init().
86 static void sdcardSpi_reset(void)
88 if (!sdcard_isInserted()) {
89 sdcard.state = SDCARD_STATE_NOT_PRESENT;
90 return;
93 sdcard.failureCount++;
94 if (sdcard.failureCount >= SDCARD_MAX_CONSECUTIVE_FAILURES) {
95 sdcard.state = SDCARD_STATE_NOT_PRESENT;
96 } else {
97 sdcard.operationStartTime = millis();
98 sdcard.state = SDCARD_STATE_RESET;
103 * The SD card spec requires 8 clock cycles to be sent by us on the bus after most commands so it can finish its
104 * processing of that command. The easiest way for us to do this is to just wait for the bus to become idle before
105 * we transmit a command, sending at least 8-bits onto the bus when we do so.
107 static bool sdcardSpi_waitForIdle(int maxBytesToWait)
109 while (maxBytesToWait > 0) {
110 uint8_t response;
112 busTransfer(sdcard.dev, &response, NULL, 1);
114 if (response == 0xFF) {
115 return true;
118 maxBytesToWait--;
121 return false;
125 * Wait for up to maxDelay 0xFF idle bytes to arrive from the card, returning the first non-idle byte found.
127 * Returns 0xFF on failure.
129 static uint8_t sdcardSpi_waitForNonIdleByte(int maxDelay)
131 for (int i = 0; i <= maxDelay; i++) { // <= so we can wait for maxDelay '0xFF' bytes before reading a response byte afterwards
132 uint8_t response;
134 busTransfer(sdcard.dev, &response, NULL, 1);
136 if (response != 0xFF) {
137 return response;
141 return 0xFF;
145 * Waits up to SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY bytes for the card to become ready, send a command to the card
146 * with the given argument, waits up to SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY bytes for a reply, and returns the
147 * first non-0xFF byte of the reply.
149 * You must select the card first with sdcardSpi_select() and deselect it afterwards with sdcardSpi_deselect().
151 * Upon failure, 0xFF is returned.
153 static uint8_t sdcardSpi_sendCommand(uint8_t commandCode, uint32_t commandArgument)
155 uint8_t command[6] = {
156 0x40 | commandCode,
157 commandArgument >> 24,
158 commandArgument >> 16,
159 commandArgument >> 8,
160 commandArgument,
161 0x95 /* Static CRC. This CRC is valid for CMD0 with a 0 argument, and CMD8 with 0x1AB argument, which are the only
162 commands that require a CRC */
165 // Go ahead and send the command even if the card isn't idle if this is the reset command
166 if (!sdcardSpi_waitForIdle(SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY) && commandCode != SDCARD_COMMAND_GO_IDLE_STATE)
167 return 0xFF;
169 busTransfer(sdcard.dev, NULL, command, sizeof(command));
172 * The card can take up to SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY bytes to send the response, in the meantime
173 * it'll transmit 0xFF filler bytes.
175 return sdcardSpi_waitForNonIdleByte(SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY);
178 static uint8_t sdcardSpi_sendAppCommand(uint8_t commandCode, uint32_t commandArgument)
180 sdcardSpi_sendCommand(SDCARD_COMMAND_APP_CMD, 0);
181 return sdcardSpi_sendCommand(commandCode, commandArgument);
185 * Sends an IF_COND message to the card to check its version and validate its voltage requirements. Sets the global
186 * sdCardVersion with the detected version (0, 1, or 2) and returns true if the card is compatible.
188 static bool sdcardSpi_validateInterfaceCondition(void)
190 uint8_t ifCondReply[4];
192 sdcard.version = 0;
194 sdcardSpi_select();
196 uint8_t status = sdcardSpi_sendCommand(SDCARD_COMMAND_SEND_IF_COND, (SDCARD_VOLTAGE_ACCEPTED_2_7_to_3_6 << 8) | SDCARD_IF_COND_CHECK_PATTERN);
198 // Don't deselect the card right away, because we'll want to read the rest of its reply if it's a V2 card
200 if (status == (SDCARD_R1_STATUS_BIT_ILLEGAL_COMMAND | SDCARD_R1_STATUS_BIT_IDLE)) {
201 // V1 cards don't support this command
202 sdcard.version = 1;
203 } else if (status == SDCARD_R1_STATUS_BIT_IDLE) {
204 busTransfer(sdcard.dev, ifCondReply, NULL, sizeof(ifCondReply));
207 * We don't bother to validate the SDCard's operating voltage range since the spec requires it to accept our
208 * 3.3V, but do check that it echoed back our check pattern properly.
210 if (ifCondReply[3] == SDCARD_IF_COND_CHECK_PATTERN) {
211 sdcard.version = 2;
215 sdcardSpi_deselect();
217 return sdcard.version > 0;
220 static bool sdcardSpi_readOCRRegister(uint32_t *result)
222 uint8_t response[4];
224 sdcardSpi_select();
226 uint8_t status = sdcardSpi_sendCommand(SDCARD_COMMAND_READ_OCR, 0);
228 busTransfer(sdcard.dev, response, NULL, sizeof(response));
230 sdcardSpi_deselect();
232 if (status == 0) {
233 *result = (response[0] << 24) | (response[1] << 16) | (response[2] << 8) | response[3];
234 return true;
235 } else {
236 return false;
240 typedef enum {
241 SDCARD_RECEIVE_SUCCESS,
242 SDCARD_RECEIVE_BLOCK_IN_PROGRESS,
243 SDCARD_RECEIVE_ERROR,
244 } sdcardReceiveBlockStatus_e;
247 * Attempt to receive a data block from the SD card.
249 * Return true on success, otherwise the card has not responded yet and you should retry later.
251 static sdcardReceiveBlockStatus_e sdcardSpi_receiveDataBlock(uint8_t *buffer, int count)
253 uint8_t dataToken = sdcardSpi_waitForNonIdleByte(8);
255 if (dataToken == 0xFF) {
256 return SDCARD_RECEIVE_BLOCK_IN_PROGRESS;
259 if (dataToken != SDCARD_SINGLE_BLOCK_READ_START_TOKEN) {
260 return SDCARD_RECEIVE_ERROR;
263 busTransfer(sdcard.dev, buffer, NULL, count);
265 // Discard trailing CRC, we don't care
266 busTransfer(sdcard.dev, NULL, NULL, 2);
268 return SDCARD_RECEIVE_SUCCESS;
271 static bool sdcardSpi_sendDataBlockFinish(void)
273 static const uint8_t dummyCRC[2] = { 0x00, 0x00 };
275 // Send a dummy CRC
276 busTransfer(sdcard.dev, NULL, dummyCRC, 2);
278 uint8_t dataResponseToken;
279 busTransfer(sdcard.dev, &dataResponseToken, NULL, 1);
282 * Check if the card accepted the write (no CRC error / no address error)
284 * The lower 5 bits are structured as follows:
285 * | 0 | Status | 1 |
286 * | 0 | x x x | 1 |
288 * Statuses:
289 * 010 - Data accepted
290 * 101 - CRC error
291 * 110 - Write error
293 return (dataResponseToken & 0x1F) == 0x05;
297 * Begin sending a buffer of SDCARD_BLOCK_SIZE bytes to the SD card.
299 static void sdcardSpi_sendDataBlockBegin(uint8_t *buffer, bool multiBlockWrite)
301 uint8_t blockStartToken[2] = { 0xFF, multiBlockWrite ? SDCARD_MULTIPLE_BLOCK_WRITE_START_TOKEN : SDCARD_SINGLE_BLOCK_WRITE_START_TOKEN };
303 // Card wants 8 dummy clock cycles between the write command's response and a data block beginning:
304 busTransfer(sdcard.dev, NULL, blockStartToken, 2);
306 // Send the first chunk now
307 busTransfer(sdcard.dev, NULL, buffer, SDCARD_BLOCK_CHUNK_SIZE);
310 static bool sdcardSpi_receiveCID(void)
312 uint8_t cid[16];
314 if (sdcardSpi_receiveDataBlock(cid, sizeof(cid)) != SDCARD_RECEIVE_SUCCESS) {
315 return false;
318 sdcard.metadata.manufacturerID = cid[0];
319 sdcard.metadata.oemID = (cid[1] << 8) | cid[2];
320 sdcard.metadata.productName[0] = cid[3];
321 sdcard.metadata.productName[1] = cid[4];
322 sdcard.metadata.productName[2] = cid[5];
323 sdcard.metadata.productName[3] = cid[6];
324 sdcard.metadata.productName[4] = cid[7];
325 sdcard.metadata.productRevisionMajor = cid[8] >> 4;
326 sdcard.metadata.productRevisionMinor = cid[8] & 0x0F;
327 sdcard.metadata.productSerial = (cid[9] << 24) | (cid[10] << 16) | (cid[11] << 8) | cid[12];
328 sdcard.metadata.productionYear = (((cid[13] & 0x0F) << 4) | (cid[14] >> 4)) + 2000;
329 sdcard.metadata.productionMonth = cid[14] & 0x0F;
331 return true;
334 static bool sdcardSpi_fetchCSD(void)
336 uint32_t readBlockLen, blockCount, blockCountMult;
337 uint64_t capacityBytes;
339 sdcardSpi_select();
341 /* The CSD command's data block should always arrive within 8 idle clock cycles (SD card spec). This is because
342 * the information about card latency is stored in the CSD register itself, so we can't use that yet!
344 bool success =
345 sdcardSpi_sendCommand(SDCARD_COMMAND_SEND_CSD, 0) == 0
346 && sdcardSpi_receiveDataBlock((uint8_t*) &sdcard.csd, sizeof(sdcard.csd)) == SDCARD_RECEIVE_SUCCESS
347 && SDCARD_GET_CSD_FIELD(sdcard.csd, 1, TRAILER) == 1;
349 if (success) {
350 switch (SDCARD_GET_CSD_FIELD(sdcard.csd, 1, CSD_STRUCTURE_VER)) {
351 case SDCARD_CSD_STRUCTURE_VERSION_1:
352 // Block size in bytes (doesn't have to be 512)
353 readBlockLen = 1 << SDCARD_GET_CSD_FIELD(sdcard.csd, 1, READ_BLOCK_LEN);
354 blockCountMult = 1 << (SDCARD_GET_CSD_FIELD(sdcard.csd, 1, CSIZE_MULT) + 2);
355 blockCount = (SDCARD_GET_CSD_FIELD(sdcard.csd, 1, CSIZE) + 1) * blockCountMult;
357 // We could do this in 32 bits but it makes the 2GB case awkward
358 capacityBytes = (uint64_t) blockCount * readBlockLen;
360 // Re-express that capacity (max 2GB) in our standard 512-byte block size
361 sdcard.metadata.numBlocks = capacityBytes / SDCARD_BLOCK_SIZE;
362 break;
363 case SDCARD_CSD_STRUCTURE_VERSION_2:
364 sdcard.metadata.numBlocks = (SDCARD_GET_CSD_FIELD(sdcard.csd, 2, CSIZE) + 1) * 1024;
365 break;
366 default:
367 success = false;
371 sdcardSpi_deselect();
373 return success;
377 * Check if the SD Card has completed its startup sequence. Must be called with sdcard.state == SDCARD_STATE_INITIALIZATION.
379 * Returns true if the card has finished its init process.
381 static bool sdcardSpi_checkInitDone(void)
383 sdcardSpi_select();
384 uint8_t status = sdcardSpi_sendAppCommand(SDCARD_ACOMMAND_SEND_OP_COND, sdcard.version == 2 ? 1 << 30 /* We support high capacity cards */ : 0);
385 sdcardSpi_deselect();
387 // When card init is complete, the idle bit in the response becomes zero.
388 return status == 0x00;
391 static bool sdcardSpi_setBlockLength(uint32_t blockLen)
393 sdcardSpi_select();
394 uint8_t status = sdcardSpi_sendCommand(SDCARD_COMMAND_SET_BLOCKLEN, blockLen);
395 sdcardSpi_deselect();
397 return status == 0;
401 * Returns true if the card is ready to accept read/write commands.
403 static bool sdcardSpi_isReady(void)
405 return sdcard.state == SDCARD_STATE_READY || sdcard.state == SDCARD_STATE_WRITING_MULTIPLE_BLOCKS;
409 * Send the stop-transmission token to complete a multi-block write.
411 * Returns:
412 * SDCARD_OPERATION_IN_PROGRESS - We're now waiting for that stop to complete, the card will enter
413 * the SDCARD_STATE_STOPPING_MULTIPLE_BLOCK_WRITE state.
414 * SDCARD_OPERATION_SUCCESS - The multi-block write finished immediately, the card will enter
415 * the SDCARD_READY state.
418 static sdcardOperationStatus_e sdcardSpi_endWriteBlocks(void)
420 uint8_t writeEndToken[2] = { 0xFF, SDCARD_MULTIPLE_BLOCK_WRITE_STOP_TOKEN };
422 sdcard.multiWriteBlocksRemain = 0;
424 // 8 dummy clocks to guarantee N_WR clocks between the last card response and this token
425 busTransfer(sdcard.dev, NULL, writeEndToken, 2);
427 // Card may choose to raise a busy (non-0xFF) signal after at most N_BR (1 byte) delay
428 if (sdcardSpi_waitForNonIdleByte(1) == 0xFF) {
429 sdcard.state = SDCARD_STATE_READY;
430 return SDCARD_OPERATION_SUCCESS;
431 } else {
432 sdcard.state = SDCARD_STATE_STOPPING_MULTIPLE_BLOCK_WRITE;
433 sdcard.operationStartTime = millis();
435 return SDCARD_OPERATION_IN_PROGRESS;
440 * Call periodically for the SD card to perform in-progress transfers.
442 * Returns true if the card is ready to accept commands.
444 static bool sdcardSpi_poll(void)
446 if (sdcard.dev == NULL) {
447 return false;
450 uint8_t initStatus;
451 bool sendComplete;
453 doMore:
454 switch (sdcard.state) {
455 case SDCARD_STATE_RESET:
456 sdcardSpi_select();
458 initStatus = sdcardSpi_sendCommand(SDCARD_COMMAND_GO_IDLE_STATE, 0);
460 sdcardSpi_deselect();
462 if (initStatus == SDCARD_R1_STATUS_BIT_IDLE) {
463 // Check card voltage and version
464 if (sdcardSpi_validateInterfaceCondition()) {
466 sdcard.state = SDCARD_STATE_CARD_INIT_IN_PROGRESS;
467 goto doMore;
468 } else {
469 // Bad reply/voltage, we ought to refrain from accessing the card.
470 sdcard.state = SDCARD_STATE_NOT_PRESENT;
474 busSetSpeed(sdcard.dev, BUS_SPEED_STANDARD);
475 break;
477 case SDCARD_STATE_CARD_INIT_IN_PROGRESS:
478 if (sdcardSpi_checkInitDone()) {
479 if (sdcard.version == 2) {
480 // Check for high capacity card
481 uint32_t ocr;
483 if (!sdcardSpi_readOCRRegister(&ocr)) {
484 sdcardSpi_reset();
485 goto doMore;
488 sdcard.highCapacity = (ocr & (1 << 30)) != 0;
489 } else {
490 // Version 1 cards are always low-capacity
491 sdcard.highCapacity = false;
494 // Now fetch the CSD and CID registers
495 if (sdcardSpi_fetchCSD()) {
496 sdcardSpi_select();
498 uint8_t status = sdcardSpi_sendCommand(SDCARD_COMMAND_SEND_CID, 0);
500 if (status == 0) {
501 // Keep the card selected to receive the response block
502 sdcard.state = SDCARD_STATE_INITIALIZATION_RECEIVE_CID;
503 goto doMore;
504 } else {
505 sdcardSpi_deselect();
507 sdcardSpi_reset();
508 goto doMore;
513 busSetSpeed(sdcard.dev, BUS_SPEED_STANDARD);
514 break;
515 case SDCARD_STATE_INITIALIZATION_RECEIVE_CID:
516 if (sdcardSpi_receiveCID()) {
517 sdcardSpi_deselect();
519 /* The spec is a little iffy on what the default block size is for Standard Size cards (it can be changed on
520 * standard size cards) so let's just set it to 512 explicitly so we don't have a problem.
522 if (!sdcard.highCapacity && !sdcardSpi_setBlockLength(SDCARD_BLOCK_SIZE)) {
523 sdcardSpi_reset();
524 goto doMore;
527 // Now we're done with init and we can switch to the full speed clock (<25MHz)
528 busSetSpeed(sdcard.dev, SDCARD_BUS_SPEED);
530 sdcard.multiWriteBlocksRemain = 0;
532 sdcard.state = SDCARD_STATE_READY;
533 goto doMore;
534 } // else keep waiting for the CID to arrive
536 busSetSpeed(sdcard.dev, BUS_SPEED_STANDARD);
537 break;
538 case SDCARD_STATE_SENDING_WRITE:
539 // Have we finished sending the write yet?
540 sendComplete = false;
542 // Send another chunk
543 busTransfer(sdcard.dev, NULL, sdcard.pendingOperation.buffer + SDCARD_BLOCK_CHUNK_SIZE * sdcard.pendingOperation.chunkIndex, SDCARD_BLOCK_CHUNK_SIZE);
544 sdcard.pendingOperation.chunkIndex++;
545 sendComplete = sdcard.pendingOperation.chunkIndex == SDCARD_BLOCK_SIZE / SDCARD_BLOCK_CHUNK_SIZE;
547 if (sendComplete) {
548 // Finish up by sending the CRC and checking the SD-card's acceptance/rejectance
549 if (sdcardSpi_sendDataBlockFinish()) {
550 // The SD card is now busy committing that write to the card
551 sdcard.state = SDCARD_STATE_WAITING_FOR_WRITE;
552 sdcard.operationStartTime = millis();
554 // Since we've transmitted the buffer we can go ahead and tell the caller their operation is complete
555 if (sdcard.pendingOperation.callback) {
556 sdcard.pendingOperation.callback(SDCARD_BLOCK_OPERATION_WRITE, sdcard.pendingOperation.blockIndex, sdcard.pendingOperation.buffer, sdcard.pendingOperation.callbackData);
558 } else {
559 /* Our write was rejected! This could be due to a bad address but we hope not to attempt that, so assume
560 * the card is broken and needs reset.
562 sdcardSpi_reset();
564 // Announce write failure:
565 if (sdcard.pendingOperation.callback) {
566 sdcard.pendingOperation.callback(SDCARD_BLOCK_OPERATION_WRITE, sdcard.pendingOperation.blockIndex, NULL, sdcard.pendingOperation.callbackData);
569 goto doMore;
572 break;
573 case SDCARD_STATE_WAITING_FOR_WRITE:
574 if (sdcardSpi_waitForIdle(SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY)) {
575 sdcard.failureCount = 0; // Assume the card is good if it can complete a write
577 // Still more blocks left to write in a multi-block chain?
578 if (sdcard.multiWriteBlocksRemain > 1) {
579 sdcard.multiWriteBlocksRemain--;
580 sdcard.multiWriteNextBlock++;
581 sdcard.state = SDCARD_STATE_WRITING_MULTIPLE_BLOCKS;
582 } else if (sdcard.multiWriteBlocksRemain == 1) {
583 // This function changes the sd card state for us whether immediately succesful or delayed:
584 if (sdcardSpi_endWriteBlocks() == SDCARD_OPERATION_SUCCESS) {
585 sdcardSpi_deselect();
587 } else {
588 sdcard.state = SDCARD_STATE_READY;
589 sdcardSpi_deselect();
591 } else if (millis() > sdcard.operationStartTime + SDCARD_TIMEOUT_WRITE_MSEC) {
593 * The caller has already been told that their write has completed, so they will have discarded
594 * their buffer and have no hope of retrying the operation. But this should be very rare and it allows
595 * them to reuse their buffer milliseconds faster than they otherwise would.
597 sdcardSpi_reset();
598 goto doMore;
600 break;
601 case SDCARD_STATE_READING:
602 switch (sdcardSpi_receiveDataBlock(sdcard.pendingOperation.buffer, SDCARD_BLOCK_SIZE)) {
603 case SDCARD_RECEIVE_SUCCESS:
604 sdcardSpi_deselect();
606 sdcard.state = SDCARD_STATE_READY;
607 sdcard.failureCount = 0; // Assume the card is good if it can complete a read
609 if (sdcard.pendingOperation.callback) {
610 sdcard.pendingOperation.callback(
611 SDCARD_BLOCK_OPERATION_READ,
612 sdcard.pendingOperation.blockIndex,
613 sdcard.pendingOperation.buffer,
614 sdcard.pendingOperation.callbackData
617 break;
618 case SDCARD_RECEIVE_BLOCK_IN_PROGRESS:
619 if (millis() <= sdcard.operationStartTime + SDCARD_TIMEOUT_READ_MSEC) {
620 break; // Timeout not reached yet so keep waiting
622 // Timeout has expired, so fall through to convert to a fatal error
623 FALLTHROUGH;
625 case SDCARD_RECEIVE_ERROR:
626 sdcardSpi_deselect();
628 sdcardSpi_reset();
630 if (sdcard.pendingOperation.callback) {
631 sdcard.pendingOperation.callback(
632 SDCARD_BLOCK_OPERATION_READ,
633 sdcard.pendingOperation.blockIndex,
634 NULL,
635 sdcard.pendingOperation.callbackData
639 goto doMore;
640 break;
642 break;
643 case SDCARD_STATE_STOPPING_MULTIPLE_BLOCK_WRITE:
644 if (sdcardSpi_waitForIdle(SDCARD_MAXIMUM_BYTE_DELAY_FOR_CMD_REPLY)) {
645 sdcardSpi_deselect();
647 sdcard.state = SDCARD_STATE_READY;
648 } else if (millis() > sdcard.operationStartTime + SDCARD_TIMEOUT_WRITE_MSEC) {
649 sdcardSpi_reset();
650 goto doMore;
652 break;
653 case SDCARD_STATE_NOT_PRESENT:
654 default:
658 // Is the card's initialization taking too long?
659 if (sdcard.state >= SDCARD_STATE_RESET && sdcard.state < SDCARD_STATE_READY
660 && millis() - sdcard.operationStartTime > SDCARD_TIMEOUT_INIT_MILLIS) {
661 sdcardSpi_reset();
664 return sdcardSpi_isReady();
668 * Write the 512-byte block from the given buffer into the block with the given index.
670 * If the write does not complete immediately, your callback will be called later. If the write was successful, the
671 * buffer pointer will be the same buffer you originally passed in, otherwise the buffer will be set to NULL.
673 * Returns:
674 * SDCARD_OPERATION_IN_PROGRESS - Your buffer is currently being transmitted to the card and your callback will be
675 * called later to report the completion. The buffer pointer must remain valid until
676 * that time.
677 * SDCARD_OPERATION_SUCCESS - Your buffer has been transmitted to the card now.
678 * SDCARD_OPERATION_BUSY - The card is already busy and cannot accept your write
679 * SDCARD_OPERATION_FAILURE - Your write was rejected by the card, card will be reset
681 static sdcardOperationStatus_e sdcardSpi_writeBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData)
683 uint8_t status;
685 doMore:
686 switch (sdcard.state) {
687 case SDCARD_STATE_WRITING_MULTIPLE_BLOCKS:
688 // Do we need to cancel the previous multi-block write?
689 if (blockIndex != sdcard.multiWriteNextBlock) {
690 if (sdcardSpi_endWriteBlocks() == SDCARD_OPERATION_SUCCESS) {
691 // Now we've entered the ready state, we can try again
692 goto doMore;
693 } else {
694 return SDCARD_OPERATION_BUSY;
698 // We're continuing a multi-block write
699 break;
700 case SDCARD_STATE_READY:
701 // We're not continuing a multi-block write so we need to send a single-block write command
702 sdcardSpi_select();
704 // Standard size cards use byte addressing, high capacity cards use block addressing
705 status = sdcardSpi_sendCommand(SDCARD_COMMAND_WRITE_BLOCK, sdcard.highCapacity ? blockIndex : blockIndex * SDCARD_BLOCK_SIZE);
707 if (status != 0) {
708 sdcardSpi_deselect();
710 sdcardSpi_reset();
712 return SDCARD_OPERATION_FAILURE;
714 break;
715 default:
716 return SDCARD_OPERATION_BUSY;
719 sdcardSpi_sendDataBlockBegin(buffer, sdcard.state == SDCARD_STATE_WRITING_MULTIPLE_BLOCKS);
721 sdcard.pendingOperation.buffer = buffer;
722 sdcard.pendingOperation.blockIndex = blockIndex;
723 sdcard.pendingOperation.callback = callback;
724 sdcard.pendingOperation.callbackData = callbackData;
725 sdcard.pendingOperation.chunkIndex = 1;
726 sdcard.state = SDCARD_STATE_SENDING_WRITE;
728 return SDCARD_OPERATION_IN_PROGRESS;
732 * Begin writing a series of consecutive blocks beginning at the given block index. This will allow (but not require)
733 * the SD card to pre-erase the number of blocks you specifiy, which can allow the writes to complete faster.
735 * Afterwards, just call sdcard_writeBlock() as normal to write those blocks consecutively.
737 * It's okay to abort the multi-block write at any time by writing to a non-consecutive address, or by performing a read.
739 * Returns:
740 * SDCARD_OPERATION_SUCCESS - Multi-block write has been queued
741 * SDCARD_OPERATION_BUSY - The card is already busy and cannot accept your write
742 * SDCARD_OPERATION_FAILURE - A fatal error occured, card will be reset
744 static sdcardOperationStatus_e sdcardSpi_beginWriteBlocks(uint32_t blockIndex, uint32_t blockCount)
746 if (sdcard.state != SDCARD_STATE_READY) {
747 if (sdcard.state == SDCARD_STATE_WRITING_MULTIPLE_BLOCKS) {
748 if (blockIndex == sdcard.multiWriteNextBlock) {
749 // Assume that the caller wants to continue the multi-block write they already have in progress!
750 return SDCARD_OPERATION_SUCCESS;
751 } else if (sdcardSpi_endWriteBlocks() != SDCARD_OPERATION_SUCCESS) {
752 return SDCARD_OPERATION_BUSY;
753 } // Else we've completed the previous multi-block write and can fall through to start the new one
754 } else {
755 return SDCARD_OPERATION_BUSY;
759 sdcardSpi_select();
761 if (
762 sdcardSpi_sendAppCommand(SDCARD_ACOMMAND_SET_WR_BLOCK_ERASE_COUNT, blockCount) == 0
763 && sdcardSpi_sendCommand(SDCARD_COMMAND_WRITE_MULTIPLE_BLOCK, sdcard.highCapacity ? blockIndex : blockIndex * SDCARD_BLOCK_SIZE) == 0
765 sdcard.state = SDCARD_STATE_WRITING_MULTIPLE_BLOCKS;
766 sdcard.multiWriteBlocksRemain = blockCount;
767 sdcard.multiWriteNextBlock = blockIndex;
769 // Leave the card selected
770 return SDCARD_OPERATION_SUCCESS;
771 } else {
772 sdcardSpi_deselect();
774 sdcardSpi_reset();
776 return SDCARD_OPERATION_FAILURE;
781 * Read the 512-byte block with the given index into the given 512-byte buffer.
783 * When the read completes, your callback will be called. If the read was successful, the buffer pointer will be the
784 * same buffer you originally passed in, otherwise the buffer will be set to NULL.
786 * You must keep the pointer to the buffer valid until the operation completes!
788 * Returns:
789 * true - The operation was successfully queued for later completion, your callback will be called later
790 * false - The operation could not be started due to the card being busy (try again later).
792 static bool sdcardSpi_readBlock(uint32_t blockIndex, uint8_t *buffer, sdcard_operationCompleteCallback_c callback, uint32_t callbackData)
794 if (sdcard.state != SDCARD_STATE_READY) {
795 if (sdcard.state == SDCARD_STATE_WRITING_MULTIPLE_BLOCKS) {
796 if (sdcardSpi_endWriteBlocks() != SDCARD_OPERATION_SUCCESS) {
797 return false;
799 } else {
800 return false;
804 sdcardSpi_select();
806 // Standard size cards use byte addressing, high capacity cards use block addressing
807 uint8_t status = sdcardSpi_sendCommand(SDCARD_COMMAND_READ_SINGLE_BLOCK, sdcard.highCapacity ? blockIndex : blockIndex * SDCARD_BLOCK_SIZE);
809 if (status == 0) {
810 sdcard.pendingOperation.buffer = buffer;
811 sdcard.pendingOperation.blockIndex = blockIndex;
812 sdcard.pendingOperation.callback = callback;
813 sdcard.pendingOperation.callbackData = callbackData;
815 sdcard.state = SDCARD_STATE_READING;
817 sdcard.operationStartTime = millis();
819 // Leave the card selected for the whole transaction
821 return true;
822 } else {
823 sdcardSpi_deselect();
824 return false;
829 * Returns true if the SD card has successfully completed its startup procedures.
831 static bool sdcardSpi_isInitialized(void)
833 return sdcard.state >= SDCARD_STATE_READY;
836 static const sdcardMetadata_t* sdcardSpi_getMetadata(void)
838 return &sdcard.metadata;
842 * Begin the initialization process for the SD card. This must be called first before any other sdcard_ routine.
844 void sdcardSpi_init(void)
846 sdcard.dev = busDeviceInit(BUSTYPE_SPI, DEVHW_SDCARD, 0, OWNER_SDCARD);
847 if (!sdcard.dev) {
848 sdcard.state = SDCARD_STATE_NOT_PRESENT;
849 return;
852 // Max frequency is initially 400kHz
853 busSetSpeed(sdcard.dev, BUS_SPEED_INITIALIZATION);
855 // SDCard wants 1ms minimum delay after power is applied to it
856 delay(1);
858 // Transmit at least 74 dummy clock cycles with CS high so the SD card can start up
859 IOHi(sdcard.dev->busdev.spi.csnPin);
860 SPI_TypeDef * instance = spiInstanceByDevice(sdcard.dev->busdev.spi.spiBus);
861 spiTransfer(instance, NULL, NULL, SDCARD_INIT_NUM_DUMMY_BYTES);
863 // Wait for that transmission to finish before we enable the SDCard, so it receives the required number of cycles:
864 int time = 100000;
865 while (busIsBusy(sdcard.dev)) {
866 if (time-- == 0) {
867 busSetSpeed(sdcard.dev, BUS_SPEED_STANDARD);
868 busDeviceDeInit(sdcard.dev);
869 sdcard.dev = NULL;
870 sdcard.state = SDCARD_STATE_NOT_PRESENT;
871 sdcard.failureCount++;
872 return;
876 sdcard.operationStartTime = millis();
877 sdcard.state = SDCARD_STATE_RESET;
878 sdcard.failureCount = 0;
881 sdcardVTable_t sdcardSpiVTable = {
882 .init = &sdcardSpi_init,
883 .readBlock = &sdcardSpi_readBlock,
884 .beginWriteBlocks = &sdcardSpi_beginWriteBlocks,
885 .writeBlock = &sdcardSpi_writeBlock,
886 .poll = &sdcardSpi_poll,
887 .isFunctional = &sdcardSpi_isFunctional,
888 .isInitialized = &sdcardSpi_isInitialized,
889 .getMetadata = &sdcardSpi_getMetadata,
892 #endif