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:
- 6:55a26a56046a
- Parent:
- 5:6befff2300d0
- Child:
- 7:61db99e52c0d
--- 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)); }