kopia lustrzana https://github.com/micropython/micropython-lib
Add CRC7 values for SDCard.cmd() function calls
Seems to be needed for some SDXC cards (SanDisk Ultra SDXC) Signed-off-by: multicoder9 <205438007+multicoder9@users.noreply.github.com>pull/992/head
rodzic
96e17b65d1
commit
3ddee7c04f
|
@ -37,6 +37,20 @@ _TOKEN_CMD25 = const(0xFC)
|
||||||
_TOKEN_STOP_TRAN = const(0xFD)
|
_TOKEN_STOP_TRAN = const(0xFD)
|
||||||
_TOKEN_DATA = const(0xFE)
|
_TOKEN_DATA = const(0xFE)
|
||||||
|
|
||||||
|
## This function computes crc7 for SDcard commands
|
||||||
|
## It is not optimized, so do not call it where performance is critical
|
||||||
|
## You should usually be precomputing these values and hardcode them
|
||||||
|
#def crc7( cmd:bytes ):
|
||||||
|
# crc = 0
|
||||||
|
# for value in cmd:
|
||||||
|
# for i in range(8):
|
||||||
|
# crc <<= 1
|
||||||
|
# if (value&0x80)^(crc&0x80):
|
||||||
|
# crc ^= 0x09
|
||||||
|
# value <<= 1
|
||||||
|
# return ((crc<<1)|1)&0xFF
|
||||||
|
#def cmd_args_to_bytes( cmd:int, args:int ):
|
||||||
|
# return bytes( [cmd|0x40,(args>>24)&0xFF,(args>>16)&0xFF,(args>>8)&0xFF,args&0xFF] )
|
||||||
|
|
||||||
class SDCard:
|
class SDCard:
|
||||||
def __init__(self, spi, cs, baudrate=1320000):
|
def __init__(self, spi, cs, baudrate=1320000):
|
||||||
|
@ -92,7 +106,7 @@ class SDCard:
|
||||||
|
|
||||||
# get the number of sectors
|
# get the number of sectors
|
||||||
# CMD9: response R2 (R1 byte + 16-byte block read)
|
# CMD9: response R2 (R1 byte + 16-byte block read)
|
||||||
if self.cmd(9, 0, 0, 0, False) != 0:
|
if self.cmd(9, 0, 0xAF, 0, False) != 0:
|
||||||
raise OSError("no response from SD card")
|
raise OSError("no response from SD card")
|
||||||
csd = bytearray(16)
|
csd = bytearray(16)
|
||||||
self.readinto(csd)
|
self.readinto(csd)
|
||||||
|
@ -109,7 +123,7 @@ class SDCard:
|
||||||
# print('sectors', self.sectors)
|
# print('sectors', self.sectors)
|
||||||
|
|
||||||
# CMD16: set block length to 512 bytes
|
# CMD16: set block length to 512 bytes
|
||||||
if self.cmd(16, 512, 0) != 0:
|
if self.cmd(16, 512, 0x15) != 0:
|
||||||
raise OSError("can't set 512 block size")
|
raise OSError("can't set 512 block size")
|
||||||
|
|
||||||
# set to high data rate now that it's initialised
|
# set to high data rate now that it's initialised
|
||||||
|
@ -118,8 +132,8 @@ class SDCard:
|
||||||
def init_card_v1(self):
|
def init_card_v1(self):
|
||||||
for i in range(_CMD_TIMEOUT):
|
for i in range(_CMD_TIMEOUT):
|
||||||
time.sleep_ms(50)
|
time.sleep_ms(50)
|
||||||
self.cmd(55, 0, 0)
|
self.cmd(55, 0, 0x65)
|
||||||
if self.cmd(41, 0, 0) == 0:
|
if self.cmd(41, 0, 0xE5) == 0:
|
||||||
# SDSC card, uses byte addressing in read/write/erase commands
|
# SDSC card, uses byte addressing in read/write/erase commands
|
||||||
self.cdv = 512
|
self.cdv = 512
|
||||||
# print("[SDCard] v1 card")
|
# print("[SDCard] v1 card")
|
||||||
|
@ -129,10 +143,10 @@ class SDCard:
|
||||||
def init_card_v2(self):
|
def init_card_v2(self):
|
||||||
for i in range(_CMD_TIMEOUT):
|
for i in range(_CMD_TIMEOUT):
|
||||||
time.sleep_ms(50)
|
time.sleep_ms(50)
|
||||||
self.cmd(58, 0, 0, 4)
|
self.cmd(58, 0, 0xFD, 4)
|
||||||
self.cmd(55, 0, 0)
|
self.cmd(55, 0, 0x65)
|
||||||
if self.cmd(41, 0x40000000, 0) == 0:
|
if self.cmd(41, 0x40000000, 0x77) == 0:
|
||||||
self.cmd(58, 0, 0, -4) # 4-byte response, negative means keep the first byte
|
self.cmd(58, 0, 0xFD, -4) # 4-byte response, negative means keep the first byte
|
||||||
ocr = self.tokenbuf[0] # get first byte of response, which is OCR
|
ocr = self.tokenbuf[0] # get first byte of response, which is OCR
|
||||||
if not ocr & 0x40:
|
if not ocr & 0x40:
|
||||||
# SDSC card, uses byte addressing in read/write/erase commands
|
# SDSC card, uses byte addressing in read/write/erase commands
|
||||||
|
@ -250,7 +264,7 @@ 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, release=False) != 0:
|
if self.cmd(17, block_num * self.cdv, 0x7F, release=False) != 0:
|
||||||
# release the card
|
# release the card
|
||||||
self.cs(1)
|
self.cs(1)
|
||||||
raise OSError(5) # EIO
|
raise OSError(5) # EIO
|
||||||
|
@ -258,7 +272,7 @@ class SDCard:
|
||||||
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, release=False) != 0:
|
if self.cmd(18, block_num * self.cdv, 0x7F, release=False) != 0:
|
||||||
# release the card
|
# release the card
|
||||||
self.cs(1)
|
self.cs(1)
|
||||||
raise OSError(5) # EIO
|
raise OSError(5) # EIO
|
||||||
|
@ -269,7 +283,7 @@ class SDCard:
|
||||||
self.readinto(mv[offset : offset + 512])
|
self.readinto(mv[offset : offset + 512])
|
||||||
offset += 512
|
offset += 512
|
||||||
nblocks -= 1
|
nblocks -= 1
|
||||||
if self.cmd(12, 0, 0xFF, skip1=True):
|
if self.cmd(12, 0, 0x61, skip1=True):
|
||||||
raise OSError(5) # EIO
|
raise OSError(5) # EIO
|
||||||
|
|
||||||
def writeblocks(self, block_num, buf):
|
def writeblocks(self, block_num, buf):
|
||||||
|
|
Ładowanie…
Reference in New Issue