8000 drivers/sdcard: Port the SDCard driver to new machine API. · danni/micropython@ce1c786 · GitHub
[go: up one dir, main page]

Skip to content

Commit ce1c786

Browse files
deshipudpgeorge
authored andcommitted
drivers/sdcard: Port the SDCard driver to new machine API.
With backwards compatibility for pyboard.
1 parent 49406b0 commit ce1c786

File tree

1 file changed

+79
-60
lines changed

1 file changed

+79
-60
lines changed

drivers/sdcard/sdcard.py

Lines changed: 79 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,41 @@
44
Requires an SPI bus and a CS pin. Provides readblocks and writeblocks
55
methods so the device can be mounted as a filesystem.
66
7-
Example usage:
7+
Example usage on pyboard:
88
99
import pyb, sdcard, os
1010
sd = sdcard.SDCard(pyb.SPI(1), pyb.Pin.board.X5)
1111
pyb.mount(sd, '/sd2')
1212
os.listdir('/')
1313
14+
Example usage on ESP8266:
15+
16+
import machine, sdcard, os
17+
sd = sdcard.SDCard(machine.SPI(0), machine.Pin(15))
18+
os.umount()
19+
os.VfsFat(sd, "")
20+
os.listdir()
21+
1422
"""
1523

16-
import pyb
24+
import time
1725

18-
class SDCard:
19-
CMD_TIMEOUT = const(100)
20-
21-
R1_IDLE_STATE = const(1 << 0)
22-
#R1_ERASE_RESET = const(1 << 1)
23-
R1_ILLEGAL_COMMAND = const(1 << 2)
24-
#R1_COM_CRC_ERROR = const(1 << 3)
25-
#R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
26-
#R1_ADDRESS_ERROR = const(1 << 5)
27-
#R1_PARAMETER_ERROR = const(1 << 6)
28-
TOKEN_CMD25 = const(0xfc)
29-
TOKEN_STOP_TRAN = const(0xfd)
30-
TOKEN_DATA = const(0xfe)
3126

27+
_CMD_TIMEOUT = const(100)
28+
29+
_R1_IDLE_STATE = const(1 << 0)
30+
#R1_ERASE_RESET = const(1 << 1)
31+
_R1_ILLEGAL_COMMAND = const(1 << 2)
32+
#R1_COM_CRC_ERROR = const(1 << 3)
33+
#R1_ERASE_SEQUENCE_ERROR = const(1 << 4)
34+
#R1_ADDRESS_ERROR = const(1 << 5)
35+
#R1_PARAMETER_ERROR = const(1 << 6)
36+
_TOKEN_CMD25 = const(0xfc)
37+
_TOKEN_STOP_TRAN = const(0xfd)
38+
_TOKEN_DATA = const(0xfe)
39+
40+
41+
class SDCard:
3242
def __init__(self, spi, cs):
3343
self.spi = spi
3444
self.cs = cs
@@ -42,30 +52,39 @@ def __init__(self, spi, cs):
4252
# initialise the card
4353
self.init_card()
4454

55+
def init_spi(self, baudrate):
56+
try:
57+
master = self.spi.MASTER
58+
except AttributeError:
59+
# on ESP8266
60+
self.spi.init(baudrate=baudrate, phase=0, polarity=0)
61+
else:
62+
# on pyboard
63+
self.spi.init(master, baudrate=baudrate, phase=0, polarity=0)
64+
4565
def init_card(self):
4666
# init CS pin
47-
self.cs.high()
48-
self.cs.init(self.cs.OUT_PP)
67+
self.cs.init(self.cs.OUT, value=1)
4968

5069
# init SPI bus; use low data rate for initialisation
51-
self.spi.init(self.spi.MASTER, baudrate=100000, phase=0, polarity=0)
70+
self.init_spi(100000)
5271

5372
# clock card at least 100 cycles with cs high
5473
for i in range(16):
55-
self.spi.send(0xff)
74+
self.spi.write(b'\xff')
5675

57-
# CMD0: init card; should return R1_IDLE_STATE (allow 5 attempts)
76+
# CMD0: init card; should return _R1_IDLE_STATE (allow 5 attempts)
5877
for _ in range(5):
59-
if self.cmd(0, 0, 0x95) == R1_IDLE_STATE:
78+
if self.cmd(0, 0, 0x95) == _R1_IDLE_STATE:
6079
break
6180
else:
6281
raise OSError("no SD card")
6382

6483
# CMD8: determine card version
6584
r = self.cmd(8, 0x01aa, 0x87, 4)
66-
if r == R1_IDLE_STATE:
85+
if r == _R1_IDLE_STATE:
6786
self.init_card_v2()
68-
elif r == (R1_IDLE_STATE | R1_ILLEGAL_COMMAND):
87+
elif r == (_R1_IDLE_STATE | _R1_ILLEGAL_COMMAND):
6988
self.init_card_v1()
7089
else:
7190
raise OSError("couldn't determine SD card version")
@@ -86,10 +105,10 @@ def init_card(self):
86105
raise OSError("can't set 512 block size")
87106

88107
# set to high data rate now that it's initialised
89-
self.spi.init(self.spi.MASTER, baudrate=1320000, phase=0, polarity=0)
108+
self.init_spi(1320000)
90109

91110
def init_card_v1(self):
92-
for i in range(CMD_TIMEOUT):
111+
for i in range(_CMD_TIMEOUT):
93112
self.cmd(55, 0, 0)
94113
if self.cmd(41, 0, 0) == 0:
95114
self.cdv = 512
@@ -98,8 +117,8 @@ def init_card_v1(self):
98117
raise OSError("timeout waiting for v1 card")
99118

100119
def init_card_v2(self):
101-
for i in range(CMD_TIMEOUT):
102-
pyb.delay(50)
120+
for i in range(_CMD_TIMEOUT):
121+
time.sleep_ms(50)
103122
self.cmd(58, 0, 0, 4)
104123
self.cmd(55, 0, 0)
105124
if self.cmd(41, 0x40000000, 0) == 0:
@@ -120,87 +139,87 @@ def cmd(self, cmd, arg, crc, final=0, release=True):
120139
buf[3] = arg >> 8
121140
buf[4] = arg
122141
buf[5] = crc
123-
self.spi.send(buf)
142+
self.spi.write(buf)
124143

125144
# wait for the repsonse (response[7] == 0)
126-
for i in range(CMD_TIMEOUT):
127-
response = self.spi.send_recv(0xff)[0]
145+
for i in range(_CMD_TIMEOUT):
146+
response = self.spi.read(1, 0xff)[0]
128147
if not (response & 0x80):
129148
# this could be a big-endian integer that we are getting here
130149
for j in range(final):
131-
self.spi.send(0xff)
150+
self.spi.write(b'\xff')
132151
if release:
133152
self.cs.high()
134-
self.spi.send(0xff)
153+
self.spi.write(b'\xff')
135154
return response
136155

137156
# timeout
138157
self.cs.high()
139-
self.spi.send(0xff)
158+
self.spi.write(b'\xff')
140159
return -1
141160

142161
def cmd_nodata(self, cmd):
143-
self.spi.send(cmd)
144-
self.spi.send_recv(0xff) # ignore stuff byte
145-
for _ in range(CMD_TIMEOUT):
146-
if self.spi.send_recv(0xff)[0] == 0xff:
162+
self.spi.write(cmd)
163+
self.spi.read(1, 0xff) # ignore stuff byte
164+
for _ in range(_CMD_TIMEOUT):
165+
if self.spi.read(1, 0xff)[0] == 0xff:
147166
self.cs.high()
148-
self.spi.send(0xff)
167+
self.spi.write(b'\xff')
149168
return 0 # OK
150169
self.cs.high()
151-
self.spi.send(0xff)
170+
self.spi.write(b'\xff')
152171
return 1 # timeout
153172

154173
def readinto(self, buf):
155174
self.cs.low()
156175

157176
# read until start byte (0xff)
158-
while self.spi.send_recv(0xff)[0] != 0xfe:
177+
while self.spi.read(1, 0xff)[0] != 0xfe:
159178
pass
160179

161180
# read data
162181
mv = self.dummybuf_memoryview[:len(buf)]
163-
self.spi.send_recv(mv, recv=buf)
182+
self.spi.write_readinto(mv, buf)
164183

165184
# read checksum
166-
self.spi.send(0xff)
167-
self.spi.send(0xff)
185+
self.spi.write(b'\xff')
186+
self.spi.write(b'\xff')
168187

169188
self.cs.high()
170-
self.spi.send(0xff)
189+
self.spi.write(b'\xff')
171190

172191
def write(self, token, buf):
173192
self.cs.low()
174193

175194
# send: start of block, data, checksum
176-
self.spi.send(token)
177-
self.spi.send(buf)
178-
self.spi.send(0xff)
179-
self.spi.send(0xff)
195+
self.spi.read(1, token)
196+
self.spi.write(buf)
197+
self.spi.write(b'\xff')
198+
self.spi.write(b'\xff')
180199

181200
# check the response
182-
if (self.spi.send_recv(0xff)[0] & 0x1f) != 0x05:
201+
if (self.spi.read(1, 0xff)[0] & 0x1f) != 0x05:
183202
self.cs.high()
184-
self.spi.send(0xff)
203+
self.spi.write(b'\xff')
185204
return
186205

187206
# wait for write to finish
188-
while self.spi.send_recv(0xff)[0] == 0:
207+
while self.spi.read(1, 0xff)[0] == 0:
189208
pass
190209

191210
self.cs.high()
192-
self.spi.send(0xff)
211+
self.spi.write(b'\xff')
193212

194213
def write_token(self, token):
195214
self.cs.low()
196-
self.spi.send(token)
197-
self.spi.send(0xff)
215+
self.spi.read(1, token)
216+
self.spi.write(b'\xff')
198217
# wait for write to finish
199-
while self.spi.send_recv(0xff)[0] == 0:
218+
while self.spi.read(1, 0xff)[0] == 0x00:
200219
pass
201220

202221
self.cs.high()
203-
self.spi.send(0xff)
222+
self.spi.write(b'\xff')
204223

205224
def count(self):
206225
return self.sectors
@@ -224,7 +243,7 @@ def readblocks(self, block_num, buf):
224243
self.readinto(mv[offset : offset + 512])
225244
offset += 512
226245
nblocks -= 1
227-
return self.cmd_nodata(12)
246+
return self.cmd_nodata(b'\x0c') # cmd 12
228247
return 0
229248

230249
def writeblocks(self, block_num, buf):
@@ -236,7 +255,7 @@ def writeblocks(self, block_num, buf):
236255
return 1
237256

238257
# send the data
239-
self.write(TOKEN_DATA, buf)
258+
self.write(_TOKEN_DATA, buf)
240259
else:
241260
# CMD25: set write address for first block
242261
if self.cmd(25, block_num * self.cdv, 0) != 0:
@@ -245,8 +264,8 @@ def writeblocks(self, block_num, buf):
245264
offset = 0
246265
mv = memoryview(buf)
247266
while nblocks:
248-
self.write(TOKEN_CMD25, mv[offset : offset + 512])
267+
self.write(_TOKEN_CMD25, mv[offset : offset + 512])
249268
offset += 512
250269
nblocks -= 1
251-
self.write_token(TOKEN_STOP_TRAN)
270+
self.write_token(_TOKEN_STOP_TRAN)
252271
return 0

0 commit comments

Comments
 (0)
0