Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of SDFileSystem by
Diff: SDFileSystem.cpp
- Revision:
- 9:1906befe7f30
- Parent:
- 8:7b6acbb6739b
- Child:
- 10:395539a1481a
--- a/SDFileSystem.cpp Thu Aug 07 16:44:42 2014 +0000 +++ b/SDFileSystem.cpp Mon Aug 11 15:28:11 2014 +0000 @@ -105,8 +105,8 @@ if (!(m_Status & STA_NOINIT)) return m_Status; - //Set the SPI frequency to 100kHz for initialization - m_Spi.frequency(100000); + //Set the SPI frequency to 400kHz for initialization + m_Spi.frequency(400000); //Send 80 dummy clocks with /CS and DI held high m_Cs = 1; @@ -251,7 +251,7 @@ else m_Spi.frequency(m_FREQ); - //Return the device status + //Return the disk status return m_Status; } @@ -260,13 +260,13 @@ //Check if there's a card in the socket checkSocket(); - //Return the device status + //Return the disk status return m_Status; } int SDFileSystem::disk_read(uint8_t* buffer, uint64_t sector) { - //Make sure the device is initialized before proceeding + //Make sure the card is initialized before proceeding if (m_Status & STA_NOINIT) return RES_NOTRDY; @@ -287,17 +287,17 @@ } } - //The read operation failed 3 times (CRC most likely) + //The read operation failed 3 times return RES_ERROR; } int SDFileSystem::disk_write(const uint8_t* buffer, uint64_t sector) { - //Make sure the device is initialized before proceeding + //Make sure the card is initialized before proceeding if (m_Status & STA_NOINIT) return RES_NOTRDY; - //Make sure the device isn't write protected before proceeding + //Make sure the card isn't write protected before proceeding if (m_Status & STA_PROTECT) return RES_WRPRT; @@ -309,58 +309,16 @@ for (int i = 0; i < 3; i++) { //Send CMD24(sector) to write a single block if (writeCommand(CMD24, sector) == 0x00) { - //Wait for up to 500ms for the card to become ready - if (!waitReady(500)) { - //We timed out, deselect and loop again - deselect(); - continue; - } - - //Send the write data token - m_Spi.write(0xFE); - - //Check if large frames are enabled or not - if (m_LargeFrames) { - //Switch to 16-bit frames for better performance - m_Spi.format(16, 0); - - //Write the data block from the buffer - for (int b = 0; b < 512; b += 2) { - m_Spi.write((buffer[b] << 8) | buffer[b + 1]); - } - - //Calculate the CRC16 checksum for the data block and send it (if enabled) - m_Spi.write(m_Crc ? CRC16((char*)buffer, 512) : 0xFFFF); - - //Switch back to 8-bit frames - m_Spi.format(8, 0); - } else { - //Write the data block from the buffer - for (int b = 0; b < 512; b++) - m_Spi.write(buffer[b]); - - //Calculate the CRC16 checksum for the data block and send it (if enabled) - unsigned short crc = m_Crc ? CRC16((char*)buffer, 512) : 0xFFFF; - m_Spi.write(crc >> 8); - m_Spi.write(crc); - } - - //Receive the data response, and deselect the card - char resp = m_Spi.write(0xFF) & 0x1F; - deselect(); - - //Check the response - if (resp == 0x05) + //Try to write the sector, and return if successful + if (writeData((char*)buffer)) return RES_OK; - else if (resp == 0x0D) - return RES_ERROR; } else { //The command failed return RES_ERROR; } } - //The operation either timed out 3 times, failed the CRC check 3 times, or experienced a write error + //The write operation failed 3 times return RES_ERROR; } @@ -376,7 +334,7 @@ uint64_t SDFileSystem::disk_sectors() { - //Make sure the device is initialized before proceeding + //Make sure the card is initialized before proceeding if (m_Status & STA_NOINIT) return 0; @@ -406,7 +364,7 @@ } } - //The read operation failed 3 times (CRC most likely) + //The read operation failed 3 times return 0; } @@ -441,16 +399,17 @@ //Pull /CS low m_Cs = 0; - //Send a dummy clock to enable DO + //Send 8 dummy clocks with DI held high to enable DO m_Spi.write(0xFF); //Wait for up to 500ms for the card to become ready - if (waitReady(500)) + if (waitReady(500)) { return true; - - //We timed out, deselect and return false - deselect(); - return false; + } else { + //We timed out, deselect and return false + deselect(); + return false; + } } inline void SDFileSystem::deselect() @@ -458,7 +417,7 @@ //Pull /CS high m_Cs = 1; - //Send a dummy byte to release DO + //Send 8 dummy clocks with DI held high to disable DO (will also initiate any internal write process) m_Spi.write(0xFF); } @@ -495,8 +454,8 @@ for (int b = 0; b < 6; b++) m_Spi.write(cmdPacket[b]); - //Allow up to 10 bytes of delay for the command response - for (int b = 0; b < 10; b++) { + //Allow up to 8 bytes of delay for the command response + for (int b = 0; b < 9; b++) { resp = m_Spi.write(0xFF); if (!(resp & 0x80)) break; @@ -506,12 +465,12 @@ if (resp > 0x01 || !(cmd == CMD8 || cmd == CMD9 || cmd == CMD17 || cmd == CMD24 || cmd == CMD55 || cmd == CMD58)) deselect(); - //Return the response unless there were CRC errors + //Return the response unless there was a CRC error if (resp == 0xFF || !(resp & (1 << 3))) return resp; } - //The command failed 3 times due to CRC errors + //The command failed 3 times return 0xFF; } @@ -537,7 +496,7 @@ char token; unsigned short crc; - //Wait for up to 200ms for the DataStart token to arrive + //Wait for up to 200ms for the data token to arrive for (int i = 0; i < 200; i++) { token = m_Spi.write(0xFF); if (token != 0xFF) @@ -556,7 +515,7 @@ //Switch to 16-bit frames for better performance m_Spi.format(16, 0); - //Read the data into the buffer + //Read the data block into the buffer unsigned short dataWord; for (int i = 0; i < length; i += 2) { dataWord = m_Spi.write(0xFFFF); @@ -582,6 +541,56 @@ //Deselect the card deselect(); - //Verify the CRC16 checksum (if enabled) + //Return the validity of the CRC16 checksum (if enabled) return (!m_Crc || crc == CRC16(buffer, length)); } + +bool SDFileSystem::writeData(char* buffer) +{ + //Wait for up to 500ms for the card to become ready + if (!waitReady(500)) { + //We timed out, deselect and indicate failure + deselect(); + return false; + } + + //Send the data token + m_Spi.write(0xFE); + + //Calculate the CRC16 checksum for the data block (if enabled) + unsigned short crc = (m_Crc) ? CRC16(buffer, 512) : 0xFFFF; + + //Check if large frames are enabled or not + if (m_LargeFrames) { + //Switch to 16-bit frames for better performance + m_Spi.format(16, 0); + + //Write the data block from the buffer + for (int b = 0; b < 512; b += 2) { + m_Spi.write((buffer[b] << 8) | buffer[b + 1]); + } + + //Send the CRC16 checksum for the data block + m_Spi.write(crc); + + //Switch back to 8-bit frames + m_Spi.format(8, 0); + } else { + //Write the data block from the buffer + for (int b = 0; b < 512; b++) + m_Spi.write(buffer[b]); + + //Send the CRC16 checksum for the data block + m_Spi.write(crc >> 8); + m_Spi.write(crc); + } + + //Receive the data response + char resp = m_Spi.write(0xFF); + + //Deselect the card (this will initiate the internal write process) + deselect(); + + //Return success/failure + return ((resp & 0x1F) == 0x05); +}