Skip to content

Commit 1572c27

Browse files
author
Deepika
committed
CRC support added
1 parent 10aac9f commit 1572c27

File tree

3 files changed

+81
-32
lines changed

3 files changed

+81
-32
lines changed

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ The following versions of the mbed-os and sd-driver repositories are known to wo
8686
- {mbed-os, sd-driver} = {mbed-os-5.5.1, sd-driver-0.1.0-mbed-os-5.5.1}.
8787
- {mbed-os, sd-driver} = {mbed-os-5.5.4, sd-driver-0.1.1-mbed-os-5.5.4}.
8888
- {mbed-os, sd-driver} = {mbed-os-5.6.1, sd-driver-0.1.2-mbed-os-5.6.1}.
89+
- {mbed-os, sd-driver} = {mbed-os-5.8.0, sd-driver-0.1.3-mbed-os-5.8.0}.
8990

9091
To find the latest compatible versions, use the following command to see the messages attached to the tags
9192
in the sd-driver repository:
@@ -97,7 +98,7 @@ in the sd-driver repository:
9798
sd-driver-0.0.3-mbed-os-5.4.1 Version compatible with mbed-os-5.4.1.
9899
sd-driver-0.1.1-mbed-os-5.5.4 Version compatible with mbed-os-5.5.4
99100
sd-driver-0.1.2-mbed-os-5.6.1 Version compatible with mbed-os-5.6.1
100-
101+
sd-driver-0.1.3-mbed-os-5.8.0 Version compatible with mbed-os-5.8.0
101102

102103
### Known Issues With This Document
103104

SDBlockDevice.cpp

Lines changed: 74 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,13 @@
142142
#include "mbed_debug.h"
143143
#include <errno.h>
144144

145-
/* Required version: 5.6.1 and above */
146-
#if defined(MBED_MAJOR_VERSION) && MBED_MAJOR_VERSION >= 5
147-
#if (MBED_VERSION < MBED_ENCODE_VERSION(5,6,1))
148-
#error "Incompatible mbed-os version detected! Required 5.6.1 and above"
145+
/* Required version: 5.8.1 and above */
146+
#if defined( MBED_MAJOR_VERSION) && MBED_MAJOR_VERSION >= 5
147+
#if (MBED_VERSION < MBED_ENCODE_VERSION(5,8,0))
148+
#error "Incompatible mbed-os version detected! Required 5.8.0 and above"
149149
#endif
150150
#else
151-
#warning "mbed-os version 5.6.1 or above required"
151+
#warning "mbed-os version 5.8.0 or above required"
152152
#endif
153153

154154
#ifndef MBED_CONF_SD_CMD_TIMEOUT
@@ -164,12 +164,12 @@
164164
#define SD_DBG 0 /*!< 1 - Enable debugging */
165165
#define SD_CMD_TRACE 0 /*!< 1 - Enable SD command tracing */
166166

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

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

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

247-
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz)
248-
: _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0)
246+
SDBlockDevice::SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz, bool crc_on)
247+
: _sectors(0), _spi(mosi, miso, sclk), _cs(cs), _is_initialized(0),
248+
_crc_on(crc_on), _crc16(0, 0, false, false)
249249
{
250250
_cs = 1;
251251
_card_type = SDCARD_NONE;
@@ -289,6 +289,11 @@ int SDBlockDevice::_initialise_card()
289289
return status;
290290
}
291291

292+
if (_crc_on) {
293+
// Enable CRC
294+
status = _cmd(CMD59_CRC_ON_OFF, _crc_on);
295+
}
296+
292297
// Read OCR - CMD58 Response contains OCR register
293298
if (BD_ERROR_OK != (status = _cmd(CMD58_READ_OCR, 0x0, 0x0, &response))) {
294299
return status;
@@ -341,16 +346,18 @@ int SDBlockDevice::_initialise_card()
341346
debug_if(SD_DBG, "Card Initialized: Version 1.x Card\n");
342347
}
343348

344-
// Disable CRC
345-
status = _cmd(CMD59_CRC_ON_OFF, 0);
346-
349+
if (!_crc_on) {
350+
// Disable CRC
351+
status = _cmd(CMD59_CRC_ON_OFF, _crc_on);
352+
}
347353
return status;
348354
}
349355

350356

351357
int SDBlockDevice::init()
352358
{
353359
lock();
360+
354361
int err = _initialise_card();
355362
_is_initialized = (err == BD_ERROR_OK);
356363
if (!_is_initialized) {
@@ -609,25 +616,32 @@ int SDBlockDevice::_freq(void)
609616
uint8_t SDBlockDevice::_cmd_spi(SDBlockDevice::cmdSupported cmd, uint32_t arg) {
610617
uint8_t response;
611618
char cmdPacket[PACKET_SIZE];
619+
uint32_t crc;
612620

613621
// Prepare the command packet
614622
cmdPacket[0] = SPI_CMD(cmd);
615623
cmdPacket[1] = (arg >> 24);
616624
cmdPacket[2] = (arg >> 16);
617625
cmdPacket[3] = (arg >> 8);
618626
cmdPacket[4] = (arg >> 0);
619-
// CMD0 is executed in SD mode, hence should have correct CRC
620-
// CMD8 CRC verification is always enabled
621-
switch(cmd) {
622-
case CMD0_GO_IDLE_STATE:
623-
cmdPacket[5] = 0x95;
624-
break;
625-
case CMD8_SEND_IF_COND:
626-
cmdPacket[5] = 0x87;
627-
break;
628-
default:
629-
cmdPacket[5] = 0xFF; // Make sure bit 0-End bit is high
630-
break;
627+
628+
if (_crc_on) {
629+
_crc7.compute((void *)cmdPacket, 5, &crc);
630+
cmdPacket[5] = (char)(crc | 0x01);
631+
} else {
632+
// CMD0 is executed in SD mode, hence should have correct CRC
633+
// CMD8 CRC verification is always enabled
634+
switch(cmd) {
635+
case CMD0_GO_IDLE_STATE:
636+
cmdPacket[5] = 0x95;
637+
break;
638+
case CMD8_SEND_IF_COND:
639+
cmdPacket[5] = 0x87;
640+
break;
641+
default:
642+
cmdPacket[5] = 0xFF; // Make sure bit 0-End bit is high
643+
break;
644+
}
631645
}
632646

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

840+
if (_crc_on) {
841+
uint32_t crc_result;
842+
// Compute and verify checksum
843+
_crc16.compute((void *)buffer, length, &crc_result);
844+
if ((uint16_t)crc_result != crc) {
845+
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%x result of computation 0x%x\n",
846+
crc, crc_result);
847+
_deselect();
848+
return SD_BLOCK_DEVICE_ERROR_CRC;
849+
}
850+
}
851+
826852
_deselect();
827853
return 0;
828854
}
@@ -844,11 +870,23 @@ int SDBlockDevice::_read(uint8_t *buffer, uint32_t length) {
844870
crc = (_spi.write(SPI_FILL_CHAR) << 8);
845871
crc |= _spi.write(SPI_FILL_CHAR);
846872

873+
if (_crc_on) {
874+
uint32_t crc_result;
875+
// Compute and verify checksum
876+
_crc16.compute((void *)buffer, length, &crc_result);
877+
if ((uint16_t)crc_result != crc) {
878+
debug_if(SD_DBG, "_read_bytes: Invalid CRC received 0x%x result of computation 0x%x\n",
879+
crc, crc_result);
880+
return SD_BLOCK_DEVICE_ERROR_CRC;
881+
}
882+
}
883+
847884
return 0;
848885
}
849886

850887
uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t length) {
851-
uint16_t crc = 0xFFFF;
888+
889+
uint32_t crc = (~0);
852890
uint8_t response = 0xFF;
853891

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

898+
if (_crc_on) {
899+
// Compute CRC
900+
_crc16.compute((void *)buffer, length, &crc);
901+
}
902+
860903
// write the checksum CRC16
861904
_spi.write(crc >> 8);
862905
_spi.write(crc);
863906

907+
864908
// check the response token
865909
response = _spi.write(SPI_FILL_CHAR);
866910

SDBlockDevice.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class SDBlockDevice : public BlockDevice {
4545
public:
4646
/** Lifetime of an SD card
4747
*/
48-
SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz=1000000);
48+
SDBlockDevice(PinName mosi, PinName miso, PinName sclk, PinName cs, uint64_t hz=1000000, bool crc_on=0);
4949
virtual ~SDBlockDevice();
5050

5151
/** Initialize a block device
@@ -225,6 +225,10 @@ class SDBlockDevice : public BlockDevice {
225225
bd_size_t _erase_size;
226226
bool _is_initialized;
227227
bool _dbg;
228+
bool _crc_on;
229+
230+
MbedCRC<POLY_7BIT_SD, 7> _crc7;
231+
MbedCRC<POLY_16BIT_CCITT, 16> _crc16;
228232
};
229233

230234
#endif /* DEVICE_SPI */

0 commit comments

Comments
 (0)