Skip to content

Commit 1cb007f

Browse files
author
Deepika
authored
Merge pull request ARMmbed#61 from deepikabhavnani/sd_diff_cards
Deselecting card between read/write ops caused issues
2 parents 9edd43d + c46d077 commit 1cb007f

File tree

1 file changed

+28
-62
lines changed

1 file changed

+28
-62
lines changed

SDBlockDevice.cpp

Lines changed: 28 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -423,19 +423,16 @@ int SDBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
423423

424424
// Write data
425425
response = _write(buffer, SPI_START_BLOCK, _block_size);
426+
426427
// Only CRC and general write error are communicated via response token
427428
if ((response == SPI_DATA_CRC_ERROR) || (response == SPI_DATA_WRITE_ERROR)) {
428429
debug_if(SD_DBG, "Single Block Write failed: 0x%x \n", response);
429430
status = SD_BLOCK_DEVICE_ERROR_WRITE;
430431
}
431-
432-
/* Once the programming operation is completed, the host should check the
433-
* results of the programming using the SEND_STATUS command (CMD13).
434-
*/
435-
status = _cmd(CMD13_SEND_STATUS, 0);
436432
} else {
437433
// Pre-erase setting prior to multiple block write operation
438434
_cmd(ACMD23_SET_WR_BLK_ERASE_COUNT, blockCnt, 1);
435+
439436
// Multiple block write command
440437
if (BD_ERROR_OK != (status = _cmd(CMD25_WRITE_MULTIPLE_BLOCK, addr))) {
441438
_lock.unlock();
@@ -456,28 +453,10 @@ int SDBlockDevice::program(const void *b, bd_addr_t addr, bd_size_t size)
456453
* sending 'Stop Tran' token instead of 'Start Block' token at the beginning
457454
* of the next block
458455
*/
459-
_select();
460456
_spi.write(SPI_STOP_TRAN);
461-
_deselect();
462-
463-
// Wait for last block to be written
464-
if (false == _wait_ready(SD_COMMAND_TIMEOUT)) {
465-
debug_if(SD_DBG, "Card not ready yet \n");
466-
}
467-
468-
/* In case of Write Error indication (on the data response) the host shall
469-
* use SEND_NUM_WR_BLOCKS (ACMD22) in order to get the number of well written write blocks.
470-
*/
471-
if(response == SPI_DATA_WRITE_ERROR) {
472-
if (BD_ERROR_OK == _cmd(ACMD22_SEND_NUM_WR_BLOCKS, 0, 1)) {
473-
uint8_t wr_blocks[4];
474-
if (BD_ERROR_OK == _read_bytes(wr_blocks, 4)) {
475-
debug_if(_dbg, "Blocks Written without errors: 0x%x\n",
476-
((wr_blocks[0] << 24) | (wr_blocks[1] << 16) | (wr_blocks[2] << 0) | wr_blocks[3]));
477-
}
478-
}
479-
}
480457
}
458+
459+
_deselect();
481460
_lock.unlock();
482461
return status;
483462
}
@@ -504,27 +483,15 @@ int SDBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
504483
addr = addr / _block_size;
505484
}
506485

507-
for (uint8_t i = 0; i < 3; i++) {
508-
// Write command ro receive data
509-
if (blockCnt > 1) {
510-
status = _cmd(CMD18_READ_MULTIPLE_BLOCK, addr);
511-
} else {
512-
status = _cmd(CMD17_READ_SINGLE_BLOCK, addr);
513-
}
514-
if (BD_ERROR_OK != status) {
515-
_lock.unlock();
516-
return status;
517-
}
518-
519-
// For the first time in read if start token is not received
520-
// means command is lost, retry sending read command once more
521-
if (SD_BLOCK_DEVICE_ERROR_NO_RESPONSE == _read(buffer, _block_size)) {
522-
continue;
523-
} else {
524-
buffer += _block_size;
525-
--blockCnt;
526-
break;
527-
}
486+
// Write command ro receive data
487+
if (blockCnt > 1) {
488+
status = _cmd(CMD18_READ_MULTIPLE_BLOCK, addr);
489+
} else {
490+
status = _cmd(CMD17_READ_SINGLE_BLOCK, addr);
491+
}
492+
if (BD_ERROR_OK != status) {
493+
_lock.unlock();
494+
return status;
528495
}
529496

530497
// receive the data : one block at a time
@@ -536,6 +503,7 @@ int SDBlockDevice::read(void *b, bd_addr_t addr, bd_size_t size)
536503
buffer += _block_size;
537504
--blockCnt;
538505
}
506+
_deselect();
539507

540508
// Send CMD12(0x00000000) to stop the transmission for multi-block transfer
541509
if (size > _block_size) {
@@ -792,6 +760,13 @@ int SDBlockDevice::_cmd(SDBlockDevice::cmdSupported cmd, uint32_t arg, bool isAc
792760
*resp = response;
793761
}
794762

763+
// Do not deselect card if read is in progress.
764+
if (((CMD9_SEND_CSD == cmd) || (ACMD22_SEND_NUM_WR_BLOCKS == cmd) ||
765+
(CMD24_WRITE_BLOCK == cmd) || (CMD25_WRITE_MULTIPLE_BLOCK == cmd) ||
766+
(CMD17_READ_SINGLE_BLOCK == cmd) || (CMD18_READ_MULTIPLE_BLOCK == cmd))
767+
&& (BD_ERROR_OK == status)) {
768+
return BD_ERROR_OK;
769+
}
795770
// Deselect card
796771
_deselect();
797772
return status;
@@ -838,8 +813,6 @@ uint32_t SDBlockDevice::_go_idle_state() {
838813
int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length) {
839814
uint16_t crc;
840815

841-
_select();
842-
843816
// read until start byte (0xFE)
844817
if (false == _wait_token(SPI_START_BLOCK)) {
845818
debug_if(SD_DBG, "Read timeout\n");
@@ -863,8 +836,6 @@ int SDBlockDevice::_read_bytes(uint8_t *buffer, uint32_t length) {
863836
int SDBlockDevice::_read(uint8_t *buffer, uint32_t length) {
864837
uint16_t crc;
865838

866-
_select();
867-
868839
// read until start byte (0xFE)
869840
if (false == _wait_token(SPI_START_BLOCK)) {
870841
debug_if(SD_DBG, "Read timeout\n");
@@ -879,24 +850,13 @@ int SDBlockDevice::_read(uint8_t *buffer, uint32_t length) {
879850
crc = (_spi.write(SPI_FILL_CHAR) << 8);
880851
crc |= _spi.write(SPI_FILL_CHAR);
881852

882-
_deselect();
883853
return 0;
884854
}
885855

886856
uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t length) {
887857
uint16_t crc = 0xFFFF;
888858
uint8_t response = 0xFF;
889859

890-
// Select card
891-
_select();
892-
893-
/* If previous write is in progress, the card will drive DO low again when reselected.
894-
* Therefore a preceding busy check, check if card is busy prior to each command and
895-
* data packet, instead of post wait, can eliminate busy wait time */
896-
if( false == _wait_ready(SD_COMMAND_TIMEOUT)) {
897-
debug_if(SD_DBG, "Card not ready yet \n");
898-
}
899-
900860
// indicate start of block
901861
_spi.write(token);
902862

@@ -909,7 +869,12 @@ uint8_t SDBlockDevice::_write(const uint8_t *buffer, uint8_t token, uint32_t len
909869

910870
// check the response token
911871
response = _spi.write(SPI_FILL_CHAR);
912-
_deselect();
872+
873+
// Wait for last block to be written
874+
if (false == _wait_ready(SD_COMMAND_TIMEOUT)) {
875+
debug_if(SD_DBG, "Card not ready yet \n");
876+
}
877+
913878
return (response & SPI_DATA_RESPONSE_MASK);
914879
}
915880

@@ -1046,6 +1011,7 @@ void SDBlockDevice::_select() {
10461011

10471012
void SDBlockDevice::_deselect() {
10481013
_cs = 1;
1014+
_spi.write(SPI_FILL_CHAR);
10491015
_spi.unlock();
10501016
}
10511017

0 commit comments

Comments
 (0)