SD File System
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)); }