CRC support added

pull/7774/head
Deepika 2017-12-06 16:26:18 -06:00
parent 10aac9f162
commit 1572c27131
3 changed files with 81 additions and 32 deletions

View File

@ -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.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.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.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 To find the latest compatible versions, use the following command to see the messages attached to the tags
in the sd-driver repository: in the sd-driver repository:
@ -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.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.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.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 ### Known Issues With This Document

View File

@ -142,13 +142,13 @@
#include "mbed_debug.h" #include "mbed_debug.h"
#include <errno.h> #include <errno.h>
/* Required version: 5.6.1 and above */ /* Required version: 5.8.1 and above */
#if defined(MBED_MAJOR_VERSION) && MBED_MAJOR_VERSION >= 5 #if defined( MBED_MAJOR_VERSION) && MBED_MAJOR_VERSION >= 5
#if (MBED_VERSION < MBED_ENCODE_VERSION(5,6,1)) #if (MBED_VERSION < MBED_ENCODE_VERSION(5,8,0))
#error "Incompatible mbed-os version detected! Required 5.6.1 and above" #error "Incompatible mbed-os version detected! Required 5.8.0 and above"
#endif #endif
#else #else
#warning "mbed-os version 5.6.1 or above required" #warning "mbed-os version 5.8.0 or above required"
#endif #endif
#ifndef MBED_CONF_SD_CMD_TIMEOUT #ifndef MBED_CONF_SD_CMD_TIMEOUT
@ -164,12 +164,12 @@
#define SD_DBG 0 /*!< 1 - Enable debugging */ #define SD_DBG 0 /*!< 1 - Enable debugging */
#define SD_CMD_TRACE 0 /*!< 1 - Enable SD command tracing */ #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_WOULD_BLOCK -5001 /*!< operation would block */
#define SD_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */ #define SD_BLOCK_DEVICE_ERROR_UNSUPPORTED -5002 /*!< unsupported operation */
#define SD_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */ #define SD_BLOCK_DEVICE_ERROR_PARAMETER -5003 /*!< invalid parameter */
#define SD_BLOCK_DEVICE_ERROR_NO_INIT -5004 /*!< uninitialized */ #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_NO_DEVICE -5005 /*!< device is missing or not connected */
#define SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */ #define SD_BLOCK_DEVICE_ERROR_WRITE_PROTECTED -5006 /*!< write protected */
#define SD_BLOCK_DEVICE_ERROR_UNUSABLE -5007 /*!< unusable card */ #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_NO_RESPONSE -5008 /*!< No response from device */
#define SD_BLOCK_DEVICE_ERROR_CRC -5009 /*!< CRC error */ #define SD_BLOCK_DEVICE_ERROR_CRC -5009 /*!< CRC error */
@ -178,7 +178,6 @@
#define BLOCK_SIZE_HC 512 /*!< Block size supported for SD card is 512 bytes */ #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 WRITE_BL_PARTIAL 0 /*!< Partial block write - Not supported */
#define CRC_SUPPORT 0 /*!< CRC - Not supported */
#define SPI_CMD(x) (0x40 | (x & 0x3f)) #define SPI_CMD(x) (0x40 | (x & 0x3f))
/* R1 Response Format */ /* R1 Response Format */
@ -244,8 +243,9 @@
#define SPI_READ_ERROR_ECC_C (0x1 << 2) /*!< Card ECC failed */ #define SPI_READ_ERROR_ECC_C (0x1 << 2) /*!< Card ECC failed */
#define SPI_READ_ERROR_OFR (0x1 << 3) /*!< Out of Range */ #define SPI_READ_ERROR_OFR (0x1 << 3) /*!< Out of Range */
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz) 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) : _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0),
_crc_on(crc_on), _crc16(0, 0, false, false)
{ {
_cs = 1; _cs = 1;
_card_type = SDCARD_NONE; _card_type = SDCARD_NONE;
@ -289,6 +289,11 @@ int SDBlockDevice::_initialise_card()
return status; return status;
} }
if (_crc_on) {
// Enable CRC
status = _cmd(CMD59_CRC_ON_OFF, _crc_on);
}
// Read OCR - CMD58 Response contains OCR register // Read OCR - CMD58 Response contains OCR register
if (BD_ERROR_OK != (status = _cmd(CMD58_READ_OCR, 0x0, 0x0, &response))) { if (BD_ERROR_OK != (status = _cmd(CMD58_READ_OCR, 0x0, 0x0, &response))) {
return status; return status;
@ -341,9 +346,10 @@ int SDBlockDevice::_initialise_card()
debug_if(SD_DBG, "Card Initialized: Version 1.x Card\n"); debug_if(SD_DBG, "Card Initialized: Version 1.x Card\n");
} }
// Disable CRC if (!_crc_on) {
status = _cmd(CMD59_CRC_ON_OFF, 0); // Disable CRC
status = _cmd(CMD59_CRC_ON_OFF, _crc_on);
}
return status; return status;
} }
@ -351,6 +357,7 @@ int SDBlockDevice::_initialise_card()
int SDBlockDevice::init() int SDBlockDevice::init()
{ {
lock(); lock();
int err = _initialise_card(); int err = _initialise_card();
_is_initialized = (err == BD_ERROR_OK); _is_initialized = (err == BD_ERROR_OK);
if (!_is_initialized) { if (!_is_initialized) {
@ -609,6 +616,7 @@ int SDBlockDevice::_freq(void)
uint8_t SDBlockDevice::_cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg) { uint8_t SDBlockDevice::_cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg) {
uint8_t response; uint8_t response;
char cmdPacket[PACKET_SIZE]; char cmdPacket[PACKET_SIZE];
uint32_t crc;
// Prepare the command packet // Prepare the command packet
cmdPacket[0] = SPI_CMD(cmd); cmdPacket[0] = SPI_CMD(cmd);
@ -616,18 +624,24 @@ uint8_t SDBlockDevice::_cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg) {
cmdPacket[2] = (arg >> 16); cmdPacket[2] = (arg >> 16);
cmdPacket[3] = (arg >> 8); cmdPacket[3] = (arg >> 8);
cmdPacket[4] = (arg >> 0); cmdPacket[4] = (arg >> 0);
// CMD0 is executed in SD mode, hence should have correct CRC
// CMD8 CRC verification is always enabled if (_crc_on) {
switch(cmd) { _crc7.compute((void *)cmdPacket, 5, &crc);
case CMD0_GO_IDLE_STATE: cmdPacket[5] = (char)(crc | 0x01);
cmdPacket[5] = 0x95; } else {
break; // CMD0 is executed in SD mode, hence should have correct CRC
case CMD8_SEND_IF_COND: // CMD8 CRC verification is always enabled
cmdPacket[5] = 0x87; switch(cmd) {
break; case CMD0_GO_IDLE_STATE:
default: cmdPacket[5] = 0x95;
cmdPacket[5] = 0xFF; // Make sure bit 0-End bit is high break;
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 // send a command
@ -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) << 8);
crc |= _spi.write(SPI_FILL_CHAR); 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(); _deselect();
return 0; return 0;
} }
@ -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) << 8);
crc |= _spi.write(SPI_FILL_CHAR); 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; return 0;
} }
uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t length) { 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; uint8_t response = 0xFF;
// indicate start of block // indicate start of block
@ -857,10 +895,16 @@ uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t len
// write the data // write the data
_spi.write((char*)buffer, length, NULL, 0); _spi.write((char*)buffer, length, NULL, 0);
if (_crc_on) {
// Compute CRC
_crc16.compute((void *)buffer, length, &crc);
}
// write the checksum CRC16 // write the checksum CRC16
_spi.write(crc >> 8); _spi.write(crc >> 8);
_spi.write(crc); _spi.write(crc);
// check the response token // check the response token
response = _spi.write(SPI_FILL_CHAR); response = _spi.write(SPI_FILL_CHAR);

View File

@ -45,7 +45,7 @@ class SDBlockDevice : public BlockDevice {
public: public:
/** Lifetime of an SD card /** 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(); virtual ~SDBlockDevice();
/** Initialize a block device /** Initialize a block device
@ -225,6 +225,10 @@ private:
bd_size_t _erase_size; bd_size_t _erase_size;
bool _is_initialized; bool _is_initialized;
bool _dbg; bool _dbg;
bool _crc_on;
MbedCRC<POLY_7BIT_SD, 7> _crc7;
MbedCRC<POLY_16BIT_CCITT, 16> _crc16;
}; };
#endif /* DEVICE_SPI */ #endif /* DEVICE_SPI */