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.
Dependencies: FATFileSystem
Fork of SDFileSystem by
Revision 6:55a26a56046a, committed 2014-08-01
- Comitter:
- neilt6
- Date:
- Fri Aug 01 14:45:21 2014 +0000
- Parent:
- 5:6befff2300d0
- Child:
- 7:61db99e52c0d
- Commit message:
- Added the option to disable CRC, and enable 16-bit frames for data read/write operations
Changed in this revision
| SDFileSystem.cpp | Show annotated file Show diff for this revision Revisions of this file |
| SDFileSystem.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/SDFileSystem.cpp Thu Jul 31 17:40:50 2014 +0000
+++ b/SDFileSystem.cpp Fri Aug 01 14:45:21 2014 +0000
@@ -19,12 +19,13 @@
#include "CRC7.h"
#include "CRC16.h"
-SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name, PinName cd, SwitchType cdtype, int hz) : FATFileSystem(name), m_SPI(mosi, miso, sclk), m_CS(cs, 1), m_CD(cd), m_CD_ASSERT((int)cdtype)
+SDFileSystem::SDFileSystem(PinName mosi, PinName miso, PinName sclk, PinName cs, const char* name, PinName cd, SwitchType cdtype, int hz) : FATFileSystem(name), m_SPI(mosi, miso, sclk), m_CS(cs, 1), m_CD(cd), m_CD_ASSERT((int)cdtype), m_FREQ(hz)
{
//Initialize the member variables
- m_SpiFreq = hz;
+ m_CardType = CARD_NONE;
+ m_CrcEnabled = true;
+ m_LargeFrames = false;
m_Status = STA_NOINIT;
- m_CardType = CARD_NONE;
//Configure the SPI bus
m_SPI.format(8, 0);
@@ -50,6 +51,47 @@
return m_CardType;
}
+bool SDFileSystem::crc_enabled()
+{
+ //Return whether or not CRC is enabled
+ return m_CrcEnabled;
+}
+
+void SDFileSystem::crc_enabled(bool enabled)
+{
+ //Check the card socket
+ checkSocket();
+
+ //Just update the member variable if the card isn't initialized
+ if (m_Status & STA_NOINIT) {
+ m_CrcEnabled = enabled;
+ return;
+ }
+
+ //Enable or disable CRC
+ if (!m_CrcEnabled && enabled) {
+ //Send CMD59(0x00000001) to enable CRC
+ writeCommand(CMD59, 0x00000001);
+ m_CrcEnabled = true;
+ } else if (m_CrcEnabled && !enabled) {
+ //Send CMD59(0x00000000) to disable CRC
+ writeCommand(CMD59, 0x00000000);
+ m_CrcEnabled = false;
+ }
+}
+
+bool SDFileSystem::large_frames()
+{
+ //Return whether or not 16-bit frames are enabled
+ return m_LargeFrames;
+}
+
+void SDFileSystem::large_frames(bool enabled)
+{
+ //Set whether or not 16-bit frames are enabled
+ m_LargeFrames = enabled;
+}
+
int SDFileSystem::disk_initialize()
{
char resp;
@@ -168,12 +210,14 @@
}
}
- //Send CMD59(0x00000001) to re-enable CRC
- resp = writeCommand(CMD59, 0x00000001);
- if (resp != 0x00) {
- //Initialization failed
- m_CardType = CARD_UNKNOWN;
- return m_Status;
+ //Send CMD59(0x00000001) to enable CRC if necessary
+ if (m_CrcEnabled) {
+ resp = writeCommand(CMD59, 0x00000001);
+ if (resp != 0x00) {
+ //Initialization failed
+ m_CardType = CARD_UNKNOWN;
+ return m_Status;
+ }
}
//Send CMD16(0x00000200) to force the block size to 512B if necessary
@@ -200,12 +244,12 @@
m_Status &= ~STA_NOINIT;
//Increase the SPI frequency to full speed (limited to 20MHz for MMC, or 25MHz for SDC)
- if (m_CardType == CARD_MMC && m_SpiFreq > 20000000)
+ if (m_CardType == CARD_MMC && m_FREQ > 20000000)
m_SPI.frequency(20000000);
- else if (m_SpiFreq > 25000000)
+ else if (m_FREQ > 25000000)
m_SPI.frequency(25000000);
else
- m_SPI.frequency(m_SpiFreq);
+ m_SPI.frequency(m_FREQ);
//Return the device status
return m_Status;
@@ -276,14 +320,31 @@
//Send the write data token
m_SPI.write(0xFE);
- //Write the data block from the buffer
- for (int b = 0; b < 512; b++)
- m_SPI.write(buffer[b]);
+ //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_CrcEnabled ? CRC16((char*)buffer, 512) : 0xFFFF);
- //Calculate the CRC16 checksum for the data block and send it
- unsigned short crc = CRC16((char*)buffer, 512);
- m_SPI.write(crc >> 8);
- 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]);
+
+ //Calculate the CRC16 checksum for the data block and send it (if enabled)
+ unsigned short crc = m_CrcEnabled ? 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;
@@ -426,7 +487,10 @@
cmdPacket[2] = arg >> 16;
cmdPacket[3] = arg >> 8;
cmdPacket[4] = arg;
- cmdPacket[5] = (CRC7(cmdPacket, 5) << 1) | 0x01;
+ if (m_CrcEnabled || cmd == CMD0 || cmd == CMD8)
+ cmdPacket[5] = (CRC7(cmdPacket, 5) << 1) | 0x01;
+ else
+ cmdPacket[5] = 0x01;
//Send the command packet
for (int b = 0; b < 6; b++)
@@ -472,6 +536,7 @@
bool SDFileSystem::readData(char* buffer, int length)
{
char token;
+ unsigned short crc;
//Wait for up to 200ms for the DataStart token to arrive
for (int i = 0; i < 200; i++) {
@@ -482,21 +547,42 @@
}
//Make sure the token is valid
- if (token != 0xFE)
+ if (token != 0xFE) {
+ deselect();
return false;
+ }
+
+ //Check if large frames are enabled or not
+ if (m_LargeFrames) {
+ //Switch to 16-bit frames for better performance
+ m_SPI.format(16, 0);
- //Read the data into the buffer
- for (int i = 0; i < length; i++)
- buffer[i] = m_SPI.write(0xFF);
+ //Read the data into the buffer
+ unsigned short dataWord;
+ for (int i = 0; i < length; i += 2) {
+ dataWord = m_SPI.write(0xFFFF);
+ buffer[i] = dataWord >> 8;
+ buffer[i + 1] = dataWord;
+ }
+
+ //Read the CRC16 checksum for the data block
+ crc = m_SPI.write(0xFFFF);
- //Read the CRC16 checksum for the data block, and deselect the card
- unsigned short crc = (m_SPI.write(0xFF) << 8);
- crc |= m_SPI.write(0xFF);
+ //Switch back to 8-bit frames
+ m_SPI.format(8, 0);
+ } else {
+ //Read the data into the buffer
+ for (int i = 0; i < length; i++)
+ buffer[i] = m_SPI.write(0xFF);
+
+ //Read the CRC16 checksum for the data block
+ crc = (m_SPI.write(0xFF) << 8);
+ crc |= m_SPI.write(0xFF);
+ }
+
+ //Deselect the card
deselect();
- //Indicate whether the CRC16 checksum was valid or not
- if (crc == CRC16(buffer, length))
- return true;
- else
- return false;
+ //Verify the CRC16 checksum (if enabled)
+ return (!m_CrcEnabled || crc == CRC16(buffer, length));
}
--- a/SDFileSystem.h Thu Jul 31 17:40:50 2014 +0000
+++ b/SDFileSystem.h Fri Aug 01 14:45:21 2014 +0000
@@ -30,7 +30,7 @@
* #include "SDFileSystem.h"
*
* //Create an SDFileSystem object
- * SDFileSystem sd(p5, p6, p7, p19, p20, "sd")
+ * SDFileSystem sd(p5, p6, p7, p20, "sd", p22)
*
* int main()
* {
@@ -100,6 +100,34 @@
*/
SDFileSystem::CardType card_type();
+ /** Get whether or not CRC is enabled for commands and data
+ *
+ * @returns
+ * 'true' if CRC is enabled for commands and data,
+ * 'false' if CRC is disabled for commands and data.
+ */
+ bool crc_enabled();
+
+ /** Set whether or not CRC is enabled for commands and data
+ *
+ * @param enabled Whether or not to enable CRC for commands and data.
+ */
+ void crc_enabled(bool enabled);
+
+ /** Get whether or not 16-bit frames are enabled for data read/write operations
+ *
+ * @returns
+ * 'true' if 16-bit frames will be used during data read/write operations,
+ * 'false' if 8-bit frames will be used during data read/write operations.
+ */
+ bool large_frames();
+
+ /** Set whether or not 16-bit frames are enabled for data read/write operations
+ *
+ * @param enabled Whether or not 16-bit frames are enabled for data read/write operations.
+ */
+ void large_frames(bool enabled);
+
virtual int disk_initialize();
virtual int disk_status();
virtual int disk_read(uint8_t* buffer, uint64_t sector);
@@ -129,9 +157,11 @@
DigitalOut m_CS;
InterruptIn m_CD;
const int m_CD_ASSERT;
- int m_SpiFreq;
+ const int m_FREQ;
+ SDFileSystem::CardType m_CardType;
+ bool m_CrcEnabled;
+ bool m_LargeFrames;
int m_Status;
- SDFileSystem::CardType m_CardType;
//Internal methods
void checkSocket();
