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
This commit is contained in:
parent
14ab81e87a
commit
1751f5ac7b
|
@ -174,7 +174,7 @@ class SDCard:
|
||||||
# read until start byte (0xff)
|
# read until start byte (0xff)
|
||||||
while True:
|
while True:
|
||||||
self.spi.readinto(self.tokenbuf, 0xff)
|
self.spi.readinto(self.tokenbuf, 0xff)
|
||||||
if self.tokenbuf[0] == 0xfe:
|
if self.tokenbuf[0] == _TOKEN_DATA:
|
||||||
break
|
break
|
||||||
|
|
||||||
# read data
|
# read data
|
||||||
|
@ -228,17 +228,22 @@ class SDCard:
|
||||||
assert nblocks and not len(buf) % 512, 'Buffer length is invalid'
|
assert nblocks and not len(buf) % 512, 'Buffer length is invalid'
|
||||||
if nblocks == 1:
|
if nblocks == 1:
|
||||||
# CMD17: set read address for single block
|
# 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
|
raise OSError(5) # EIO
|
||||||
# receive the data
|
# receive the data and release card
|
||||||
self.readinto(buf)
|
self.readinto(buf)
|
||||||
else:
|
else:
|
||||||
# CMD18: set read address for multiple blocks
|
# 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
|
raise OSError(5) # EIO
|
||||||
offset = 0
|
offset = 0
|
||||||
mv = memoryview(buf)
|
mv = memoryview(buf)
|
||||||
while nblocks:
|
while nblocks:
|
||||||
|
# receive the data and release card
|
||||||
self.readinto(mv[offset : offset + 512])
|
self.readinto(mv[offset : offset + 512])
|
||||||
offset += 512
|
offset += 512
|
||||||
nblocks -= 1
|
nblocks -= 1
|
||||||
|
|
Loading…
Reference in New Issue