summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorMateusz Kijowski <mateusz@kijowski.info>2018-06-29 01:32:02 +0200
committerDamien George <damien.p.george@gmail.com>2018-07-05 19:39:06 +1000
commit1751f5ac7bd48f5673791801b052487ae73d064d (patch)
tree5d49f220c40773eab619c67e4f907cf09ecb0cb5
parent14ab81e87accedfb9ed231b206dd21f3a0143404 (diff)
downloadmicropython-1751f5ac7bd48f5673791801b052487ae73d064d.tar.gz
micropython-1751f5ac7bd48f5673791801b052487ae73d064d.zip
drivers/sdcard: Do not release CS during the middle of read operations.
It seems that some cards do not tolerate releasing the card (by setting CS high) after issuing CMD17 (and 18) and raising it again before reading data. Somehow this causes the 0xfe data start marker not being read and SDCard.readinto() is spinning forever (or until this byte is in the data). This seems to fix weird behviour of SDCard.readblocks() returning different data, also solved hanging os.mount() for my case with a 16GB Infineon card. This stackexchange answer gives more context: https://electronics.stackexchange.com/questions/307214/sd-card-spi-interface-issue-read-operation-returns-0x3f-0xff-instead-of-0x7f-0#307268
-rw-r--r--drivers/sdcard/sdcard.py13
1 files changed, 9 insertions, 4 deletions
diff --git a/drivers/sdcard/sdcard.py b/drivers/sdcard/sdcard.py
index fe402f7457..3eb62ee2fe 100644
--- a/drivers/sdcard/sdcard.py
+++ b/drivers/sdcard/sdcard.py
@@ -174,7 +174,7 @@ class SDCard:
# read until start byte (0xff)
while True:
self.spi.readinto(self.tokenbuf, 0xff)
- if self.tokenbuf[0] == 0xfe:
+ if self.tokenbuf[0] == _TOKEN_DATA:
break
# read data
@@ -228,17 +228,22 @@ class SDCard:
assert nblocks and not len(buf) % 512, 'Buffer length is invalid'
if nblocks == 1:
# CMD17: set read address for single block
- if self.cmd(17, block_num * self.cdv, 0) != 0:
+ if self.cmd(17, block_num * self.cdv, 0, release=False) != 0:
+ # release the card
+ self.cs(1)
raise OSError(5) # EIO
- # receive the data
+ # receive the data and release card
self.readinto(buf)
else:
# CMD18: set read address for multiple blocks
- if self.cmd(18, block_num * self.cdv, 0) != 0:
+ if self.cmd(18, block_num * self.cdv, 0, release=False) != 0:
+ # release the card
+ self.cs(1)
raise OSError(5) # EIO
offset = 0
mv = memoryview(buf)
while nblocks:
+ # receive the data and release card
self.readinto(mv[offset : offset + 512])
offset += 512
nblocks -= 1