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