Switch from GPLv2 to GPLv2+
[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; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18
19 #include "ao.h"
20 #include "ao_sdcard.h"
21
22 #if HAS_RADIO
23 extern uint8_t ao_radio_mutex;
24 #define get_radio()     ao_mutex_get(&ao_radio_mutex)
25 #define put_radio()     ao_mutex_put(&ao_radio_mutex)
26 #else
27 #define get_radio()
28 #define put_radio()
29 #endif
30
31 #define ao_sdcard_get_slow() do { get_radio(); ao_spi_get(AO_SDCARD_SPI_BUS, AO_SPI_SPEED_250kHz); } while (0)
32 #define ao_sdcard_get() do { get_radio(); ao_spi_get(AO_SDCARD_SPI_BUS, AO_SPI_SPEED_FAST); } while (0)
33 #define ao_sdcard_put() do { ao_spi_put(AO_SDCARD_SPI_BUS); put_radio(); } while (0)
34 #define ao_sdcard_send_fixed(d,l)       ao_spi_send_fixed((d), (l), AO_SDCARD_SPI_BUS)
35 #define ao_sdcard_send(d,l)             ao_spi_send((d), (l), AO_SDCARD_SPI_BUS)
36 #define ao_sdcard_recv(d,l)             ao_spi_recv((d), (l), AO_SDCARD_SPI_BUS)
37 #define ao_sdcard_select()              ao_gpio_set(AO_SDCARD_SPI_CS_PORT,AO_SDCARD_SPI_CS_PIN,AO_SDCARD_SPI_CS,0)
38 #define ao_sdcard_deselect()            ao_gpio_set(AO_SDCARD_SPI_CS_PORT,AO_SDCARD_SPI_CS_PIN,AO_SDCARD_SPI_CS,1)
39
40 /* Include SD card commands */
41 #define SDCARD_DEBUG    0
42
43 /* Spew SD tracing */
44 #define SDCARD_TRACE    0
45
46 /* Emit error and warning messages */
47 #define SDCARD_WARN     0
48
49 static uint8_t  initialized;
50 static uint8_t  present;
51 static uint8_t  mutex;
52 static enum ao_sdtype sdtype;
53
54 #define ao_sdcard_lock()        ao_mutex_get(&mutex)
55 #define ao_sdcard_unlock()      ao_mutex_put(&mutex)
56
57 #if SDCARD_TRACE
58 #define DBG(...) printf(__VA_ARGS__)
59 #else
60 #define DBG(...) (void) 0
61 #endif
62
63 #if SDCARD_WARN
64 #define WARN(...) printf(__VA_ARGS__)
65 #else
66 #define WARN(...) (void) 0
67 #endif
68
69 #define later(x,y)      ((int16_t) ((x) - (y)) >= 0)
70
71 /*
72  * Wait while the card is busy. The card will return a stream of 0xff
73  * when it is ready to accept a command
74  */
75
76 static uint8_t
77 ao_sdcard_wait_busy(void)
78 {
79         uint16_t        timeout = ao_time() + SDCARD_BUSY_TIMEOUT;
80         uint8_t         reply;
81         for (;;) {
82                 ao_sdcard_recv(&reply, 1);
83                 DBG("\t\twait busy %02x\n", reply);
84                 if (reply == 0xff)
85                         break;
86                 if (later(ao_time(), timeout)) {
87                         WARN("wait busy timeout\n");
88                         return 0;
89                 }
90         }
91         return 1;
92 }
93
94
95 /*
96  * Send an SD command and await the status reply
97  */
98
99 static uint8_t
100 ao_sdcard_send_cmd(uint8_t cmd, uint32_t arg)
101 {
102         uint8_t data[6];
103         uint8_t reply;
104         uint16_t timeout;
105
106         DBG ("\tsend_cmd %d arg %08x\n", cmd, arg);
107
108         /* Wait for the card to not be busy */
109         if (cmd != SDCARD_GO_IDLE_STATE) {
110                 if (!ao_sdcard_wait_busy())
111                         return SDCARD_STATUS_TIMEOUT;
112         }
113         
114         data[0] = (cmd & 0x3f) | 0x40;
115         data[1] = arg >> 24;
116         data[2] = arg >> 16;
117         data[3] = arg >> 8;
118         data[4] = arg;
119         if (cmd == SDCARD_GO_IDLE_STATE)
120                 data[5] = 0x95; /* Valid for 0 arg */
121         else if (cmd == SDCARD_SEND_IF_COND)
122                 data[5] = 0x87; /* Valid for 0x1aa arg */
123         else
124                 data[5] = 0xff; /* no CRC */
125         ao_sdcard_send(data, 6);
126
127         /* The first reply byte will be the status,
128          * which must have the high bit clear
129          */
130         timeout = ao_time() + SDCARD_CMD_TIMEOUT;
131         for (;;) {
132                 ao_sdcard_recv(&reply, 1);
133                 DBG ("\t\tgot byte %02x\n", reply);
134                 if ((reply & 0x80) == 0)
135                         break;
136                 if (later(ao_time(), timeout)) {
137                         WARN("send_cmd %02x timeout\n", cmd);
138                         return SDCARD_STATUS_TIMEOUT;
139                 }
140         }
141 #if SDCARD_WARN
142         if (reply != SDCARD_STATUS_READY_STATE && reply != SDCARD_STATUS_IDLE_STATE)
143                 WARN("send_cmd %d failed %02x\n", cmd, reply);
144 #endif
145         return reply;
146 }
147
148 /*
149  * Retrieve any reply, discarding the trailing CRC byte
150  */
151 static void
152 ao_sdcard_recv_reply(uint8_t *reply, int len)
153 {
154         uint8_t discard;
155
156         if (len)
157                 ao_sdcard_recv(reply, len);
158         /* trailing byte */
159         ao_sdcard_recv(&discard, 1);
160 }
161
162 /*
163  * Switch to 'idle' state. This is used to get the card into SPI mode
164  */
165 static uint8_t
166 ao_sdcard_go_idle_state(void)
167 {
168         uint8_t ret;
169
170         DBG ("go_idle_state\n");
171         ao_sdcard_select();
172         ret = ao_sdcard_send_cmd(SDCARD_GO_IDLE_STATE, 0);
173         ao_sdcard_recv_reply(NULL, 0);
174         ao_sdcard_deselect();
175         DBG ("\tgo_idle_state status %02x\n", ret);
176         return ret;
177 }
178
179 static uint8_t
180 ao_sdcard_send_op_cond(void)
181 {
182         uint8_t ret;
183
184         DBG ("send_op_cond\n");
185         ao_sdcard_select();
186         ret = ao_sdcard_send_cmd(SDCARD_SEND_OP_COND, 0);
187         ao_sdcard_recv_reply(NULL, 0);
188         ao_sdcard_deselect();
189         DBG ("\tsend_op_cond %02x\n", ret);
190         return ret;
191 }
192
193 static uint8_t
194 ao_sdcard_send_if_cond(uint32_t arg, uint8_t send_if_cond_response[4])
195 {
196         uint8_t ret;
197
198         DBG ("send_if_cond\n");
199         ao_sdcard_select();
200         ret = ao_sdcard_send_cmd(SDCARD_SEND_IF_COND, arg);
201         if (ret != SDCARD_STATUS_IDLE_STATE) {
202                 DBG ("\tsend_if_cond failed %02x\n", ret);
203                 return ret;
204         }
205         ao_sdcard_recv_reply(send_if_cond_response, 4);
206         DBG ("send_if_cond status %02x response %02x %02x %02x %02x\n",
207                 ret,
208                 send_if_cond_response[0],
209                 send_if_cond_response[1],
210                 send_if_cond_response[2],
211                 send_if_cond_response[3]);
212         ao_sdcard_deselect();
213         return ret;
214 }
215
216 /*
217  * _ao_sdcard_send_status
218  *
219  * Get the 2-byte status value.
220  *
221  * Called from other functions with CS held low already,
222  * hence prefixing the name with '_'
223  */
224 static uint16_t
225 _ao_sdcard_send_status(void)
226 {
227         uint8_t ret;
228         uint8_t extra;
229
230         DBG ("send_status\n");
231         ret = ao_sdcard_send_cmd(SDCARD_SEND_STATUS, 0);
232         ao_sdcard_recv_reply(&extra, 1);
233         if (ret != SDCARD_STATUS_READY_STATE)
234                 DBG ("\tsend_if_cond failed %02x\n", ret);
235         return ret | (extra << 8);
236 }
237
238 /*
239  * ao_sdcard_set_blocklen
240  *
241  * Set the block length for future read and write commands
242  */
243 static uint8_t
244 ao_sdcard_set_blocklen(uint32_t blocklen)
245 {
246         uint8_t ret;
247
248         DBG ("set_blocklen %d\n", blocklen);
249         ao_sdcard_select();
250         ret = ao_sdcard_send_cmd(SDCARD_SET_BLOCKLEN, blocklen);
251         ao_sdcard_recv_reply(NULL, 0);
252         ao_sdcard_deselect();
253         if (ret != SDCARD_STATUS_READY_STATE)
254                 DBG ("\tsend_if_cond failed %02x\n", ret);
255         return ret;
256 }
257
258 /*
259  * _ao_sdcard_app_cmd
260  *
261  * Send the app command prefix
262  *
263  * Called with the CS held low, hence
264  * the '_' prefix
265  */
266 static uint8_t
267 _ao_sdcard_app_cmd(void)
268 {
269         uint8_t ret;
270
271         DBG ("app_cmd\n");
272         ret = ao_sdcard_send_cmd(SDCARD_APP_CMD, 0);
273         ao_sdcard_recv_reply(NULL, 0);
274         DBG ("\tapp_cmd status %02x\n");
275         return ret;
276 }
277
278 static uint8_t
279 ao_sdcard_app_send_op_cond(uint32_t arg)
280 {
281         uint8_t ret;
282
283         DBG("send_op_comd\n");
284         ao_sdcard_select();
285         ret = _ao_sdcard_app_cmd();
286         if (ret != SDCARD_STATUS_IDLE_STATE)
287                 goto bail;
288         ret = ao_sdcard_send_cmd(SDCARD_APP_SEND_OP_COMD, arg);
289         ao_sdcard_recv_reply(NULL, 0);
290 bail:
291         ao_sdcard_deselect();
292         DBG ("\tapp_send_op_cond status %02x\n", ret);
293         return ret;
294 }
295
296 static uint8_t
297 ao_sdcard_read_ocr(uint8_t read_ocr_response[4])
298 {
299         uint8_t ret;
300
301         DBG ("read_ocr\n");
302         ao_sdcard_select();
303         ret = ao_sdcard_send_cmd(SDCARD_READ_OCR, 0);
304         if (ret != SDCARD_STATUS_READY_STATE)
305                 DBG ("\tread_ocr failed %02x\n", ret);
306         else {
307                 ao_sdcard_recv_reply(read_ocr_response, 4);
308                 DBG ("\tread_ocr status %02x response %02x %02x %02x %02x\n", ret,
309                         read_ocr_response[0], read_ocr_response[1],
310                         read_ocr_response[2], read_ocr_response[3]);
311         }
312         ao_sdcard_deselect();
313         return ret;
314 }
315
316 /*
317  * Follow the flow-chart defined by the SD group to
318  * initialize the card and figure out what kind it is
319  */
320 static void
321 ao_sdcard_setup(void)
322 {
323         int     i;
324         uint8_t ret;
325         uint8_t response[10];
326
327         DBG ("Testing sdcard\n");
328
329         ao_sdcard_get_slow();
330         /*
331          * min 74 clocks with CS high
332          */
333         ao_sdcard_send_fixed(0xff, 10);
334
335         /* Reset the card and get it into SPI mode */
336         for (i = 0; i < SDCARD_IDLE_RETRY; i++) {
337                 if (ao_sdcard_go_idle_state() == SDCARD_STATUS_IDLE_STATE)
338                         break;
339         }
340         if (i == SDCARD_IDLE_RETRY)
341                 goto bail;
342
343         /* Figure out what kind of card we have */
344         sdtype = ao_sdtype_unknown;
345
346         if (ao_sdcard_send_if_cond(0x1aa, response) == SDCARD_STATUS_IDLE_STATE) {
347                 uint32_t        arg = 0;
348                 uint8_t         sdver2 = 0;
349
350                 /* Check for SD version 2 */
351                 if ((response[2] & 0xf) == 1 && response[3] == 0xaa) {
352                         arg = 0x40000000;
353                         sdver2 = 1;
354                 }
355
356                 for (i = 0; i < SDCARD_OP_COND_RETRY; i++) {
357                         ao_delay(AO_MS_TO_TICKS(10));
358                         ret = ao_sdcard_app_send_op_cond(arg);
359                         if (ret != SDCARD_STATUS_IDLE_STATE)
360                                 break;
361                 }
362                 if (ret != SDCARD_STATUS_READY_STATE) {
363                         /* MMC */
364                         for (i = 0; i < SDCARD_OP_COND_RETRY; i++) {
365                                 ao_delay(AO_MS_TO_TICKS(10));
366                                 ret = ao_sdcard_send_op_cond();
367                                 if (ret != SDCARD_STATUS_IDLE_STATE)
368                                         break;
369                         }
370                         if (ret != SDCARD_STATUS_READY_STATE)
371                                 goto bail;
372                         sdtype = ao_sdtype_mmc3;
373                 } else {
374                         /* SD */
375                         if (sdver2 != 0) {
376                                 ret = ao_sdcard_read_ocr(response);
377                                 if (ret != SDCARD_STATUS_READY_STATE)
378                                         goto bail;
379                                 if ((response[0] & 0xc0) == 0xc0)
380                                         sdtype = ao_sdtype_sd2block;
381                                 else
382                                         sdtype = ao_sdtype_sd2byte;
383                         } else {
384                                 sdtype = ao_sdtype_sd1;
385                         }
386                 }
387
388                 /* For everything but SDHC cards, set the block length */
389                 if (sdtype != ao_sdtype_sd2block) {
390                         ret = ao_sdcard_set_blocklen(512);
391                         if (ret != SDCARD_STATUS_READY_STATE)
392                                 DBG ("set_blocklen failed, ignoring\n");
393                 }
394         }
395
396         DBG ("SD card detected, type %d\n", sdtype);
397 bail:
398         ao_sdcard_put();
399 }
400
401 static uint8_t
402 _ao_sdcard_reset(void)
403 {
404         int i;
405         uint8_t ret = 0x3f;
406         uint8_t response[10];
407
408         for (i = 0; i < SDCARD_IDLE_RETRY; i++) {
409                 if (ao_sdcard_go_idle_state() == SDCARD_STATUS_IDLE_STATE)
410                         break;
411         }
412         if (i == SDCARD_IDLE_RETRY) {
413                 ret = 0x3f;
414                 goto bail;
415         }
416
417         /* Follow the setup path to get the card out of idle state and
418          * up and running again
419          */
420         if (ao_sdcard_send_if_cond(0x1aa, response) == SDCARD_STATUS_IDLE_STATE) {
421                 uint32_t        arg = 0;
422 //              uint8_t         sdver2 = 0;
423
424                 /* Check for SD version 2 */
425                 if ((response[2] & 0xf) == 1 && response[3] == 0xaa) {
426                         arg = 0x40000000;
427 //                      sdver2 = 1;
428                 }
429
430                 for (i = 0; i < SDCARD_IDLE_RETRY; i++) {
431                         ret = ao_sdcard_app_send_op_cond(arg);
432                         if (ret != SDCARD_STATUS_IDLE_STATE)
433                                 break;
434                 }
435
436                 if (ret != SDCARD_STATUS_READY_STATE) {
437                         /* MMC */
438                         for (i = 0; i < SDCARD_IDLE_RETRY; i++) {
439                                 ret = ao_sdcard_send_op_cond();
440                                 if (ret != SDCARD_STATUS_IDLE_STATE)
441                                         break;
442                         }
443                         if (ret != SDCARD_STATUS_READY_STATE)
444                                 goto bail;
445                 }
446
447                 /* For everything but SDHC cards, set the block length */
448                 if (sdtype != ao_sdtype_sd2block) {
449                         ret = ao_sdcard_set_blocklen(512);
450                         if (ret != SDCARD_STATUS_READY_STATE)
451                                 DBG ("set_blocklen failed, ignoring\n");
452                 }
453         }
454 bail:
455         return ret;
456 }
457
458 /*
459  * The card will send 0xff until it is ready to send
460  * the data block at which point it will send the START_BLOCK
461  * marker followed by the data. This function waits while
462  * the card is sending 0xff
463  */
464 static uint8_t
465 ao_sdcard_wait_block_start(void)
466 {
467         uint8_t         v;
468         uint16_t        timeout = ao_time() + SDCARD_BLOCK_TIMEOUT;
469
470         DBG ("\twait_block_start\n");
471         for (;;) {
472                 ao_sdcard_recv(&v, 1);
473                 DBG("\t\trecv %02x\n", v);
474                 if (v != 0xff)
475                         break;
476                 if (later(ao_time(), timeout)) {
477                         printf ("wait block start timeout\n");
478                         return 0xff;
479                 }
480         }
481         return v;
482 }
483
484 /*
485  * Read a block of 512 bytes from the card
486  */
487 uint8_t
488 ao_sdcard_read_block(uint32_t block, uint8_t *data)
489 {
490         uint8_t ret = 0x3f;
491         uint8_t start_block;
492         uint8_t crc[2];
493         int tries;
494
495         ao_sdcard_lock();
496         if (!initialized) {
497                 ao_sdcard_setup();
498                 initialized = 1;
499                 if (sdtype != ao_sdtype_unknown)
500                         present = 1;
501         }
502         if (!present) {
503                 ao_sdcard_unlock();
504                 return 0;
505         }
506         DBG("read block %d\n", block);
507         if (sdtype != ao_sdtype_sd2block)
508                 block <<= 9;
509
510         ao_sdcard_get();
511         for (tries = 0; tries < 10; tries++) {
512                 ao_sdcard_select();
513
514                 ret = ao_sdcard_send_cmd(SDCARD_READ_BLOCK, block);
515                 ao_sdcard_recv_reply(NULL, 0);
516                 if (ret != SDCARD_STATUS_READY_STATE) {
517                         uint16_t        status;
518                         WARN ("read block command failed %d status %02x\n", block, ret);
519                         status = _ao_sdcard_send_status();
520                         WARN ("\tstatus now %04x\n", status);
521                         (void) status;
522                         goto bail;
523                 }
524
525                 ao_sdcard_send_fixed(0xff, 1);
526
527                 /* Wait for the data start block marker */
528                 start_block = ao_sdcard_wait_block_start();
529                 if (start_block != SDCARD_DATA_START_BLOCK) {
530                         WARN ("wait block start failed %02x\n", start_block);
531                         ret = 0x3f;
532                         goto bail;
533                 }
534
535                 ao_sdcard_recv(data, 512);
536                 ao_sdcard_recv(crc, 2);
537         bail:
538                 ao_sdcard_deselect();
539                 if (ret == SDCARD_STATUS_READY_STATE)
540                         break;
541                 if (ret == SDCARD_STATUS_IDLE_STATE) {
542                         ret = _ao_sdcard_reset();
543                         if (ret != SDCARD_STATUS_READY_STATE)
544                                 break;
545                 }
546         }
547         ao_sdcard_put();
548         ao_sdcard_unlock();
549
550 #if SDCARD_WARN
551         if (ret != SDCARD_STATUS_READY_STATE)
552                 WARN("read failed\n");
553         else if (tries)
554                 WARN("took %d tries to read %d\n", tries + 1, block);
555 #endif
556
557         DBG("read %s\n", ret == SDCARD_STATUS_READY_STATE ? "success" : "failure");
558         return ret == SDCARD_STATUS_READY_STATE;
559 }
560
561 /*
562  * Write a block of 512 bytes to the card
563  */
564 uint8_t
565 ao_sdcard_write_block(uint32_t block, uint8_t *data)
566 {
567         uint8_t ret;
568         uint8_t response[1];
569         uint8_t start_block[8];
570         uint16_t status;
571         int     tries;
572
573         ao_sdcard_lock();
574         if (!initialized) {
575                 ao_sdcard_setup();
576                 initialized = 1;
577                 if (sdtype != ao_sdtype_unknown)
578                         present = 1;
579         }
580         if (!present) {
581                 ao_sdcard_unlock();
582                 return 0;
583         }
584         DBG("write block %d\n", block);
585         if (sdtype != ao_sdtype_sd2block)
586                 block <<= 9;
587
588         ao_sdcard_get();
589
590         for (tries = 0; tries < 10; tries++) {
591                 ao_sdcard_select();
592
593                 ret = ao_sdcard_send_cmd(SDCARD_WRITE_BLOCK, block);
594                 ao_sdcard_recv_reply(NULL, 0);
595                 if (ret != SDCARD_STATUS_READY_STATE)
596                         goto bail;
597
598                 /* Write a pad byte followed by the data start block marker */
599                 start_block[0] = 0xff;
600                 start_block[1] = SDCARD_DATA_START_BLOCK;
601                 ao_sdcard_send(start_block, 2);
602
603                 /* Send the data */
604                 ao_sdcard_send(data, 512);
605
606                 /* Fake the CRC */
607                 ao_sdcard_send_fixed(0xff, 2);
608
609                 /* See if the card liked the data */
610                 ao_sdcard_recv(response, sizeof (response));
611                 if ((response[0] & SDCARD_DATA_RES_MASK) != SDCARD_DATA_RES_ACCEPTED) {
612                         int i;
613                         WARN("Data not accepted, response");
614                         for (i = 0; i < (int) sizeof (response); i++)
615                                 WARN(" %02x", response[i]);
616                         WARN("\n");
617                         ret = 0x3f;
618                         goto bail;
619                 }
620                 
621                 /* Wait for the bus to go idle (should be done with an interrupt?) */
622                 if (!ao_sdcard_wait_busy()) {
623                         ret = 0x3f;
624                         goto bail;
625                 }
626
627                 /* Check the current status after the write completes */
628                 status = _ao_sdcard_send_status();
629                 if ((status & 0xff) != SDCARD_STATUS_READY_STATE) {
630                         WARN ("send status after write %04x\n", status);
631                         ret = status & 0xff;
632                         goto bail;
633                 }
634         bail:
635                 ao_sdcard_deselect();
636                 DBG("write %s\n", ret == SDCARD_STATUS_READY_STATE ? "success" : "failure");
637                 if (ret == SDCARD_STATUS_READY_STATE)
638                         break;
639         }
640         ao_sdcard_put();
641         ao_sdcard_unlock();
642         if (tries)
643                 WARN("took %d tries to write %d\n", tries + 1, block);
644
645         return ret == SDCARD_STATUS_READY_STATE;
646 }
647
648 #if SDCARD_DEBUG
649 static uint8_t  test_data[512];
650
651 static void
652 ao_sdcard_test_read(void)
653 {
654         int i;
655
656         ao_cmd_decimal();
657         if (ao_cmd_status != ao_cmd_success)
658                 return;
659         
660         for (i = 0; i < 100; i++) {
661                 printf ("."); flush();
662                 if (!ao_sdcard_read_block(ao_cmd_lex_u32+i, test_data)) {
663                         printf ("read error %d\n", i);
664                         return;
665                 }
666         }
667         printf ("data:");
668         for (i = 0; i < 18; i++)
669                 printf (" %02x", test_data[i]);
670         printf ("\n");
671 }
672
673 static void
674 ao_sdcard_test_write(void)
675 {
676         int     i;
677         printf ("data:");
678         for (i = 0; i < 16; i++) {
679                 test_data[i]++;
680                 printf (" %02x", test_data[i]);
681         }
682         printf ("\n");
683         if (!ao_sdcard_write_block(1, test_data)) {
684                 printf ("write error\n");
685                 return;
686         }
687 }
688
689 static const struct ao_cmds ao_sdcard_cmds[] = {
690         { ao_sdcard_test_read,  "x\0Test read" },
691         { ao_sdcard_test_write, "y\0Test read" },
692         { 0, NULL },
693 };
694 #endif
695
696 void
697 ao_sdcard_init(void)
698 {
699         stm_pupdr_set(AO_SDCARD_SPI_PORT, AO_SDCARD_SPI_SCK_PIN, STM_PUPDR_PULL_UP);
700         stm_pupdr_set(AO_SDCARD_SPI_PORT, AO_SDCARD_SPI_MISO_PIN, STM_PUPDR_PULL_UP);
701         stm_pupdr_set(AO_SDCARD_SPI_PORT, AO_SDCARD_SPI_MOSI_PIN, STM_PUPDR_PULL_UP);
702         ao_spi_init_cs(AO_SDCARD_SPI_CS_PORT, (1 << AO_SDCARD_SPI_CS_PIN));
703 #if SDCARD_DEBUG
704         ao_cmd_register(&ao_sdcard_cmds[0]);
705 #endif
706 }