]>
Commit | Line | Data |
---|---|---|
1 | ; ----------------- MMC/SD routines ------------------ | |
2 | ||
3 | mmcByteNoSend: | |
4 | ldi temp,0xff | |
5 | mmcByte: | |
6 | ||
7 | .if MMC_DEBUG | |
8 | printstring "MMC: <--" | |
9 | rcall printhex | |
10 | .endif | |
11 | ||
12 | out SPDR,temp | |
13 | mmcWrByteW: | |
14 | in temp,SPSR | |
15 | sbrs temp,7 | |
16 | rjmp mmcWrByteW | |
17 | in temp,SPDR | |
18 | ||
19 | .if MMC_DEBUG | |
20 | printstring ", -->" | |
21 | rcall printhex | |
22 | printnewline | |
23 | .endif | |
24 | ret | |
25 | ||
26 | ||
27 | ;Wait till the mmc answers with the response in temp2, or till a timeout happens. | |
28 | mmcWaitResp: | |
29 | ldiw z,0 | |
30 | mmcWaitResploop: | |
31 | rcall mmcByteNoSend | |
32 | cpi temp,0xff | |
33 | brne mmcWaitResploopEnd | |
34 | adiw zl,1 | |
35 | cpi zh,255 | |
36 | breq mmcWaitErr | |
37 | rjmp mmcWaitResploop | |
38 | mmcWaitResploopEnd: | |
39 | ret | |
40 | ||
41 | ||
42 | mmcWaitErr: | |
43 | mov temp,temp2 | |
44 | rcall printhex | |
45 | printstring ": Error: MMC resp timeout!" | |
46 | printnewline | |
47 | rjmp resetAVR | |
48 | ||
49 | mmcInit: | |
50 | ldi temp,0x53 | |
51 | out SPCR,temp | |
52 | ||
53 | ;Init start: send 80 clocks with cs disabled | |
54 | sbi P_MMC_CS,mmc_cs | |
55 | ||
56 | ; ldi temp2,20 | |
57 | ldi temp2,10 ; exactly 80 clocks | |
58 | mmcInitLoop: | |
59 | mov temp,temp2 | |
60 | rcall mmcByte | |
61 | dec temp2 | |
62 | brne mmcInitLoop | |
63 | ||
64 | cbi P_MMC_CS,mmc_cs | |
65 | rcall mmcByteNoSend | |
66 | rcall mmcByteNoSend | |
67 | rcall mmcByteNoSend | |
68 | rcall mmcByteNoSend | |
69 | rcall mmcByteNoSend | |
70 | rcall mmcByteNoSend | |
71 | sbi P_MMC_CS,mmc_cs | |
72 | rcall mmcByteNoSend | |
73 | rcall mmcByteNoSend | |
74 | rcall mmcByteNoSend | |
75 | rcall mmcByteNoSend | |
76 | ||
77 | ;Send init command | |
78 | cbi P_MMC_CS,mmc_cs | |
79 | ldi temp,0xff ;dummy | |
80 | rcall mmcByte | |
81 | ldi temp,0xff ;dummy | |
82 | rcall mmcByte | |
83 | ldi temp,0x40 ;cmd | |
84 | rcall mmcByte | |
85 | ldi temp,0 ;pxh | |
86 | rcall mmcByte | |
87 | ldi temp,0 ;pxl | |
88 | rcall mmcByte | |
89 | ldi temp,0 ;pyh | |
90 | rcall mmcByte | |
91 | ldi temp,0 ;pyl | |
92 | rcall mmcByte | |
93 | ldi temp,0x95 ;crc | |
94 | rcall mmcByte | |
95 | ldi temp,0xff ;return byte | |
96 | rcall mmcByte | |
97 | ||
98 | ldi temp2,0 ;Error Code 0 | |
99 | rcall mmcWaitResp ;Test on CMD0 is OK | |
100 | ||
101 | sbi P_MMC_CS,mmc_cs ;disable /CS | |
102 | rcall mmcByteNoSend | |
103 | ||
104 | ||
105 | ;Read OCR till card is ready | |
106 | ldi temp2,100 ;repeat counter | |
107 | mmcInitOcrLoop: | |
108 | push temp2 | |
109 | ||
110 | cbi P_MMC_CS,mmc_cs ;enable /CS | |
111 | ldi temp,0xff ;dummy | |
112 | rcall mmcByte | |
113 | ldi temp,0x41 ;cmd | |
114 | rcall mmcByte | |
115 | ldi temp,0 ;pxh | |
116 | rcall mmcByte | |
117 | ldi temp,0 ;pxl | |
118 | rcall mmcByte | |
119 | ldi temp,0 ;pyh | |
120 | rcall mmcByte | |
121 | ldi temp,0 ;pyl | |
122 | rcall mmcByte | |
123 | ; ldi temp,0x95 ;crc | |
124 | ldi temp,0x01 ;crc | |
125 | rcall mmcByte | |
126 | rcall mmcByteNoSend | |
127 | ||
128 | ldi temp2,1 | |
129 | rcall mmcWaitResp ;wait until mmc-card send a byte <> 0xFF | |
130 | ;the first answer must be 0x01 (Idle-Mode) | |
131 | cpi temp,0 | |
132 | breq mmcInitOcrLoopDone ;second answer is 0x00 (Idle-Mode leave) CMD1 is OK | |
133 | ||
134 | sbi P_MMC_CS,mmc_cs ;disable /CS | |
135 | ||
136 | rcall mmcByteNoSend | |
137 | ||
138 | ldi temp,10 | |
139 | rcall delay_ms | |
140 | ||
141 | pop temp2 | |
142 | dec temp2 | |
143 | brne mmcInitOcrLoop ;repeat | |
144 | ||
145 | ldi temp2,4 | |
146 | rjmp mmcWaitErr | |
147 | ||
148 | mmcInitOcrLoopDone: | |
149 | pop temp2 | |
150 | sbi P_MMC_CS,mmc_cs ;disable /CS | |
151 | rcall mmcByteNoSend | |
152 | ||
153 | out SPCR,_0 | |
154 | ret | |
155 | ||
156 | ||
157 | ;Call this with yh:yl:xh:xl = sector number | |
158 | ; | |
159 | mmcReadSect: | |
160 | ldi temp,0x50 | |
161 | out SPCR,temp | |
162 | ||
163 | cbi P_MMC_CS,mmc_cs | |
164 | rcall mmcByteNoSend | |
165 | ldi temp,0x51 ;cmd (read sector) | |
166 | rcall mmcByte | |
167 | lsl xl ;convert to byte address (*512) | |
168 | rol xh | |
169 | rol yl | |
170 | mov temp,yl | |
171 | rcall mmcByte | |
172 | mov temp,xh ;pxl | |
173 | rcall mmcByte | |
174 | mov temp,xl ;pyh | |
175 | rcall mmcByte | |
176 | ldi temp,0 ;pyl | |
177 | rcall mmcByte | |
178 | ldi temp,0x95 ;crc | |
179 | rcall mmcByte | |
180 | ldi temp,0xff ;return byte | |
181 | rcall mmcByte | |
182 | ||
183 | ;resp | |
184 | ldi temp2,2 | |
185 | rcall mmcWaitResp | |
186 | ||
187 | ;data token | |
188 | ldi temp2,3 | |
189 | rcall mmcWaitResp | |
190 | ||
191 | ;Read sector to AVR RAM | |
192 | ldiw z,hostbuf | |
193 | mmcreadloop: | |
194 | rcall mmcByteNoSend | |
195 | st z+,temp | |
196 | cpi zl,low(hostbuf+512) | |
197 | brne mmcreadloop | |
198 | cpi zh,high(hostbuf+512) | |
199 | brne mmcreadloop | |
200 | ||
201 | ;CRC | |
202 | rcall mmcByteNoSend | |
203 | rcall mmcByteNoSend | |
204 | ||
205 | sbi P_MMC_CS,mmc_cs | |
206 | rcall mmcByteNoSend | |
207 | ||
208 | out SPCR,_0 | |
209 | ret | |
210 | ||
211 | ||
212 | ;Call this with yh:yl:xh:xl = sector number | |
213 | ; | |
214 | mmcWriteSect: | |
215 | ldi temp,0x50 | |
216 | out SPCR,temp | |
217 | ||
218 | cbi P_MMC_CS,mmc_cs | |
219 | rcall mmcByteNoSend | |
220 | ||
221 | ldi temp,0x58 ;cmd (write sector) | |
222 | rcall mmcByte | |
223 | lsl xl ;convert to byte address (*512) | |
224 | rol xh | |
225 | rol yl | |
226 | mov temp,yl | |
227 | rcall mmcByte | |
228 | mov temp,xh ;pxl | |
229 | rcall mmcByte | |
230 | mov temp,xl ;pyh | |
231 | rcall mmcByte | |
232 | ldi temp,0 ;pyl | |
233 | rcall mmcByte | |
234 | ldi temp,0x95 ;crc | |
235 | rcall mmcByte | |
236 | ldi temp,0xff ;return byte | |
237 | rcall mmcByte | |
238 | ||
239 | ;resp | |
240 | ldi temp2,1 | |
241 | rcall mmcWaitResp | |
242 | ||
243 | ;Send data token | |
244 | ldi temp,0xfe | |
245 | rcall mmcByte | |
246 | ||
247 | ;Write sector from AVR RAM | |
248 | ldiw z,hostbuf | |
249 | mmcwriteloop: | |
250 | ld temp,z+ | |
251 | rcall mmcByte | |
252 | cpi zl,low(hostbuf+512) | |
253 | brne mmcwriteloop | |
254 | cpi zh,high(hostbuf+512) | |
255 | brne mmcwriteloop | |
256 | ||
257 | ;CRC | |
258 | rcall mmcByteNoSend | |
259 | rcall mmcByteNoSend | |
260 | ||
261 | ;Status. Ignored for now. | |
262 | rcall mmcByteNoSend | |
263 | ||
264 | ;Wait till the mmc has written everything | |
265 | mmcwaitwritten: | |
266 | rcall mmcByteNoSend | |
267 | cpi temp,0xff | |
268 | brne mmcwaitwritten | |
269 | ||
270 | sbi P_MMC_CS,mmc_cs | |
271 | rcall mmcByteNoSend | |
272 | ||
273 | out SPCR,_0 | |
274 | ret | |
275 | ||
276 | ||
277 | ;Set up wdt to time out after 1 sec. | |
278 | resetAVR: | |
279 | lds temp,txcount ;Wait, till tx buffer is empty | |
280 | tst temp | |
281 | brne resetAVR | |
282 | ||
283 | cli | |
284 | ldi temp,(1<<WDCE) | |
285 | outm8 WDTCSR,temp | |
286 | ldi temp,(1<<WDCE) | (1<<WDE) | (110<<WDP0) | |
287 | outm8 WDTCSR,temp | |
288 | resetwait: | |
289 | rjmp resetwait | |
290 | ||
291 |