65
65
_CMD_TIMEOUT = const (200 )
66
66
67
67
_R1_IDLE_STATE = const (1 << 0 )
68
- #R1_ERASE_RESET = const(1 << 1)
68
+ # R1_ERASE_RESET = const(1 << 1)
69
69
_R1_ILLEGAL_COMMAND = const (1 << 2 )
70
- #R1_COM_CRC_ERROR = const(1 << 3)
71
- #R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
72
- #R1_ADDRESS_ERROR = const(1 << 5)
73
- #R1_PARAMETER_ERROR = const(1 << 6)
74
- _TOKEN_CMD25 = const (0xfc )
75
- _TOKEN_STOP_TRAN = const (0xfd )
76
- _TOKEN_DATA = const (0xfe )
77
-
78
- #pylint: disable-msg=superfluous-parens
70
+ # R1_COM_CRC_ERROR = const(1 << 3)
71
+ # R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
72
+ # R1_ADDRESS_ERROR = const(1 << 5)
73
+ # R1_PARAMETER_ERROR = const(1 << 6)
74
+ _TOKEN_CMD25 = const (0xFC )
75
+ _TOKEN_STOP_TRAN = const (0xFD )
76
+ _TOKEN_DATA = const (0xFE )
77
+
78
+ # pylint: disable-msg=superfluous-parens
79
79
class SDCard :
80
80
"""Controls an SD card over SPI.
81
81
@@ -100,6 +100,7 @@ class SDCard:
100
100
os.listdir('/')
101
101
102
102
"""
103
+
103
104
def __init__ (self , spi , cs , baudrate = 1320000 ):
104
105
# This is the init baudrate.
105
106
# We create a second device with the target baudrate after card initialization.
@@ -125,7 +126,7 @@ def _clock_card(self, cycles=8):
125
126
self ._spi .spi .configure (baudrate = self ._spi .baudrate )
126
127
self ._spi .chip_select .value = True
127
128
128
- self ._single_byte [0 ] = 0xff
129
+ self ._single_byte [0 ] = 0xFF
129
130
for _ in range (cycles // 8 + 1 ):
130
131
self ._spi .spi .write (self ._single_byte )
131
132
self ._spi .spi .unlock ()
@@ -145,7 +146,7 @@ def _init_card(self, baudrate):
145
146
146
147
# CMD8: determine card version
147
148
rb7 = bytearray (4 )
148
- r = self ._cmd (card , 8 , 0x01aa , 0x87 , rb7 , data_block = False )
149
+ r = self ._cmd (card , 8 , 0x01AA , 0x87 , rb7 , data_block = False )
149
150
if r == _R1_IDLE_STATE :
150
151
self ._init_card_v2 (card )
151
152
elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND ):
@@ -156,18 +157,18 @@ def _init_card(self, baudrate):
156
157
# get the number of sectors
157
158
# CMD9: response R2 (R1 byte + 16-byte block read)
158
159
csd = bytearray (16 )
159
- if self ._cmd (card , 9 , 0 , 0xaf , response_buf = csd ) != 0 :
160
+ if self ._cmd (card , 9 , 0 , 0xAF , response_buf = csd ) != 0 :
160
161
raise OSError ("no response from SD card" )
161
- #self.readinto(csd)
162
- csd_version = (csd [0 ] & 0xc0 ) >> 6
162
+ # self.readinto(csd)
163
+ csd_version = (csd [0 ] & 0xC0 ) >> 6
163
164
if csd_version >= 2 :
164
165
raise OSError ("SD card CSD format not supported" )
165
166
166
167
if csd_version == 1 :
167
168
self ._sectors = ((csd [8 ] << 8 | csd [9 ]) + 1 ) * 1024
168
169
else :
169
- block_length = 2 ** (csd [5 ] & 0xf )
170
- c_size = ((csd [6 ] & 0x3 ) << 10 ) | (csd [7 ] << 2 ) | ((csd [8 ] & 0xc ) >> 6 )
170
+ block_length = 2 ** (csd [5 ] & 0xF )
171
+ c_size = ((csd [6 ] & 0x3 ) << 10 ) | (csd [7 ] << 2 ) | ((csd [8 ] & 0xC ) >> 6 )
171
172
mult = 2 ** (((csd [9 ] & 0x3 ) << 1 | (csd [10 ] & 0x80 ) >> 7 ) + 2 )
172
173
self ._sectors = block_length // 512 * mult * (c_size + 1 )
173
174
@@ -176,34 +177,35 @@ def _init_card(self, baudrate):
176
177
raise OSError ("can't set 512 block size" )
177
178
178
179
# set to high data rate now that it's initialised
179
- self ._spi = spi_device .SPIDevice (self ._spi .spi , self ._spi .chip_select ,
180
- baudrate = baudrate , extra_clocks = 8 )
180
+ self ._spi = spi_device .SPIDevice (
181
+ self ._spi .spi , self ._spi .chip_select , baudrate = baudrate , extra_clocks = 8
182
+ )
181
183
182
184
def _init_card_v1 (self , card ):
183
185
"""Initialize v1 SDCards which use byte addressing."""
184
186
for _ in range (_CMD_TIMEOUT ):
185
187
self ._cmd (card , 55 , 0 , 0 )
186
188
if self ._cmd (card , 41 , 0 , 0 ) == 0 :
187
- #print("[SDCard] v1 card")
189
+ # print("[SDCard] v1 card")
188
190
return
189
191
raise OSError ("timeout waiting for v1 card" )
190
192
191
193
def _init_card_v2 (self , card ):
192
194
"""Initialize v2 SDCards which use 512-byte block addressing."""
193
195
ocr = bytearray (4 )
194
196
for _ in range (_CMD_TIMEOUT ):
195
- time .sleep (.050 )
196
- self ._cmd (card , 58 , 0 , 0xfd , response_buf = ocr , data_block = False )
197
+ time .sleep (0 .050 )
198
+ self ._cmd (card , 58 , 0 , 0xFD , response_buf = ocr , data_block = False )
197
199
self ._cmd (card , 55 , 0 , 0x65 )
198
200
# On non-longint builds, we cannot use 0x40000000 directly as the arg
199
201
# so break it into bytes, which are interpreted by self._cmd().
200
- if self ._cmd (card , 41 , b' \x40 \x00 \x00 \x00 ' , 0x77 ) == 0 :
201
- self ._cmd (card , 58 , 0 , 0xfd , response_buf = ocr , data_block = False )
202
+ if self ._cmd (card , 41 , b" \x40 \x00 \x00 \x00 " , 0x77 ) == 0 :
203
+ self ._cmd (card , 58 , 0 , 0xFD , response_buf = ocr , data_block = False )
202
204
203
205
# Check for block addressing
204
206
if (ocr [0 ] & 0x40 ) != 0 :
205
207
self ._cdv = 1
206
- #print("[SDCard] v2 card")
208
+ # print("[SDCard] v2 card")
207
209
return
208
210
raise OSError ("timeout waiting for v2 card" )
209
211
@@ -216,13 +218,15 @@ def _wait_for_ready(self, card, timeout=0.3):
216
218
"""
217
219
start_time = time .monotonic ()
218
220
self ._single_byte [0 ] = 0x00
219
- while time .monotonic () - start_time < timeout and self ._single_byte [0 ] != 0xff :
220
- card .readinto (self ._single_byte , write_value = 0xff )
221
+ while time .monotonic () - start_time < timeout and self ._single_byte [0 ] != 0xFF :
222
+ card .readinto (self ._single_byte , write_value = 0xFF )
221
223
222
224
# pylint: disable-msg=too-many-arguments
223
225
# pylint: disable=no-member
224
226
# no-member disable should be reconsidered when it can be tested
225
- def _cmd (self , card , cmd , arg = 0 , crc = 0 , response_buf = None , data_block = True , wait = True ):
227
+ def _cmd (
228
+ self , card , cmd , arg = 0 , crc = 0 , response_buf = None , data_block = True , wait = True
229
+ ):
226
230
"""
227
231
Issue a command to the card and read an optional data response.
228
232
@@ -237,17 +241,17 @@ def _cmd(self, card, cmd, arg=0, crc=0, response_buf=None, data_block=True, wait
237
241
buf = self ._cmdbuf
238
242
buf [0 ] = 0x40 | cmd
239
243
if isinstance (arg , int ):
240
- buf [1 ] = (arg >> 24 ) & 0xff
241
- buf [2 ] = (arg >> 16 ) & 0xff
242
- buf [3 ] = (arg >> 8 ) & 0xff
243
- buf [4 ] = arg & 0xff
244
+ buf [1 ] = (arg >> 24 ) & 0xFF
245
+ buf [2 ] = (arg >> 16 ) & 0xFF
246
+ buf [3 ] = (arg >> 8 ) & 0xFF
247
+ buf [4 ] = arg & 0xFF
244
248
elif len (arg ) == 4 :
245
249
# arg can be a 4-byte buf
246
250
buf [1 :5 ] = arg
247
251
else :
248
252
raise ValueError ()
249
253
250
- if ( crc == 0 ) :
254
+ if crc == 0 :
251
255
buf [5 ] = calculate_crc (buf [:- 1 ])
252
256
else :
253
257
buf [5 ] = crc
@@ -259,21 +263,22 @@ def _cmd(self, card, cmd, arg=0, crc=0, response_buf=None, data_block=True, wait
259
263
260
264
# wait for the response (response[7] == 0)
261
265
for _ in range (_CMD_TIMEOUT ):
262
- card .readinto (buf , end = 1 , write_value = 0xff )
266
+ card .readinto (buf , end = 1 , write_value = 0xFF )
263
267
if not (buf [0 ] & 0x80 ):
264
268
if response_buf :
265
269
if data_block :
266
270
# Wait for the start block byte
267
- buf [1 ] = 0xff
268
- while buf [1 ] != 0xfe :
269
- card .readinto (buf , start = 1 , end = 2 , write_value = 0xff )
270
- card .readinto (response_buf , write_value = 0xff )
271
+ buf [1 ] = 0xFF
272
+ while buf [1 ] != 0xFE :
273
+ card .readinto (buf , start = 1 , end = 2 , write_value = 0xFF )
274
+ card .readinto (response_buf , write_value = 0xFF )
271
275
if data_block :
272
276
# Read the checksum
273
- card .readinto (buf , start = 1 , end = 3 , write_value = 0xff )
277
+ card .readinto (buf , start = 1 , end = 3 , write_value = 0xFF )
274
278
return buf [0 ]
275
279
return - 1
276
- #pylint: enable-msg=too-many-arguments
280
+
281
+ # pylint: enable-msg=too-many-arguments
277
282
278
283
# pylint: disable-msg=too-many-arguments
279
284
def _block_cmd (self , card , cmd , block , crc , response_buf = None ):
@@ -294,12 +299,12 @@ def _block_cmd(self, card, cmd, block, crc, response_buf=None):
294
299
# We address by byte because cdv is 512. Instead of multiplying, shift
295
300
# the data to the correct spot so that we don't risk creating a long
296
301
# int.
297
- buf [1 ] = (block >> 15 ) & 0xff
298
- buf [2 ] = (block >> 7 ) & 0xff
299
- buf [3 ] = (block << 1 ) & 0xff
302
+ buf [1 ] = (block >> 15 ) & 0xFF
303
+ buf [2 ] = (block >> 7 ) & 0xFF
304
+ buf [3 ] = (block << 1 ) & 0xFF
300
305
buf [4 ] = 0
301
306
302
- if ( crc == 0 ) :
307
+ if crc == 0 :
303
308
buf [5 ] = calculate_crc (buf [:- 1 ])
304
309
else :
305
310
buf [5 ] = crc
@@ -311,7 +316,7 @@ def _block_cmd(self, card, cmd, block, crc, response_buf=None):
311
316
312
317
# wait for the response (response[7] == 0)
313
318
for _ in range (_CMD_TIMEOUT ):
314
- card .readinto (buf , end = 1 , write_value = 0xff )
319
+ card .readinto (buf , end = 1 , write_value = 0xFF )
315
320
if not (buf [0 ] & 0x80 ):
316
321
result = buf [0 ]
317
322
break
@@ -322,9 +327,10 @@ def _block_cmd(self, card, cmd, block, crc, response_buf=None):
322
327
self ._readinto (card , response_buf )
323
328
324
329
return result
330
+
325
331
# pylint: enable-msg=too-many-arguments
326
332
327
- def _cmd_nodata (self , card , cmd , response = 0xff ):
333
+ def _cmd_nodata (self , card , cmd , response = 0xFF ):
328
334
"""
329
335
Issue a command to the card with no argument.
330
336
@@ -333,14 +339,14 @@ def _cmd_nodata(self, card, cmd, response=0xff):
333
339
"""
334
340
buf = self ._cmdbuf
335
341
buf [0 ] = cmd
336
- buf [1 ] = 0xff
342
+ buf [1 ] = 0xFF
337
343
338
344
card .write (buf , end = 2 )
339
345
for _ in range (_CMD_TIMEOUT ):
340
- card .readinto (buf , end = 1 , write_value = 0xff )
346
+ card .readinto (buf , end = 1 , write_value = 0xFF )
341
347
if buf [0 ] == response :
342
- return 0 # OK
343
- return 1 # timeout
348
+ return 0 # OK
349
+ return 1 # timeout
344
350
345
351
def _readinto (self , card , buf , start = 0 , end = None ):
346
352
"""
@@ -355,14 +361,14 @@ def _readinto(self, card, buf, start=0, end=None):
355
361
end = len (buf )
356
362
357
363
# read until start byte (0xfe)
358
- buf [start ] = 0xff # busy
359
- while buf [start ] != 0xfe :
360
- card .readinto (buf , start = start , end = start + 1 , write_value = 0xff )
364
+ buf [start ] = 0xFF # busy
365
+ while buf [start ] != 0xFE :
366
+ card .readinto (buf , start = start , end = start + 1 , write_value = 0xFF )
361
367
362
- card .readinto (buf , start = start , end = end , write_value = 0xff )
368
+ card .readinto (buf , start = start , end = end , write_value = 0xFF )
363
369
364
370
# read checksum and throw it away
365
- card .readinto (self ._cmdbuf , end = 2 , write_value = 0xff )
371
+ card .readinto (self ._cmdbuf , end = 2 , write_value = 0xFF )
366
372
367
373
# pylint: disable-msg=too-many-arguments
368
374
def _write (self , card , token , buf , start = 0 , end = None ):
@@ -385,27 +391,28 @@ def _write(self, card, token, buf, start=0, end=None):
385
391
cmd [0 ] = token
386
392
card .write (cmd , end = 1 )
387
393
card .write (buf , start = start , end = end )
388
- cmd [0 ] = 0xff
389
- cmd [1 ] = 0xff
394
+ cmd [0 ] = 0xFF
395
+ cmd [1 ] = 0xFF
390
396
card .write (cmd , end = 2 )
391
397
392
398
# check the response
393
399
# pylint: disable=no-else-return
394
400
# Disable should be removed when refactor can be tested
395
401
for _ in range (_CMD_TIMEOUT ):
396
- card .readinto (cmd , end = 1 , write_value = 0xff )
402
+ card .readinto (cmd , end = 1 , write_value = 0xFF )
397
403
if not (cmd [0 ] & 0x80 ):
398
- if (cmd [0 ] & 0x1f ) != 0x05 :
404
+ if (cmd [0 ] & 0x1F ) != 0x05 :
399
405
return - 1
400
406
else :
401
407
break
402
408
403
409
# wait for write to finish
404
- card .readinto (cmd , end = 1 , write_value = 0xff )
410
+ card .readinto (cmd , end = 1 , write_value = 0xFF )
405
411
while cmd [0 ] == 0 :
406
- card .readinto (cmd , end = 1 , write_value = 0xff )
412
+ card .readinto (cmd , end = 1 , write_value = 0xFF )
413
+
414
+ return 0 # worked
407
415
408
- return 0 # worked
409
416
# pylint: enable-msg=too-many-arguments
410
417
411
418
def count (self ):
@@ -425,7 +432,7 @@ def readblocks(self, start_block, buf):
425
432
:param bytearray buf: The buffer to write into. Length must be multiple of 512.
426
433
"""
427
434
nblocks , err = divmod (len (buf ), 512 )
428
- assert nblocks and not err , ' Buffer length is invalid'
435
+ assert nblocks and not err , " Buffer length is invalid"
429
436
with self ._spi as card :
430
437
if nblocks == 1 :
431
438
# CMD17: set read address for single block
@@ -445,7 +452,7 @@ def readblocks(self, start_block, buf):
445
452
ret = self ._cmd (card , 12 , 0 , 0x61 , wait = False )
446
453
# return first status 0 or last before card ready (0xff)
447
454
while ret != 0 :
448
- card .readinto (self ._single_byte , write_value = 0xff )
455
+ card .readinto (self ._single_byte , write_value = 0xFF )
449
456
if self ._single_byte [0 ] & 0x80 :
450
457
return ret
451
458
ret = self ._single_byte [0 ]
@@ -459,7 +466,7 @@ def writeblocks(self, start_block, buf):
459
466
:param bytearray buf: The buffer to write into. Length must be multiple of 512.
460
467
"""
461
468
nblocks , err = divmod (len (buf ), 512 )
462
- assert nblocks and not err , ' Buffer length is invalid'
469
+ assert nblocks and not err , " Buffer length is invalid"
463
470
with self ._spi as card :
464
471
if nblocks == 1 :
465
472
# CMD24: set write address for single block
@@ -475,12 +482,15 @@ def writeblocks(self, start_block, buf):
475
482
# send the data
476
483
offset = 0
477
484
while nblocks :
478
- self ._write (card , _TOKEN_CMD25 , buf , start = offset , end = (offset + 512 ))
485
+ self ._write (
486
+ card , _TOKEN_CMD25 , buf , start = offset , end = (offset + 512 )
487
+ )
479
488
offset += 512
480
489
nblocks -= 1
481
490
self ._cmd_nodata (card , _TOKEN_STOP_TRAN , 0x0 )
482
491
return 0
483
492
493
+
484
494
def _calculate_crc_table ():
485
495
"""Precompute the table used in calculate_crc."""
486
496
# Code converted from https://github.com/hazelnusse/crc7/blob/master/crc7.cc by devoh747
@@ -492,18 +502,20 @@ def _calculate_crc_table():
492
502
493
503
# generate a table value for all 256 possible byte values
494
504
for i in range (256 ):
495
- if ( i & 0x80 ) :
505
+ if i & 0x80 :
496
506
crc_table [i ] = i ^ crc_poly
497
507
else :
498
508
crc_table [i ] = i
499
509
for _ in range (1 , 8 ):
500
510
crc_table [i ] = crc_table [i ] << 1
501
- if ( crc_table [i ] & 0x80 ) :
511
+ if crc_table [i ] & 0x80 :
502
512
crc_table [i ] = crc_table [i ] ^ crc_poly
503
513
return crc_table
504
514
515
+
505
516
CRC_TABLE = _calculate_crc_table ()
506
517
518
+
507
519
def calculate_crc (message ):
508
520
"""
509
521
Calculate the CRC of message[0:5], using a precomputed table in CRC_TABLE.
@@ -515,4 +527,4 @@ def calculate_crc(message):
515
527
for i in range (0 , 5 ):
516
528
crc = CRC_TABLE [(crc << 1 ) ^ message [i ]]
517
529
518
- return (( crc << 1 ) | 1 )
530
+ return (crc << 1 ) | 1
0 commit comments