142
142
#include " mbed_debug.h"
143
143
#include < errno.h>
144
144
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"
149
149
#endif
150
150
#else
151
- #warning "mbed-os version 5.6.1 or above required"
151
+ #warning "mbed-os version 5.8.0 or above required"
152
152
#endif
153
153
154
154
#ifndef MBED_CONF_SD_CMD_TIMEOUT
164
164
#define SD_DBG 0 /* !< 1 - Enable debugging */
165
165
#define SD_CMD_TRACE 0 /* !< 1 - Enable SD command tracing */
166
166
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 */
173
173
#define SD_BLOCK_DEVICE_ERROR_UNUSABLE -5007 /* !< unusable card */
174
174
#define SD_BLOCK_DEVICE_ERROR_NO_RESPONSE -5008 /* !< No response from device */
175
175
#define SD_BLOCK_DEVICE_ERROR_CRC -5009 /* !< CRC error */
178
178
179
179
#define BLOCK_SIZE_HC 512 /* !< Block size supported for SD card is 512 bytes */
180
180
#define WRITE_BL_PARTIAL 0 /* !< Partial block write - Not supported */
181
- #define CRC_SUPPORT 0 /* !< CRC - Not supported */
182
181
#define SPI_CMD (x ) (0x40 | (x & 0x3f ))
183
182
184
183
/* R1 Response Format */
244
243
#define SPI_READ_ERROR_ECC_C (0x1 << 2 ) /* !< Card ECC failed */
245
244
#define SPI_READ_ERROR_OFR (0x1 << 3 ) /* !< Out of Range */
246
245
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 )
249
249
{
250
250
_cs = 1 ;
251
251
_card_type = SDCARD_NONE;
@@ -289,6 +289,11 @@ int SDBlockDevice::_initialise_card()
289
289
return status;
290
290
}
291
291
292
+ if (_crc_on) {
293
+ // Enable CRC
294
+ status = _cmd (CMD59_CRC_ON_OFF, _crc_on);
295
+ }
296
+
292
297
// Read OCR - CMD58 Response contains OCR register
293
298
if (BD_ERROR_OK != (status = _cmd (CMD58_READ_OCR, 0x0 , 0x0 , &response))) {
294
299
return status;
@@ -341,16 +346,18 @@ int SDBlockDevice::_initialise_card()
341
346
debug_if (SD_DBG, " Card Initialized: Version 1.x Card\n " );
342
347
}
343
348
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
+ }
347
353
return status;
348
354
}
349
355
350
356
351
357
int SDBlockDevice::init ()
352
358
{
353
359
lock ();
360
+
354
361
int err = _initialise_card ();
355
362
_is_initialized = (err == BD_ERROR_OK);
356
363
if (!_is_initialized) {
@@ -609,25 +616,32 @@ int SDBlockDevice::_freq(void)
609
616
uint8_t SDBlockDevice::_cmd_spi (SDBlockDevice::cmdSupported cmd, uint32_t arg) {
610
617
uint8_t response;
611
618
char cmdPacket[PACKET_SIZE];
619
+ uint32_t crc;
612
620
613
621
// Prepare the command packet
614
622
cmdPacket[0 ] = SPI_CMD (cmd);
615
623
cmdPacket[1 ] = (arg >> 24 );
616
624
cmdPacket[2 ] = (arg >> 16 );
617
625
cmdPacket[3 ] = (arg >> 8 );
618
626
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
+ }
631
645
}
632
646
633
647
// send a command
@@ -823,6 +837,18 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length) {
823
837
crc = (_spi.write (SPI_FILL_CHAR) << 8 );
824
838
crc |= _spi.write (SPI_FILL_CHAR);
825
839
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
+
826
852
_deselect ();
827
853
return 0 ;
828
854
}
@@ -844,11 +870,23 @@ int SDBlockDevice::_read(uint8_t *buffer, uint32_t length) {
844
870
crc = (_spi.write (SPI_FILL_CHAR) << 8 );
845
871
crc |= _spi.write (SPI_FILL_CHAR);
846
872
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
+
847
884
return 0 ;
848
885
}
849
886
850
887
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 );
852
890
uint8_t response = 0xFF ;
853
891
854
892
// indicate start of block
@@ -857,10 +895,16 @@ uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t len
857
895
// write the data
858
896
_spi.write ((char *)buffer, length, NULL , 0 );
859
897
898
+ if (_crc_on) {
899
+ // Compute CRC
900
+ _crc16.compute ((void *)buffer, length, &crc);
901
+ }
902
+
860
903
// write the checksum CRC16
861
904
_spi.write (crc >> 8 );
862
905
_spi.write (crc);
863
906
907
+
864
908
// check the response token
865
909
response = _spi.write (SPI_FILL_CHAR);
866
910
0 commit comments