3838_TOKEN_DATA = const (0xFE )
3939
4040
41+ def _crc7 (buf , n ):
42+ crc = 0
43+ for i in range (n ):
44+ crc ^= buf [i ]
45+ for j in range (8 ):
46+ crc = ((crc << 1 ) ^ (0x12 * (crc >> 7 ))) & 0xFF
47+ return crc | 1
48+
49+
4150class SDCard :
4251 def __init__ (self , spi , cs , baudrate = 1320000 ):
4352 self .spi = spi
@@ -76,13 +85,13 @@ def init_card(self, baudrate):
7685
7786 # CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
7887 for _ in range (5 ):
79- if self .cmd (0 , 0 , 0x95 ) == _R1_IDLE_STATE :
88+ if self .cmd (0 , 0 ) == _R1_IDLE_STATE :
8089 break
8190 else :
8291 raise OSError ("no SD card" )
8392
8493 # CMD8: determine card version
85- r = self .cmd (8 , 0x01AA , 0x87 , 4 )
94+ r = self .cmd (8 , 0x01AA , 4 )
8695 if r == _R1_IDLE_STATE :
8796 self .init_card_v2 ()
8897 elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND ):
@@ -92,7 +101,7 @@ def init_card(self, baudrate):
92101
93102 # get the number of sectors
94103 # CMD9: response R2 (R1 byte + 16-byte block read)
95- if self .cmd (9 , 0 , 0 , 0 , False ) != 0 :
104+ if self .cmd (9 , 0 , 0 , False ) != 0 :
96105 raise OSError ("no response from SD card" )
97106 csd = bytearray (16 )
98107 self .readinto (csd )
@@ -109,7 +118,7 @@ def init_card(self, baudrate):
109118 # print('sectors', self.sectors)
110119
111120 # CMD16: set block length to 512 bytes
112- if self .cmd (16 , 512 , 0 ) != 0 :
121+ if self .cmd (16 , 512 ) != 0 :
113122 raise OSError ("can't set 512 block size" )
114123
115124 # set to high data rate now that it's initialised
@@ -118,8 +127,8 @@ def init_card(self, baudrate):
118127 def init_card_v1 (self ):
119128 for i in range (_CMD_TIMEOUT ):
120129 time .sleep_ms (50 )
121- self .cmd (55 , 0 , 0 )
122- if self .cmd (41 , 0 , 0 ) == 0 :
130+ self .cmd (55 , 0 )
131+ if self .cmd (41 , 0 ) == 0 :
123132 # SDSC card, uses byte addressing in read/write/erase commands
124133 self .cdv = 512
125134 # print("[SDCard] v1 card")
@@ -129,10 +138,10 @@ def init_card_v1(self):
129138 def init_card_v2 (self ):
130139 for i in range (_CMD_TIMEOUT ):
131140 time .sleep_ms (50 )
132- self .cmd (58 , 0 , 0 , 4 )
133- self .cmd (55 , 0 , 0 )
134- if self .cmd (41 , 0x40000000 , 0 ) == 0 :
135- self .cmd (58 , 0 , 0 , - 4 ) # 4-byte response, negative means keep the first byte
141+ self .cmd (58 , 0 , 4 )
142+ self .cmd (55 , 0 )
143+ if self .cmd (41 , 0x40000000 ) == 0 :
144+ self .cmd (58 , 0 , - 4 ) # 4-byte response, negative means keep the first byte
136145 ocr = self .tokenbuf [0 ] # get first byte of response, which is OCR
137146 if not ocr & 0x40 :
138147 # SDSC card, uses byte addressing in read/write/erase commands
@@ -144,7 +153,7 @@ def init_card_v2(self):
144153 return
145154 raise OSError ("timeout waiting for v2 card" )
146155
147- def cmd (self , cmd , arg , crc , final = 0 , release = True , skip1 = False ):
156+ def cmd (self , cmd , arg , final = 0 , release = True , skip1 = False ):
148157 self .cs (0 )
149158
150159 # create and send the command
@@ -154,7 +163,7 @@ def cmd(self, cmd, arg, crc, final=0, release=True, skip1=False):
154163 buf [2 ] = arg >> 16
155164 buf [3 ] = arg >> 8
156165 buf [4 ] = arg
157- buf [5 ] = crc
166+ buf [5 ] = _crc7 ( buf , 5 )
158167 self .spi .write (buf )
159168
160169 if skip1 :
@@ -250,15 +259,15 @@ def readblocks(self, block_num, buf):
250259 assert nblocks and not len (buf ) % 512 , "Buffer length is invalid"
251260 if nblocks == 1 :
252261 # CMD17: set read address for single block
253- if self .cmd (17 , block_num * self .cdv , 0 , release = False ) != 0 :
262+ if self .cmd (17 , block_num * self .cdv , release = False ) != 0 :
254263 # release the card
255264 self .cs (1 )
256265 raise OSError (5 ) # EIO
257266 # receive the data and release card
258267 self .readinto (buf )
259268 else :
260269 # CMD18: set read address for multiple blocks
261- if self .cmd (18 , block_num * self .cdv , 0 , release = False ) != 0 :
270+ if self .cmd (18 , block_num * self .cdv , release = False ) != 0 :
262271 # release the card
263272 self .cs (1 )
264273 raise OSError (5 ) # EIO
@@ -269,7 +278,7 @@ def readblocks(self, block_num, buf):
269278 self .readinto (mv [offset : offset + 512 ])
270279 offset += 512
271280 nblocks -= 1
272- if self .cmd (12 , 0 , 0xFF , skip1 = True ):
281+ if self .cmd (12 , 0 , skip1 = True ):
273282 raise OSError (5 ) # EIO
274283
275284 def writeblocks (self , block_num , buf ):
@@ -281,14 +290,14 @@ def writeblocks(self, block_num, buf):
281290 assert nblocks and not err , "Buffer length is invalid"
282291 if nblocks == 1 :
283292 # CMD24: set write address for single block
284- if self .cmd (24 , block_num * self .cdv , 0 ) != 0 :
293+ if self .cmd (24 , block_num * self .cdv ) != 0 :
285294 raise OSError (5 ) # EIO
286295
287296 # send the data
288297 self .write (_TOKEN_DATA , buf )
289298 else :
290299 # CMD25: set write address for first block
291- if self .cmd (25 , block_num * self .cdv , 0 ) != 0 :
300+ if self .cmd (25 , block_num * self .cdv ) != 0 :
292301 raise OSError (5 ) # EIO
293302 # send the data
294303 offset = 0
0 commit comments