altos: Add SDCARD and FAT16 filesystem support
[fw/altos] / src / drivers / ao_sdcard.c
1 /*
2  * Copyright © 2013 Keith Packard <keithp@keithp.com>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; version 2 of the License.
7  *
8  * This program is distributed in the hope that it will be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11  * General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License along
14  * with this program; if not, write to the Free Software Foundation, Inc.,
15  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
16  */
17
18 #include "ao.h"
19 #include "ao_sdcard.h"
20
21 #define ao_sdcard_get_slow()            ao_spi_get(AO_SDCARD_SPI_BUS, AO_SPI_SPEED_250kHz)
22 #define ao_sdcard_get()                 ao_spi_get(AO_SDCARD_SPI_BUS, AO_SPI_SPEED_FAST)
23 #define ao_sdcard_put()                 ao_spi_put(AO_SDCARD_SPI_BUS)
24 #define ao_sdcard_send_fixed(d,l)       ao_spi_send_fixed((d), (l), AO_SDCARD_SPI_BUS)
25 #define ao_sdcard_send(d,l)             ao_spi_send((d), (l), AO_SDCARD_SPI_BUS)
26 #define ao_sdcard_recv(d,l)             ao_spi_recv((d), (l), AO_SDCARD_SPI_BUS)
27 #define ao_sdcard_select()              ao_gpio_set(AO_SDCARD_SPI_CS_PORT,AO_SDCARD_SPI_CS_PIN,AO_SDCARD_SPI_CS,0)
28 #define ao_sdcard_deselect()            ao_gpio_set(AO_SDCARD_SPI_CS_PORT,AO_SDCARD_SPI_CS_PIN,AO_SDCARD_SPI_CS,1)
29
30
31 static uint8_t  initialized;
32 static uint8_t  present;
33 static uint8_t  mutex;
34 static enum ao_sdtype sdtype;
35
36 #define ao_sdcard_lock()        ao_mutex_get(&mutex)
37 #define ao_sdcard_unlock()      ao_mutex_put(&mutex)
38
39 #if 0
40 #define DBG(...) printf(__VA_ARGS__)
41 #else
42 #define DBG(...)
43 #endif
44
45 /*
46  * Send an SD command and await the status reply
47  */
48
49 static uint8_t
50 ao_sdcard_send_cmd(uint8_t cmd, uint32_t arg)
51 {
52         uint8_t data[6];
53         uint8_t reply;
54         int i;
55
56         DBG ("\tsend_cmd %d arg %08x\n", cmd, arg);
57         if (cmd != SDCARD_GO_IDLE_STATE) {
58                 for (i = 0; i < SDCARD_CMD_TIMEOUT; i++) {
59                         ao_sdcard_recv(&reply, 1);
60                         if (reply == 0xff)
61                                 break;
62                 }
63                 if (i == SDCARD_CMD_TIMEOUT)
64                         return SDCARD_STATUS_TIMEOUT;
65         }
66         
67         data[0] = cmd & 0x3f | 0x40;
68         data[1] = arg >> 24;
69         data[2] = arg >> 16;
70         data[3] = arg >> 8;
71         data[4] = arg;
72         if (cmd == SDCARD_GO_IDLE_STATE)
73                 data[5] = 0x95; /* Valid for 0 arg */
74         else if (cmd == SDCARD_SEND_IF_COND)
75                 data[5] = 0x87; /* Valid for 0x1aa arg */
76         else
77                 data[5] = 0xff; /* no CRC */
78         ao_sdcard_send(data, 6);
79
80         /* The first reply byte will be the status,
81          * which must have the high bit clear
82          */
83         for (i = 0; i < SDCARD_CMD_TIMEOUT; i++) {
84                 ao_sdcard_recv(&reply, 1);
85                 DBG ("\t\tgot byte %02x\n", reply);
86                 if ((reply & 0x80) == 0)
87                         return reply;
88         }
89         return SDCARD_STATUS_TIMEOUT;
90 }
91
92 /*
93  * Retrieve any reply, discarding the trailing CRC byte
94  */
95 static void
96 ao_sdcard_recv_reply(uint8_t *reply, int len)
97 {
98         uint8_t discard;
99
100         if (len)
101                 ao_sdcard_recv(reply, len);
102         /* trailing byte */
103         ao_sdcard_recv(&discard, 1);
104 }
105
106 /*
107  * Wait while the card is busy. The
108  * card will return a stream of 0xff
109  * until it isn't busy anymore
110  */
111 static void
112 ao_sdcard_wait_busy(void)
113 {
114         uint8_t v;
115
116         do {
117                 ao_sdcard_recv(&v, 1);
118         } while (v != 0xff);
119         ao_sdcard_send_fixed(0xff, 1);
120 }
121
122 static uint8_t
123 ao_sdcard_go_idle_state(void)
124 {
125         uint8_t ret;
126
127         DBG ("go_idle_state\n");
128         ao_sdcard_select();
129         ret = ao_sdcard_send_cmd(SDCARD_GO_IDLE_STATE, 0);
130         ao_sdcard_recv_reply(NULL, 0);
131         ao_sdcard_deselect();
132         DBG ("\tgo_idle_state status %02x\n", ret);
133         return ret;
134 }
135
136 static uint8_t
137 ao_sdcard_send_op_cond(void)
138 {
139         uint8_t ret;
140
141         DBG ("send_op_cond\n");
142         ao_sdcard_select();
143         ret = ao_sdcard_send_cmd(SDCARD_SEND_OP_COND, 0);
144         ao_sdcard_recv_reply(NULL, 0);
145         ao_sdcard_deselect();
146         DBG ("\tsend_op_cond %02x\n", ret);
147         return ret;
148 }
149
150 static uint8_t
151 ao_sdcard_send_if_cond(uint32_t arg, uint8_t send_if_cond_response[4])
152 {
153         uint8_t ret;
154
155         DBG ("send_if_cond\n");
156         ao_sdcard_select();
157         ret = ao_sdcard_send_cmd(SDCARD_SEND_IF_COND, arg);
158         if (ret != SDCARD_STATUS_IDLE_STATE) {
159                 DBG ("\tsend_if_cond failed %02x\n", ret);
160                 return ret;
161         }
162         ao_sdcard_recv_reply(send_if_cond_response, 4);
163         DBG ("send_if_cond status %02x response %02x %02x %02x %02x\n",
164                 ret,
165                 send_if_cond_response[0],
166                 send_if_cond_response[1],
167                 send_if_cond_response[2],
168                 send_if_cond_response[3]);
169         ao_sdcard_deselect();
170         return ret;
171 }
172
173 static uint8_t
174 ao_sdcard_set_blocklen(uint32_t blocklen)
175 {
176         uint8_t ret;
177
178         DBG ("set_blocklen %d\n", blocklen);
179         ao_sdcard_select();
180         ret = ao_sdcard_send_cmd(SDCARD_SET_BLOCKLEN, blocklen);
181         ao_sdcard_recv_reply(NULL, 0);
182         if (ret != SDCARD_STATUS_READY_STATE)
183                 DBG ("\tsend_if_cond failed %02x\n", ret);
184         return ret;
185         
186 }
187
188 static uint8_t
189 ao_sdcard_app_cmd(void)
190 {
191         uint8_t ret;
192
193         DBG ("app_cmd\n");
194         ao_sdcard_select();
195         ret = ao_sdcard_send_cmd(SDCARD_APP_CMD, 0);
196         ao_sdcard_recv_reply(NULL, 0);
197         ao_sdcard_deselect();
198         DBG ("\tapp_cmd status %02x\n");
199         return ret;
200 }
201
202 static uint8_t
203 ao_sdcard_app_send_op_cond(uint32_t arg)
204 {
205         uint8_t ret;
206
207         ret = ao_sdcard_app_cmd();
208         if (ret != SDCARD_STATUS_IDLE_STATE)
209                 return ret;
210         DBG("send_op_comd\n");
211         ao_sdcard_select();
212         ret = ao_sdcard_send_cmd(SDCARD_APP_SEND_OP_COMD, arg);
213         ao_sdcard_recv_reply(NULL, 0);
214         ao_sdcard_deselect();
215         DBG ("\tapp_send_op_cond status %02x\n", ret);
216         return ret;
217 }
218
219 static uint8_t
220 ao_sdcard_read_ocr(uint8_t read_ocr_response[4])
221 {
222         uint8_t ret;
223
224         DBG ("read_ocr\n");
225         ao_sdcard_select();
226         ret = ao_sdcard_send_cmd(SDCARD_READ_OCR, 0);
227         if (ret != SDCARD_STATUS_READY_STATE)
228                 DBG ("\tread_ocr failed %02x\n", ret);
229         else {
230                 ao_sdcard_recv_reply(read_ocr_response, 4);
231                 DBG ("\tread_ocr status %02x response %02x %02x %02x %02x\n", ret,
232                         read_ocr_response[0], read_ocr_response[1],
233                         read_ocr_response[2], read_ocr_response[3]);
234         }
235         ao_sdcard_deselect();
236         return ret;
237 }
238
239 static void
240 ao_sdcard_setup(void)
241 {
242         int     i;
243         uint8_t ret;
244         uint8_t response[10];
245
246         DBG ("Testing sdcard\n");
247
248         ao_sdcard_get_slow();
249         /*
250          * min 74 clocks with CS high
251          */
252         ao_sdcard_send_fixed(0xff, 10);
253
254         ao_delay(AO_MS_TO_TICKS(10));
255
256         /* Reset the card and get it into SPI mode */
257
258         for (i = 0; i < SDCARD_IDLE_WAIT; i++) {
259                 if (ao_sdcard_go_idle_state() == SDCARD_STATUS_IDLE_STATE)
260                         break;
261         }
262         if (i == SDCARD_IDLE_WAIT)
263                 goto bail;
264
265         /* Figure out what kind of card we have */
266
267         sdtype = ao_sdtype_unknown;
268
269         if (ao_sdcard_send_if_cond(0x1aa, response) == SDCARD_STATUS_IDLE_STATE) {
270                 uint32_t        arg = 0;
271                 uint8_t         sdver2 = 0;
272
273                 /* Check for SD version 2 */
274                 if ((response[2] & 0xf) == 1 && response[3] == 0xaa) {
275                         arg = 0x40000000;
276                         sdver2 = 1;
277                 }
278
279                 for (i = 0; i < SDCARD_IDLE_WAIT; i++) {
280                         ret = ao_sdcard_app_send_op_cond(arg);
281                         if (ret != SDCARD_STATUS_IDLE_STATE)
282                                 break;
283                 }
284                 if (ret != SDCARD_STATUS_READY_STATE) {
285                         /* MMC */
286                         for (i = 0; i < SDCARD_IDLE_WAIT; i++) {
287                                 ret = ao_sdcard_send_op_cond();
288                                 if (ret != SDCARD_STATUS_IDLE_STATE)
289                                         break;
290                         }
291                         if (ret != SDCARD_STATUS_READY_STATE)
292                                 goto bail;
293                         sdtype = ao_sdtype_mmc3;
294                 } else {
295                         /* SD */
296                         if (sdver2 != 0) {
297                                 ret = ao_sdcard_read_ocr(response);
298                                 if (ret != SDCARD_STATUS_READY_STATE)
299                                         goto bail;
300                                 if ((response[0] & 0xc0) == 0xc0)
301                                         sdtype = ao_sdtype_sd2block;
302                                 else
303                                         sdtype = ao_sdtype_sd2byte;
304                         } else {
305                                 sdtype = ao_sdtype_sd1;
306                         }
307                 }
308
309                 /* For everything but SDHC cards, set the block length */
310                 if (sdtype != ao_sdtype_sd2block) {
311                         ret = ao_sdcard_set_blocklen(512);
312                         if (ret != SDCARD_STATUS_READY_STATE)
313                                 DBG ("set_blocklen failed, ignoring\n");
314                 }
315         }
316
317         DBG ("SD card detected, type %d\n", sdtype);
318 bail:
319         ao_sdcard_put();
320 }
321
322 static uint8_t
323 ao_sdcard_wait_block_start(void)
324 {
325         int     i;
326         uint8_t v;
327
328         DBG ("\twait_block_start\n");
329         for (i = 0; i < SDCARD_BLOCK_TIMEOUT; i++) {
330                 ao_sdcard_recv(&v, 1);
331                 DBG("\t\trecv %02x\n", v);
332                 if (v != 0xff)
333                         break;
334         }
335         return v;
336 }
337
338 /*
339  * Read a block of 512 bytes from the card
340  */
341 uint8_t
342 ao_sdcard_read_block(uint32_t block, uint8_t *data)
343 {
344         uint8_t ret;
345         uint8_t crc[2];
346
347         ao_sdcard_lock();
348         if (!initialized) {
349                 ao_sdcard_setup();
350                 initialized = 1;
351                 if (sdtype != ao_sdtype_unknown)
352                         present = 1;
353         }
354         if (!present) {
355                 ao_sdcard_unlock();
356                 return 0;
357         }
358         if (sdtype != ao_sdtype_sd2block)
359                 block <<= 9;
360         ao_sdcard_get();
361         ao_sdcard_select();
362         ret = ao_sdcard_send_cmd(SDCARD_READ_BLOCK, block);
363         ao_sdcard_recv_reply(NULL, 0);
364         if (ret != SDCARD_STATUS_READY_STATE)
365                 goto bail;
366
367         if (ao_sdcard_wait_block_start() != 0xfe) {
368                 ret = 0x3f;
369                 goto bail;
370         }
371
372         ao_sdcard_recv(data, 512);
373         ao_sdcard_recv(crc, 2);
374 bail:
375         ao_sdcard_deselect();
376         ao_sdcard_put();
377         ao_sdcard_unlock();
378         return ret == SDCARD_STATUS_READY_STATE;
379 }
380
381 /*
382  * Write a block of 512 bytes to the card
383  */
384 uint8_t
385 ao_sdcard_write_block(uint32_t block, uint8_t *data)
386 {
387         /* Not doing anything until the file system code seems reasonable
388          */
389         return 1;
390 }
391
392 void
393 ao_sdcard_init(void)
394 {
395         ao_spi_init_cs(AO_SDCARD_SPI_CS_PORT, (1 << AO_SDCARD_SPI_CS_PIN));
396 }
397
398