altos: Add SD card writing function
[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 #define SDCARD_DEBUG    0
31
32 static uint8_t  initialized;
33 static uint8_t  present;
34 static uint8_t  mutex;
35 static enum ao_sdtype sdtype;
36
37 #define ao_sdcard_lock()        ao_mutex_get(&mutex)
38 #define ao_sdcard_unlock()      ao_mutex_put(&mutex)
39
40 #if 0
41 #define DBG(...) printf(__VA_ARGS__)
42 #else
43 #define DBG(...)
44 #endif
45
46 /*
47  * Send an SD command and await the status reply
48  */
49
50 static uint8_t
51 ao_sdcard_send_cmd(uint8_t cmd, uint32_t arg)
52 {
53         uint8_t data[6];
54         uint8_t reply;
55         int i;
56
57         DBG ("\tsend_cmd %d arg %08x\n", cmd, arg);
58         if (cmd != SDCARD_GO_IDLE_STATE) {
59                 for (i = 0; i < SDCARD_CMD_TIMEOUT; i++) {
60                         ao_sdcard_recv(&reply, 1);
61                         if (reply == 0xff)
62                                 break;
63                 }
64                 if (i == SDCARD_CMD_TIMEOUT)
65                         return SDCARD_STATUS_TIMEOUT;
66         }
67         
68         data[0] = cmd & 0x3f | 0x40;
69         data[1] = arg >> 24;
70         data[2] = arg >> 16;
71         data[3] = arg >> 8;
72         data[4] = arg;
73         if (cmd == SDCARD_GO_IDLE_STATE)
74                 data[5] = 0x95; /* Valid for 0 arg */
75         else if (cmd == SDCARD_SEND_IF_COND)
76                 data[5] = 0x87; /* Valid for 0x1aa arg */
77         else
78                 data[5] = 0xff; /* no CRC */
79         ao_sdcard_send(data, 6);
80
81         /* The first reply byte will be the status,
82          * which must have the high bit clear
83          */
84         for (i = 0; i < SDCARD_CMD_TIMEOUT; i++) {
85                 ao_sdcard_recv(&reply, 1);
86                 DBG ("\t\tgot byte %02x\n", reply);
87                 if ((reply & 0x80) == 0)
88                         return reply;
89         }
90         return SDCARD_STATUS_TIMEOUT;
91 }
92
93 /*
94  * Retrieve any reply, discarding the trailing CRC byte
95  */
96 static void
97 ao_sdcard_recv_reply(uint8_t *reply, int len)
98 {
99         uint8_t discard;
100
101         if (len)
102                 ao_sdcard_recv(reply, len);
103         /* trailing byte */
104         ao_sdcard_recv(&discard, 1);
105 }
106
107 /*
108  * Wait while the card is busy. The
109  * card will return a stream of 0xff
110  * until it isn't busy anymore
111  */
112 static void
113 ao_sdcard_wait_busy(void)
114 {
115         uint8_t v;
116
117         do {
118                 ao_sdcard_recv(&v, 1);
119         } while (v != 0xff);
120         ao_sdcard_send_fixed(0xff, 1);
121 }
122
123 static uint8_t
124 ao_sdcard_go_idle_state(void)
125 {
126         uint8_t ret;
127
128         DBG ("go_idle_state\n");
129         ao_sdcard_select();
130         ret = ao_sdcard_send_cmd(SDCARD_GO_IDLE_STATE, 0);
131         ao_sdcard_recv_reply(NULL, 0);
132         ao_sdcard_deselect();
133         DBG ("\tgo_idle_state status %02x\n", ret);
134         return ret;
135 }
136
137 static uint8_t
138 ao_sdcard_send_op_cond(void)
139 {
140         uint8_t ret;
141
142         DBG ("send_op_cond\n");
143         ao_sdcard_select();
144         ret = ao_sdcard_send_cmd(SDCARD_SEND_OP_COND, 0);
145         ao_sdcard_recv_reply(NULL, 0);
146         ao_sdcard_deselect();
147         DBG ("\tsend_op_cond %02x\n", ret);
148         return ret;
149 }
150
151 static uint8_t
152 ao_sdcard_send_if_cond(uint32_t arg, uint8_t send_if_cond_response[4])
153 {
154         uint8_t ret;
155
156         DBG ("send_if_cond\n");
157         ao_sdcard_select();
158         ret = ao_sdcard_send_cmd(SDCARD_SEND_IF_COND, arg);
159         if (ret != SDCARD_STATUS_IDLE_STATE) {
160                 DBG ("\tsend_if_cond failed %02x\n", ret);
161                 return ret;
162         }
163         ao_sdcard_recv_reply(send_if_cond_response, 4);
164         DBG ("send_if_cond status %02x response %02x %02x %02x %02x\n",
165                 ret,
166                 send_if_cond_response[0],
167                 send_if_cond_response[1],
168                 send_if_cond_response[2],
169                 send_if_cond_response[3]);
170         ao_sdcard_deselect();
171         return ret;
172 }
173
174 static uint8_t
175 ao_sdcard_send_status(void)
176 {
177         uint8_t ret;
178
179         DBG ("send_status\n");
180         ao_sdcard_select();
181         ret = ao_sdcard_send_cmd(SDCARD_SEND_STATUS, 0);
182         ao_sdcard_recv_reply(NULL, 0);
183         if (ret != SDCARD_STATUS_READY_STATE)
184                 DBG ("\tsend_if_cond failed %02x\n", ret);
185         return ret;
186 }
187
188 static uint8_t
189 ao_sdcard_set_blocklen(uint32_t blocklen)
190 {
191         uint8_t ret;
192
193         DBG ("set_blocklen %d\n", blocklen);
194         ao_sdcard_select();
195         ret = ao_sdcard_send_cmd(SDCARD_SET_BLOCKLEN, blocklen);
196         ao_sdcard_recv_reply(NULL, 0);
197         if (ret != SDCARD_STATUS_READY_STATE)
198                 DBG ("\tsend_if_cond failed %02x\n", ret);
199         return ret;
200 }
201
202 static uint8_t
203 ao_sdcard_app_cmd(void)
204 {
205         uint8_t ret;
206
207         DBG ("app_cmd\n");
208         ao_sdcard_select();
209         ret = ao_sdcard_send_cmd(SDCARD_APP_CMD, 0);
210         ao_sdcard_recv_reply(NULL, 0);
211         ao_sdcard_deselect();
212         DBG ("\tapp_cmd status %02x\n");
213         return ret;
214 }
215
216 static uint8_t
217 ao_sdcard_app_send_op_cond(uint32_t arg)
218 {
219         uint8_t ret;
220
221         ret = ao_sdcard_app_cmd();
222         if (ret != SDCARD_STATUS_IDLE_STATE)
223                 return ret;
224         DBG("send_op_comd\n");
225         ao_sdcard_select();
226         ret = ao_sdcard_send_cmd(SDCARD_APP_SEND_OP_COMD, arg);
227         ao_sdcard_recv_reply(NULL, 0);
228         ao_sdcard_deselect();
229         DBG ("\tapp_send_op_cond status %02x\n", ret);
230         return ret;
231 }
232
233 static uint8_t
234 ao_sdcard_read_ocr(uint8_t read_ocr_response[4])
235 {
236         uint8_t ret;
237
238         DBG ("read_ocr\n");
239         ao_sdcard_select();
240         ret = ao_sdcard_send_cmd(SDCARD_READ_OCR, 0);
241         if (ret != SDCARD_STATUS_READY_STATE)
242                 DBG ("\tread_ocr failed %02x\n", ret);
243         else {
244                 ao_sdcard_recv_reply(read_ocr_response, 4);
245                 DBG ("\tread_ocr status %02x response %02x %02x %02x %02x\n", ret,
246                         read_ocr_response[0], read_ocr_response[1],
247                         read_ocr_response[2], read_ocr_response[3]);
248         }
249         ao_sdcard_deselect();
250         return ret;
251 }
252
253 static void
254 ao_sdcard_setup(void)
255 {
256         int     i;
257         uint8_t ret;
258         uint8_t response[10];
259
260         DBG ("Testing sdcard\n");
261
262         ao_sdcard_get_slow();
263         /*
264          * min 74 clocks with CS high
265          */
266         ao_sdcard_send_fixed(0xff, 10);
267
268         ao_delay(AO_MS_TO_TICKS(10));
269
270         /* Reset the card and get it into SPI mode */
271
272         for (i = 0; i < SDCARD_IDLE_WAIT; i++) {
273                 if (ao_sdcard_go_idle_state() == SDCARD_STATUS_IDLE_STATE)
274                         break;
275         }
276         if (i == SDCARD_IDLE_WAIT)
277                 goto bail;
278
279         /* Figure out what kind of card we have */
280
281         sdtype = ao_sdtype_unknown;
282
283         if (ao_sdcard_send_if_cond(0x1aa, response) == SDCARD_STATUS_IDLE_STATE) {
284                 uint32_t        arg = 0;
285                 uint8_t         sdver2 = 0;
286
287                 /* Check for SD version 2 */
288                 if ((response[2] & 0xf) == 1 && response[3] == 0xaa) {
289                         arg = 0x40000000;
290                         sdver2 = 1;
291                 }
292
293                 for (i = 0; i < SDCARD_IDLE_WAIT; i++) {
294                         ret = ao_sdcard_app_send_op_cond(arg);
295                         if (ret != SDCARD_STATUS_IDLE_STATE)
296                                 break;
297                 }
298                 if (ret != SDCARD_STATUS_READY_STATE) {
299                         /* MMC */
300                         for (i = 0; i < SDCARD_IDLE_WAIT; i++) {
301                                 ret = ao_sdcard_send_op_cond();
302                                 if (ret != SDCARD_STATUS_IDLE_STATE)
303                                         break;
304                         }
305                         if (ret != SDCARD_STATUS_READY_STATE)
306                                 goto bail;
307                         sdtype = ao_sdtype_mmc3;
308                 } else {
309                         /* SD */
310                         if (sdver2 != 0) {
311                                 ret = ao_sdcard_read_ocr(response);
312                                 if (ret != SDCARD_STATUS_READY_STATE)
313                                         goto bail;
314                                 if ((response[0] & 0xc0) == 0xc0)
315                                         sdtype = ao_sdtype_sd2block;
316                                 else
317                                         sdtype = ao_sdtype_sd2byte;
318                         } else {
319                                 sdtype = ao_sdtype_sd1;
320                         }
321                 }
322
323                 /* For everything but SDHC cards, set the block length */
324                 if (sdtype != ao_sdtype_sd2block) {
325                         ret = ao_sdcard_set_blocklen(512);
326                         if (ret != SDCARD_STATUS_READY_STATE)
327                                 DBG ("set_blocklen failed, ignoring\n");
328                 }
329         }
330
331         DBG ("SD card detected, type %d\n", sdtype);
332 bail:
333         ao_sdcard_put();
334 }
335
336 static uint8_t
337 ao_sdcard_wait_block_start(void)
338 {
339         int     i;
340         uint8_t v;
341
342         DBG ("\twait_block_start\n");
343         for (i = 0; i < SDCARD_BLOCK_TIMEOUT; i++) {
344                 ao_sdcard_recv(&v, 1);
345                 DBG("\t\trecv %02x\n", v);
346                 if (v != 0xff)
347                         break;
348         }
349         return v;
350 }
351
352 /*
353  * Read a block of 512 bytes from the card
354  */
355 uint8_t
356 ao_sdcard_read_block(uint32_t block, uint8_t *data)
357 {
358         uint8_t ret;
359         uint8_t crc[2];
360
361         ao_sdcard_lock();
362         if (!initialized) {
363                 ao_sdcard_setup();
364                 initialized = 1;
365                 if (sdtype != ao_sdtype_unknown)
366                         present = 1;
367         }
368         if (!present) {
369                 ao_sdcard_unlock();
370                 return 0;
371         }
372         if (sdtype != ao_sdtype_sd2block)
373                 block <<= 9;
374         ao_sdcard_get();
375         ao_sdcard_select();
376         ret = ao_sdcard_send_cmd(SDCARD_READ_BLOCK, block);
377         ao_sdcard_recv_reply(NULL, 0);
378         if (ret != SDCARD_STATUS_READY_STATE)
379                 goto bail;
380
381         /* Wait for the data start block marker */
382         if (ao_sdcard_wait_block_start() != SDCARD_DATA_START_BLOCK) {
383                 ret = 0x3f;
384                 goto bail;
385         }
386
387         ao_sdcard_recv(data, 512);
388         ao_sdcard_recv(crc, 2);
389 bail:
390         ao_sdcard_deselect();
391         ao_sdcard_put();
392         ao_sdcard_unlock();
393         return ret == SDCARD_STATUS_READY_STATE;
394 }
395
396 /*
397  * Write a block of 512 bytes to the card
398  */
399 uint8_t
400 ao_sdcard_write_block(uint32_t block, uint8_t *data)
401 {
402         uint8_t ret;
403         uint8_t response;
404         uint8_t start_block[2];
405         int     i;
406
407         ao_sdcard_lock();
408         if (!initialized) {
409                 ao_sdcard_setup();
410                 initialized = 1;
411                 if (sdtype != ao_sdtype_unknown)
412                         present = 1;
413         }
414         if (!present) {
415                 ao_sdcard_unlock();
416                 return 0;
417         }
418         if (sdtype != ao_sdtype_sd2block)
419                 block <<= 9;
420         ao_sdcard_get();
421         ao_sdcard_select();
422
423         ret = ao_sdcard_send_cmd(SDCARD_WRITE_BLOCK, block);
424         ao_sdcard_recv_reply(NULL, 0);
425         if (ret != SDCARD_STATUS_READY_STATE)
426                 goto bail;
427
428         /* Write a pad byte followed by the data start block marker */
429         start_block[0] = 0xff;
430         start_block[1] = SDCARD_DATA_START_BLOCK;
431         ao_sdcard_send(start_block, 2);
432
433         /* Send the data */
434         ao_sdcard_send(data, 512);
435
436         /* Fake the CRC */
437         ao_sdcard_send_fixed(0xff, 2);
438
439         /* See if the card liked the data */
440         ao_sdcard_recv(&response, 1);
441         if ((response & SDCARD_DATA_RES_MASK) != SDCARD_DATA_RES_ACCEPTED) {
442                 ret = 0x3f;
443                 goto bail;
444         }
445                 
446         /* Wait for the bus to go idle (should be done with an interrupt) */
447         for (i = 0; i < SDCARD_IDLE_TIMEOUT; i++) {
448                 ao_sdcard_recv(&response, 1);
449                 if (response == 0xff)
450                         break;
451         }
452         if (i == SDCARD_IDLE_TIMEOUT)
453                 ret = 0x3f;
454 bail:
455         ao_sdcard_deselect();
456         ao_sdcard_put();
457         ao_sdcard_unlock();
458         return ret == SDCARD_STATUS_READY_STATE;
459 }
460
461 #if SDCARD_DEBUG
462 static uint8_t  test_data[512];
463
464 static void
465 ao_sdcard_test_read(void)
466 {
467         int i;
468         if (!ao_sdcard_read_block(1, test_data)) {
469                 printf ("read error\n");
470                 return;
471         }
472         printf ("data:");
473         for (i = 0; i < 18; i++)
474                 printf (" %02x", test_data[i]);
475         printf ("\n");
476 }
477
478 static void
479 ao_sdcard_test_write(void)
480 {
481         int     i;
482         printf ("data:");
483         for (i = 0; i < 16; i++) {
484                 test_data[i]++;
485                 printf (" %02x", test_data[i]);
486         }
487         printf ("\n");
488         if (!ao_sdcard_write_block(1, test_data)) {
489                 printf ("write error\n");
490                 return;
491         }
492 }
493
494 static const struct ao_cmds ao_sdcard_cmds[] = {
495         { ao_sdcard_test_read,  "x\0Test read" },
496         { ao_sdcard_test_write, "y\0Test read" },
497         { 0, NULL },
498 };
499 #endif
500
501 void
502 ao_sdcard_init(void)
503 {
504         ao_spi_init_cs(AO_SDCARD_SPI_CS_PORT, (1 << AO_SDCARD_SPI_CS_PIN));
505 #if SDCARD_DEBUG
506         ao_cmd_register(&ao_sdcard_cmds[0]);
507 #endif
508 }