@@ -81,6 +81,7 @@ class SDCard:
81
81
82
82
:param ~busio.SPI spi: The SPI bus
83
83
:param ~digitalio.DigitalInOut cs: The chip select connected to the card
84
+ :param int freq: The SPI data rate to use after card setup
84
85
85
86
Example usage:
86
87
@@ -99,8 +100,8 @@ class SDCard:
99
100
os.listdir('/')
100
101
101
102
"""
102
- def __init__ (self , spi , cs ):
103
- # This is the init baudrate. We create a second device for high speed.
103
+ def __init__ (self , spi , cs , freq = 1320000 ):
104
+ # This is the init baudrate. We create a second device with baudrate=freq for high speed.
104
105
self ._spi = spi_device .SPIDevice (spi , cs , baudrate = 250000 , extra_clocks = 8 )
105
106
106
107
self ._cmdbuf = bytearray (6 )
@@ -109,8 +110,8 @@ def __init__(self, spi, cs):
109
110
# Card is byte addressing, set to 1 if addresses are per block
110
111
self ._cdv = 512
111
112
112
- # initialise the card
113
- self ._init_card ()
113
+ # initialise the card and switch to high speed
114
+ self ._init_card (freq )
114
115
115
116
def _clock_card (self , cycles = 8 ):
116
117
"""
@@ -128,7 +129,7 @@ def _clock_card(self, cycles=8):
128
129
self ._spi .spi .write (self ._single_byte )
129
130
self ._spi .spi .unlock ()
130
131
131
- def _init_card (self ):
132
+ def _init_card (self , freq ):
132
133
"""Initialize the card in SPI mode."""
133
134
# clock card at least cycles with cs high
134
135
self ._clock_card (80 )
@@ -174,7 +175,7 @@ def _init_card(self):
174
175
175
176
# set to high data rate now that it's initialised
176
177
self ._spi = spi_device .SPIDevice (self ._spi .spi , self ._spi .chip_select ,
177
- baudrate = 1320000 , extra_clocks = 8 )
178
+ baudrate = freq , extra_clocks = 8 )
178
179
179
180
def _init_card_v1 (self ):
180
181
"""Initialize v1 SDCards which use byte addressing."""
@@ -210,7 +211,7 @@ def _wait_for_ready(self, spi, timeout=0.3):
210
211
:param float timeout: Maximum time to wait in seconds.
211
212
"""
212
213
start_time = time .monotonic ()
213
- self ._single_byte [ 0 ] = 0x00
214
+ spi . readinto ( self ._single_byte , write_value = 0xff )
214
215
while time .monotonic () - start_time < timeout and self ._single_byte [0 ] != 0xff :
215
216
spi .readinto (self ._single_byte , write_value = 0xff )
216
217
@@ -253,6 +254,7 @@ def _cmd(self, cmd, arg=0, crc=0, response_buf=None, data_block=True, wait=True)
253
254
if response_buf :
254
255
if data_block :
255
256
# Wait for the start block byte
257
+ spi .readinto (buf , start = 1 , end = 2 , write_value = 0xff )
256
258
while buf [1 ] != 0xfe :
257
259
spi .readinto (buf , start = 1 , end = 2 , write_value = 0xff )
258
260
spi .readinto (response_buf , write_value = 0xff )
@@ -341,7 +343,7 @@ def _readinto(self, buf, start=0, end=None):
341
343
end = len (buf )
342
344
with self ._spi as spi :
343
345
# read until start byte (0xfe)
344
- buf [ start ] = 0xff #busy
346
+ spi . readinto ( buf , start = start , end = start + 1 , write_value = 0xff )
345
347
while buf [start ] != 0xfe :
346
348
spi .readinto (buf , start = start , end = start + 1 , write_value = 0xff )
347
349
@@ -456,17 +458,13 @@ def writeblocks(self, start_block, buf):
456
458
self ._cmd_nodata (_TOKEN_STOP_TRAN , 0x0 )
457
459
return 0
458
460
459
- def calculate_crc (message ):
460
- """
461
- Calculate the CRC of a message.
462
- :param bytearray message: Where each index is a byte
463
- """
461
+ def _calculate_crc_table ():
462
+ """Precompute the table used in calculate_crc."""
464
463
# Code converted from https://github.com/hazelnusse/crc7/blob/master/crc7.cc by devoh747
465
464
# With permission from Dale Lukas Peterson <[email protected] >
466
465
# 8/6/2019
467
466
468
467
crc_table = bytearray (256 )
469
-
470
468
crc_poly = const (0x89 ) # the value of our CRC-7 polynomial
471
469
472
470
# generate a table value for all 256 possible byte values
@@ -479,10 +477,19 @@ def calculate_crc(message):
479
477
crc_table [i ] = crc_table [i ] << 1
480
478
if (crc_table [i ] & 0x80 ):
481
479
crc_table [i ] = crc_table [i ] ^ crc_poly
480
+ return crc_table
481
+
482
+ CRC_TABLE = _calculate_crc_table ()
483
+
484
+ def calculate_crc (message ):
485
+ """
486
+ Calculate the CRC of message[0:5], using a precomputed table in CRC_TABLE.
487
+ :param bytearray message: Where each index is a byte
488
+ """
482
489
483
490
crc = 0
484
491
# All messages in _cmd are 5 bytes including the cmd.. The 6th byte is the crc value.
485
492
for i in range (0 , 5 ):
486
- crc = crc_table [(crc << 1 ) ^ message [i ]]
493
+ crc = CRC_TABLE [(crc << 1 ) ^ message [i ]]
487
494
488
495
return ((crc << 1 ) | 1 )
0 commit comments