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.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:
@ -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

View File

@ -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.1 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
@ -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 */
@ -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 */
@ -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;
@ -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;
@ -341,9 +346,10 @@ 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;
}
@ -351,6 +357,7 @@ int SDBlockDevice::_initialise_card()
int SDBlockDevice::init()
{
lock();
int err = _initialise_card();
_is_initialized = (err == BD_ERROR_OK);
if (!_is_initialized) {
@ -609,6 +616,7 @@ 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);
@ -616,18 +624,24 @@ uint8_t SDBlockDevice::_cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg) {
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
@ -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;
}
@ -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
@ -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);

View File

@ -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
@ -225,6 +225,10 @@ private:
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 */