Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CRC support added #75

Merged
merged 2 commits into from
Mar 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ The following versions of the mbed-os and sd-driver repositories are known to wo
- {mbed-os, sd-driver} = {mbed-os-5.5.1, sd-driver-0.1.0-mbed-os-5.5.1}.
- {mbed-os, sd-driver} = {mbed-os-5.5.4, sd-driver-0.1.1-mbed-os-5.5.4}.
- {mbed-os, sd-driver} = {mbed-os-5.6.1, sd-driver-0.1.2-mbed-os-5.6.1}.
- {mbed-os, sd-driver} = {mbed-os-5.8.0, sd-driver-0.1.3-mbed-os-5.8.0}.

To find the latest compatible versions, use the following command to see the messages attached to the tags
in the sd-driver repository:
Expand All @@ -97,7 +98,7 @@ in the sd-driver repository:
sd-driver-0.0.3-mbed-os-5.4.1 Version compatible with mbed-os-5.4.1.
sd-driver-0.1.1-mbed-os-5.5.4 Version compatible with mbed-os-5.5.4
sd-driver-0.1.2-mbed-os-5.6.1 Version compatible with mbed-os-5.6.1

sd-driver-0.1.3-mbed-os-5.8.0 Version compatible with mbed-os-5.8.0

### Known Issues With This Document

Expand Down
104 changes: 74 additions & 30 deletions SDBlockDevice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,13 @@
#include "mbed_debug.h"
#include <errno.h>

/* Required version: 5.6.1 and above */
#if defined(MBED_MAJOR_VERSION) && MBED_MAJOR_VERSION >= 5
#if (MBED_VERSION < MBED_ENCODE_VERSION(5,6,1))
#error "Incompatible mbed-os version detected! Required 5.6.1 and above"
/* Required version: 5.8.0 and above */
#if defined( MBED_MAJOR_VERSION) && MBED_MAJOR_VERSION >= 5
#if (MBED_VERSION < MBED_ENCODE_VERSION(5,8,0))
#error "Incompatible mbed-os version detected! Required 5.8.0 and above"
#endif
#else
#warning "mbed-os version 5.6.1 or above required"
#warning "mbed-os version 5.8.0 or above required"
#endif

#ifndef MBED_CONF_SD_CMD_TIMEOUT
Expand All @@ -164,12 +164,12 @@
#define SD_DBG 0 /*!< 1 - Enable debugging */
#define SD_CMD_TRACE 0 /*!< 1 - Enable SD command tracing */

#define SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */
#define SD_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */
#define SD_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */
#define SD_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */
#define SD_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */
#define SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */
#define SD_BLOCK_DEVICE_ERROR_WOULD_BLOCK -5001 /*!< operation would block */
#define SD_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */
#define SD_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */
#define SD_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */
#define SD_BLOCK_DEVICE_ERROR_NO_DEVICE -5005 /*!< device is missing or not connected */
#define SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */
#define SD_BLOCK_DEVICE_ERROR_UNUSABLE -5007 /*!< unusable card */
#define SD_BLOCK_DEVICE_ERROR_NO_RESPONSE -5008 /*!< No response from device */
#define SD_BLOCK_DEVICE_ERROR_CRC -5009 /*!< CRC error */
Expand All @@ -178,7 +178,6 @@

#define BLOCK_SIZE_HC 512 /*!< Block size supported for SD card is 512 bytes */
#define WRITE_BL_PARTIAL 0 /*!< Partial block write - Not supported */
#define CRC_SUPPORT 0 /*!< CRC - Not supported */
#define SPI_CMD(x) (0x40 | (x & 0x3f))

/* R1 Response Format */
Expand Down Expand Up @@ -244,8 +243,9 @@
#define SPI_READ_ERROR_ECC_C (0x1 << 2) /*!< Card ECC failed */
#define SPI_READ_ERROR_OFR (0x1 << 3) /*!< Out of Range */

SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz)
: _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0)
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on)
: _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0),
_crc_on(crc_on), _crc16(0, 0, false, false)
{
_cs = 1;
_card_type = SDCARD_NONE;
Expand Down Expand Up @@ -289,6 +289,11 @@ int SDBlockDevice::_initialise_card()
return status;
}

if (_crc_on) {
// Enable CRC
status = _cmd(CMD59_CRC_ON_OFF, _crc_on);
}

// Read OCR - CMD58 Response contains OCR register
if (BD_ERROR_OK != (status = _cmd(CMD58_READ_OCR, 0x0, 0x0, &response))) {
return status;
Expand Down Expand Up @@ -341,16 +346,18 @@ int SDBlockDevice::_initialise_card()
debug_if(SD_DBG, "Card Initialized: Version 1.x Card\n");
}

// Disable CRC
status = _cmd(CMD59_CRC_ON_OFF, 0);

if (!_crc_on) {
// Disable CRC
status = _cmd(CMD59_CRC_ON_OFF, _crc_on);
}
return status;
}


int SDBlockDevice::init()
{
lock();

int err = _initialise_card();
_is_initialized = (err == BD_ERROR_OK);
if (!_is_initialized) {
Expand Down Expand Up @@ -609,25 +616,32 @@ int SDBlockDevice::_freq(void)
uint8_t SDBlockDevice::_cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg) {
uint8_t response;
char cmdPacket[PACKET_SIZE];
uint32_t crc;

// Prepare the command packet
cmdPacket[0] = SPI_CMD(cmd);
cmdPacket[1] = (arg >> 24);
cmdPacket[2] = (arg >> 16);
cmdPacket[3] = (arg >> 8);
cmdPacket[4] = (arg >> 0);
// CMD0 is executed in SD mode, hence should have correct CRC
// CMD8 CRC verification is always enabled
switch(cmd) {
case CMD0_GO_IDLE_STATE:
cmdPacket[5] = 0x95;
break;
case CMD8_SEND_IF_COND:
cmdPacket[5] = 0x87;
break;
default:
cmdPacket[5] = 0xFF; // Make sure bit 0-End bit is high
break;

if (_crc_on) {
_crc7.compute((void *)cmdPacket, 5, &crc);
cmdPacket[5] = (char)(crc | 0x01);
} else {
// CMD0 is executed in SD mode, hence should have correct CRC
// CMD8 CRC verification is always enabled
switch(cmd) {
case CMD0_GO_IDLE_STATE:
cmdPacket[5] = 0x95;
break;
case CMD8_SEND_IF_COND:
cmdPacket[5] = 0x87;
break;
default:
cmdPacket[5] = 0xFF; // Make sure bit 0-End bit is high
break;
}
}

// send a command
Expand Down Expand Up @@ -823,6 +837,18 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length) {
crc = (_spi.write(SPI_FILL_CHAR) << 8);
crc |= _spi.write(SPI_FILL_CHAR);

if (_crc_on) {
uint32_t crc_result;
// Compute and verify checksum
_crc16.compute((void *)buffer, length, &crc_result);
if ((uint16_t)crc_result != crc) {
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%x result of computation 0x%x\n",
crc, crc_result);
_deselect();
return SD_BLOCK_DEVICE_ERROR_CRC;
}
}

_deselect();
return 0;
}
Expand All @@ -844,11 +870,23 @@ int SDBlockDevice::_read(uint8_t *buffer, uint32_t length) {
crc = (_spi.write(SPI_FILL_CHAR) << 8);
crc |= _spi.write(SPI_FILL_CHAR);

if (_crc_on) {
uint32_t crc_result;
// Compute and verify checksum
_crc16.compute((void *)buffer, length, &crc_result);
if ((uint16_t)crc_result != crc) {
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%x result of computation 0x%x\n",
crc, crc_result);
return SD_BLOCK_DEVICE_ERROR_CRC;
}
}

return 0;
}

uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t length) {
uint16_t crc = 0xFFFF;

uint32_t crc = (~0);
uint8_t response = 0xFF;

// indicate start of block
Expand All @@ -857,10 +895,16 @@ uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t len
// write the data
_spi.write((char*)buffer, length, NULL, 0);

if (_crc_on) {
// Compute CRC
_crc16.compute((void *)buffer, length, &crc);
}

// write the checksum CRC16
_spi.write(crc >> 8);
_spi.write(crc);


// check the response token
response = _spi.write(SPI_FILL_CHAR);

Expand Down
6 changes: 5 additions & 1 deletion SDBlockDevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class SDBlockDevice : public BlockDevice {
public:
/** Lifetime of an SD card
*/
SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz=1000000);
SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz=1000000, bool crc_on=0);
virtual ~SDBlockDevice();

/** Initialize a block device
Expand Down Expand Up @@ -225,6 +225,10 @@ class SDBlockDevice : public BlockDevice {
bd_size_t _erase_size;
bool _is_initialized;
bool _dbg;
bool _crc_on;

MbedCRC<POLY_7BIT_SD, 7> _crc7;
MbedCRC<POLY_16BIT_CCITT, 16> _crc16;
};

#endif /* DEVICE_SPI */
Expand Down