aa53ecc05de1537e2eb7bf648e97c6a0308c44c1
[bertos.git] / bertos / cpu / cortex-m3 / drv / sd_sam3.c
1 /**
2  * \file
3  * <!--
4  * This file is part of BeRTOS.
5  *
6  * Bertos is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  * As a special exception, you may use this file as part of a free software
21  * library without restriction.  Specifically, if other files instantiate
22  * templates or use macros or inline functions from this file, or you compile
23  * this file and link it with other files to produce an executable, this
24  * file does not by itself cause the resulting executable to be covered by
25  * the GNU General Public License.  This exception does not however
26  * invalidate any other reasons why the executable file might be covered by
27  * the GNU General Public License.
28  *
29  * Copyright 2007 Develer S.r.l. (http://www.develer.com/)
30  * -->
31  *
32  * \brief Function library for secure digital memory.
33  *
34  * \author Francesco Sacchi <batt@develer.com>
35  */
36
37
38 #include "hw/hw_sd.h"
39 #include "cfg/cfg_sd.h"
40
41 #include <drv/sd.h>
42 #include <drv/timer.h>
43 #include <drv/hsmci_sam3.h>
44
45 #include <io/kfile.h>
46 #include <io/kblock.h>
47
48 #include <fs/fat.h>
49
50 #define LOG_LEVEL  SD_LOG_LEVEL
51 #define LOG_FORMAT SD_LOG_FORMAT
52 #include <cfg/log.h>
53 #include <cpu/power.h>
54
55 #include <string.h> /* memset */
56
57
58 #define SD_STATUS_APP_CMD      BV(5)
59 #define SD_STATUS_READY        BV(8)
60 #define SD_STATUS_CURR_MASK    0x1E00
61 #define SD_STATUS_CURR_SHIFT   9
62
63 #define SD_READY_FOR_DATA         BV(8)
64 #define SD_CARD_IS_LOCKED         BV(25)
65
66 #define SD_SEND_CID_RCA     0
67 #define SD_SEND_ALL_CID   BV(0)
68
69
70 #define SD_ADDR_TO_RCA(addr)    (uint32_t)(((addr) << 16) & 0xFFFF0000)
71 #define SD_GET_STATE(status)    (uint8_t)(((status) & SD_STATUS_CURR_MASK) >> SD_STATUS_CURR_SHIFT)
72
73 static const uint32_t tran_exp[] =
74 {
75         10000,      100000,     1000000,    10000000,
76         0,      0,      0,      0
77 };
78
79 static const uint8_t tran_mant[] =
80 {
81         0,  10, 12, 13, 15, 20, 25, 30,
82         35, 40, 45, 50, 55, 60, 70, 80,
83 };
84
85
86 void sd_dumpCsd(SdCSD *csd);
87 void sd_dumpCid(SdCID *cid);
88 void sd_dumpSsr(SdSSR *ssr);
89
90 void sd_sendInit(void);
91 void sd_goIdle(void);
92 int sd_sendIfCond(Sd *sd);
93 int sd_sendAppOpCond(Sd *sd);
94
95 int sd_getCid(Sd *sd, SdCID *cid, uint32_t addr, uint8_t flag);
96 int sd_getCsd(Sd *sd, SdCSD *csd);
97 int sd_getSrc(Sd *sd);
98
99 int sd_appStatus(Sd *sd);
100 int sd_getRelativeAddr(Sd *sd);
101 int sd_getStatus(Sd *sd, SdSSR *ssr, uint32_t *buf, size_t words);
102
103 int sd_selectCard(Sd *sd);
104 int sd_deSelectCard(Sd *sd);
105 int sd_setBusWidth(Sd *sd, size_t len);
106 int sd_set_BlockLen(Sd *sd, size_t len);
107 void sd_setHightSpeed(Sd *sd);
108
109
110 INLINE int sd_setBus4bit(Sd *sd)
111 {
112         return sd_setBusWidth(sd, 4);
113 }
114
115 INLINE int sd_setBus1bit(Sd *sd)
116 {
117         return sd_setBusWidth(sd, 1);
118 }
119
120
121 LOG_INFOB(
122 static void dump(const char *label, uint32_t *r, size_t len)
123 {
124         ASSERT(r);
125         size_t i;
126         int j = 0;
127         kprintf("\n%s [\n", label);
128         for (i = 0; i < len; i++)
129         {
130                 if (j == 5)
131                 {
132                         kputs("\n");
133                         j = 0;
134                 }
135                 kprintf("%08lx ", r[i]);
136                 j++;
137         }
138         kprintf("\n] len=%d\n\n", i);
139 }
140 )
141
142 void sd_dumpCsd(SdCSD *csd)
143 {
144         ASSERT(csd);
145
146         LOG_INFO("VERSION: %d.0\n", csd->structure ? 2 : 1);
147         LOG_INFO("CARD COMMAND CLASS: %d\n", csd->ccc);
148         LOG_INFO("MAX DATA RATE: %ld\n", csd->max_data_rate);
149         LOG_INFO("WRITE BLK LEN BITS: %ld\n", csd->write_blk_bits);
150         LOG_INFO("READ BLK LEN BITS: %ld\n", csd->read_blk_bits);
151         LOG_INFO("ERASE SIZE: %ld\n", csd->erase_size);
152         LOG_INFO("BLK NUM: %ld\n", csd->block_num);
153         LOG_INFO("BLK LEN: %ld\n", csd->block_len);
154         LOG_INFO("CAPACITY %ld\n", csd->capacity);
155         LOG_INFO("FLAG Write: WP %d, W MISALIGN %d\n", csd->write_partial, csd->write_misalign);
156         LOG_INFO("FLAG Read: RP %d, R MISALIGN %d\n", csd->read_partial, csd->read_misalign);
157
158 }
159
160 void sd_dumpCid(SdCID *cid)
161 {
162         ASSERT(cid);
163
164         LOG_INFO("MANFID: %d\n", cid->manfid);
165         LOG_INFO("OEMID: %d\n", cid->oemid);
166         LOG_INFO("SERIAL: %ld\n", cid->serial);
167         LOG_INFO("PROD_NAME: %s\n", cid->prod_name);
168         LOG_INFO("REV: %d.%d\n", cid->m_rev, cid->l_rev);
169         LOG_INFO("OFF,Y,M: %lx, %ld %ld\n", cid->year_off, (BCD_TO_INT_32BIT(cid->year_off) / 12) + 2000,
170                                                                                                 (BCD_TO_INT_32BIT(cid->year_off) % 12));
171 }
172
173 void sd_dumpSsr(SdSSR *ssr)
174 {
175         ASSERT(ssr);
176
177         LOG_INFO("BUS_WIDTH: %d\n", ssr->bus_width);
178         LOG_INFO("TYPE: %d\n", ssr->card_type);
179         LOG_INFO("AU_TYPE: %d\n", ssr->au_size);
180         LOG_INFO("ERASE_SIZE: %d\n", ssr->erase_size);
181         LOG_INFO("SPEED_CLASS: %d\n", ssr->speed_class);
182 }
183
184
185 static int sd_decodeCsd(SdCSD *csd, uint32_t *resp, size_t len)
186 {
187         ASSERT(csd);
188         ASSERT(resp);
189         ASSERT(len >= 4);
190
191         csd->structure = UNSTUFF_BITS(resp, 126, 2);
192         csd->ccc = UNSTUFF_BITS(resp, 84, 12);
193
194         csd->max_data_rate  = tran_exp[UNSTUFF_BITS(resp, 96, 3)] * tran_mant[UNSTUFF_BITS(resp, 99, 4)];
195
196         /*
197          * CSD structure:
198          * - 0:
199          *              - Version 1.01-1.10
200          *              - Version 2.00/Standard Capacity
201          * - 1:
202          *              - Version 2.00/High Capacity
203          * - >1: not defined.
204          */
205
206         if (csd->structure == 0)
207         {
208                 // (C_size + 1) x 2^(C_SIZE_MUL+2)
209                 csd->block_num = (1 + UNSTUFF_BITS(resp, 62, 12)) << (UNSTUFF_BITS(resp, 47, 3) + 2);
210
211                 csd->read_blk_bits = UNSTUFF_BITS(resp, 80, 4);
212                 csd->write_blk_bits = UNSTUFF_BITS(resp, 22, 4);
213
214                 csd->block_len = 1 << csd->read_blk_bits;
215                 csd->capacity  = csd->block_num * csd->block_len;
216
217                 csd->read_partial = UNSTUFF_BITS(resp, 79, 1);
218                 csd->read_misalign = UNSTUFF_BITS(resp, 77, 1);
219
220                 csd->write_misalign = UNSTUFF_BITS(resp, 78, 1);
221                 csd->write_partial = UNSTUFF_BITS(resp, 21, 1);
222
223                 if (UNSTUFF_BITS(resp, 46, 1))
224                 {
225                         csd->erase_size = 1;
226                 }
227                 else if(csd->write_blk_bits >= 9)
228                 {
229                         csd->erase_size = UNSTUFF_BITS(resp, 39, 7) + 1;
230                         csd->erase_size <<= csd->write_blk_bits - 9;
231                 }
232
233                 return 0;
234         }
235         else if (csd->structure == 1)
236         {
237                 kprintf("csize %ld\n", UNSTUFF_BITS(resp, 48, 22));
238                 csd->capacity  = (1 + UNSTUFF_BITS(resp, 48, 22)) << 10;
239
240                 csd->write_blk_bits = 9;
241                 csd->write_partial = 0;
242                 csd->write_misalign = 0;
243
244                 csd->read_blk_bits = 9;
245                 csd->read_partial = 0;
246                 csd->read_misalign = 0;
247
248                 csd->erase_size = 1;
249                 // the block size if fixed to 512kb
250                 csd->block_len = (1 << csd->write_blk_bits) << 10;
251
252                 return 0;
253         }
254         else
255         {
256                 kprintf("Unrecognised CSD structure version %d\n", csd->structure);
257                 return -1;
258         }
259
260         return 0;
261 }
262
263 void sd_sendInit(void)
264 {
265         hsmci_init(NULL); //TODO: REMOVE IT!
266
267         if (hsmci_sendCmd(0, 0, HSMCI_CMDR_SPCMD_INIT | HSMCI_CMDR_RSPTYP_NORESP))
268                 LOG_ERR("INIT: %lx\n", HSMCI_SR);
269 }
270
271
272 void sd_goIdle(void)
273 {
274         hsmci_setSpeed(HSMCI_INIT_SPEED, false);
275         if (hsmci_sendCmd(0, 0, HSMCI_CMDR_RSPTYP_NORESP))
276                 LOG_ERR("GO_IDLE: %lx\n", HSMCI_SR);
277 }
278
279 int sd_sendIfCond(Sd *sd)
280 {
281         if (hsmci_sendCmd(8, CMD8_V_RANGE_27V_36V, HSMCI_CMDR_RSPTYP_48_BIT))
282         {
283                 LOG_ERR("IF_COND %lx\n", HSMCI_SR);
284                 return -1;
285         }
286         hsmci_readResp(&(sd->status), 1);
287         if (((sd->status) & 0xFFF) == CMD8_V_RANGE_27V_36V)
288         {
289                 LOG_INFO("IF_COND: %lx\n", (sd->status));
290                 return 0;
291         }
292         LOG_ERR("IF_COND: %lx\n", (sd->status));
293
294         return -1;
295 }
296
297 int sd_sendAppOpCond(Sd *sd)
298 {
299         if (hsmci_sendCmd(55, 0, HSMCI_CMDR_RSPTYP_48_BIT))
300         {
301                 LOG_ERR("APP_CMD %lx\n", HSMCI_SR);
302                 return -1;
303         }
304
305         hsmci_readResp(&(sd->status), 1);
306         if ((sd->status) & (SD_STATUS_APP_CMD | SD_STATUS_READY))
307         {
308                 if (hsmci_sendCmd(41, SD_HOST_VOLTAGE_RANGE | SD_OCR_CCS, HSMCI_CMDR_RSPTYP_48_BIT))// se cmd 8 va ok.
309                 {
310                         LOG_ERR("APP_OP_COND %lx\n", HSMCI_SR);
311                         return -1;
312                 }
313                 else
314                 {
315                         hsmci_readResp(&(sd->status), 1);
316                         if ((sd->status) & SD_OCR_BUSY)
317                         {
318                                 LOG_INFO("SD power up! Hight Capability [%d]\n", (bool)((sd->status) & SD_OCR_CCS));
319                                 return 0;
320                         }
321
322                         LOG_ERR("sd not ready.\n");
323                 }
324         }
325
326         return -1;
327 }
328
329
330 int sd_getCid(Sd *sd, SdCID *cid, uint32_t addr, uint8_t flag)
331 {
332         ASSERT(sd);
333         ASSERT(cid);
334         memset(cid, 0, sizeof(SdCID));
335
336         uint8_t idx = 9; // CMD9 get cid from gived sd address (RCA)
337         if (flag & SD_SEND_ALL_CID)
338                 idx = 2;
339
340
341         if (hsmci_sendCmd(idx, SD_ADDR_TO_RCA(addr), HSMCI_CMDR_RSPTYP_136_BIT))
342         {
343                 LOG_ERR("GET_CID %lx\n", HSMCI_SR);
344                 return -1;
345         }
346         else
347         {
348                 uint32_t resp[4];
349                 hsmci_readResp(resp, 4);
350                 LOG_INFOB(dump("CID", resp, 4););
351
352                 cid->manfid        = UNSTUFF_BITS(resp, 120, 8);
353                 cid->oemid         = UNSTUFF_BITS(resp, 104, 16);
354                 cid->prod_name[0]      = UNSTUFF_BITS(resp, 96, 8);
355                 cid->prod_name[1]      = UNSTUFF_BITS(resp, 88, 8);
356                 cid->prod_name[2]      = UNSTUFF_BITS(resp, 80, 8);
357                 cid->prod_name[3]      = UNSTUFF_BITS(resp, 72, 8);
358                 cid->prod_name[4]      = UNSTUFF_BITS(resp, 64, 8);
359                 cid->m_rev         = UNSTUFF_BITS(resp, 60, 4);
360                 cid->l_rev         = UNSTUFF_BITS(resp, 56, 4);
361                 cid->serial        = (uint32_t)UNSTUFF_BITS(resp, 24, 32);
362                 cid->year_off      = UNSTUFF_BITS(resp, 8, 12);
363         }
364
365         return 0;
366 }
367
368 int sd_getCsd(Sd *sd, SdCSD *csd)
369 {
370         ASSERT(sd);
371         ASSERT(csd);
372         memset(csd, 0, sizeof(SdCSD));
373
374         LOG_INFO("Send to RCA: %lx\n", SD_ADDR_TO_RCA(sd->addr));
375         if (hsmci_sendCmd(9, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_136_BIT))
376         {
377                 LOG_ERR("GET_CSD %lx\n", HSMCI_SR);
378                 return -1;
379         }
380         else
381         {
382                 uint32_t resp[4];
383                 hsmci_readResp(resp, 4);
384                 LOG_INFOB(dump("CSD", resp, 4););
385                 sd_decodeCsd(csd, resp, 4);
386         }
387
388         return 0;
389 }
390
391 int sd_getRelativeAddr(Sd *sd)
392 {
393         ASSERT(sd);
394         if (hsmci_sendCmd(3, 0, HSMCI_CMDR_RSPTYP_48_BIT))
395         {
396                 LOG_ERR("RCA: %lx\n", HSMCI_SR);
397                 return -1;
398         }
399
400         hsmci_readResp(&sd->addr, 1);
401         sd->addr = sd->addr >> 16;
402
403         LOG_INFOB(dump("RCA", &sd->addr, 1););
404
405         return 0;
406 }
407
408 int sd_appStatus(Sd *sd)
409 {
410         ASSERT(sd);
411         LOG_INFO("Send to RCA: %lx\n", SD_ADDR_TO_RCA(sd->addr));
412         if (hsmci_sendCmd(13, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
413         {
414                 LOG_ERR("STATUS: %lx\n", HSMCI_SR);
415                 return -1;
416         }
417
418         hsmci_readResp(&(sd->status), 1);
419         LOG_INFOB(dump("STATUS", &(sd->status), 1););
420
421         LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
422
423         if (sd->status & SD_STATUS_READY)
424                 return 0;
425
426         return -1;
427 }
428
429
430 INLINE int sd_cardSelection(Sd *sd, uint32_t rca)
431 {
432         ASSERT(sd);
433         LOG_INFO("Select RCA: %lx\n", rca);
434         if (hsmci_sendCmd(7, rca, HSMCI_CMDR_RSPTYP_R1B))
435         {
436                 LOG_ERR("SELECT_SD: %lx\n", HSMCI_SR);
437                 return -1;
438         }
439
440         HSMCI_CHECK_BUSY();
441         hsmci_readResp(&(sd->status), 1);
442         LOG_INFOB(dump("SELECT_SD", &(sd->status), 1););
443
444         LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
445
446         if (sd->status & SD_STATUS_READY)
447                 return 0;
448
449         return -1;
450 }
451
452 int sd_selectCard(Sd *sd)
453 {
454         ASSERT(sd);
455         uint32_t rca = SD_ADDR_TO_RCA(sd->addr);
456         LOG_INFO("Select RCA: %lx\n", rca);
457         if (hsmci_sendCmd(7, rca, HSMCI_CMDR_RSPTYP_R1B))
458         {
459                 LOG_ERR("SELECT_SD: %lx\n", HSMCI_SR);
460                 return -1;
461         }
462
463         HSMCI_CHECK_BUSY();
464         hsmci_readResp(&(sd->status), 1);
465
466         LOG_INFOB(dump("SELECT_SD", &(sd->status), 1););
467         LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
468
469         if (sd->status & SD_STATUS_READY)
470                 return 0;
471
472         return -1;
473 }
474
475 int sd_deSelectCard(Sd *sd)
476 {
477         ASSERT(sd);
478
479         uint32_t rca = 0;
480         if (!sd->addr)
481                 rca = SD_ADDR_TO_RCA(sd->addr + 1);
482
483         LOG_INFO("Select RCA: %lx\n", rca);
484
485         if (hsmci_sendCmd(7, rca, HSMCI_CMDR_RSPTYP_NORESP))
486         {
487                 LOG_ERR("DESELECT_SD: %lx\n", HSMCI_SR);
488                 return -1;
489         }
490
491         return 0;
492 }
493
494 int sd_setBusWidth(Sd *sd, size_t len)
495 {
496         ASSERT(sd);
497
498         if (hsmci_sendCmd(55, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
499         {
500                 LOG_ERR("APP_CMD %lx\n", HSMCI_SR);
501                 return -1;
502         }
503
504         hsmci_readResp(&(sd->status), 1);
505         if ((sd->status) & (SD_STATUS_APP_CMD | SD_STATUS_READY))
506         {
507                 hsmci_setBusWidth(len);
508
509                 uint8_t arg = 0;
510                 if (len == 4)
511                         arg = 2;
512
513                 if (hsmci_sendCmd(6, arg, HSMCI_CMDR_RSPTYP_48_BIT))
514                 {
515                         LOG_ERR("SET_BUS_WIDTH CMD: %lx\n", HSMCI_SR);
516                         return -1;
517                 }
518
519                 hsmci_readResp(&(sd->status), 1);
520
521                 LOG_INFOB(dump("SET_BUS_WIDTH", &(sd->status), 1););
522                 LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
523
524                 if (sd->status & SD_STATUS_READY)
525                         return 0;
526         }
527
528         LOG_ERR("SET_BUS_WIDTH REP %lx\n", (sd->status));
529         return -1;
530 }
531
532
533 int sd_set_BlockLen(Sd *sd, size_t len)
534 {
535         ASSERT(sd);
536
537         if (hsmci_sendCmd(16, len, HSMCI_CMDR_RSPTYP_48_BIT))
538         {
539                 LOG_ERR("SET_BLK_LEN: %lx\n", HSMCI_SR);
540                 return -1;
541         }
542
543         hsmci_readResp(&(sd->status), 1);
544
545         LOG_INFOB(dump("SET_BLK_LEN", &(sd->status), 1););
546         LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
547
548         sd->b.blk_size = len;
549
550         if (sd->status & SD_STATUS_READY)
551                 return 0;
552
553         return -1;
554 }
555
556 int sd_getStatus(Sd *sd, SdSSR *ssr, uint32_t *buf, size_t words)
557 {
558         ASSERT(sd);
559         ASSERT(ssr);
560
561         // Status reply with 512bit data, so the block size in byte is 64
562         hsmci_prgRxDMA(buf, words, 64);
563
564         if (hsmci_sendCmd(55, SD_ADDR_TO_RCA(sd->addr), HSMCI_CMDR_RSPTYP_48_BIT))
565         {
566                 LOG_ERR("APP_CMD %lx\n", HSMCI_SR);
567                 return -1;
568         }
569
570         uint32_t status = HSMCI_RSPR;
571         if (status & (SD_STATUS_APP_CMD | SD_STATUS_READY))
572         {
573                 if (hsmci_sendCmd(13, 0, HSMCI_CMDR_RSPTYP_48_BIT |
574                                 BV(HSMCI_CMDR_TRDIR) | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE))
575                 {
576                         LOG_ERR("STATUS CMD: %lx\n", HSMCI_SR);
577                         return -1;
578                 }
579
580                 hsmci_readResp(&(sd->status), 1);
581                 LOG_INFOB(dump("STATUS", &(sd->status), 1););
582                 LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
583
584                 if (sd->status & SD_STATUS_READY)
585                 {
586                         hsmci_waitTransfer();
587
588                         LOG_INFOB(dump("STATUS", buf, words););
589                         memset(ssr, 0, sizeof(SdSSR));
590                         ssr->bus_width  = UNSTUFF_BITS(buf, 510, 2);
591                         ssr->card_type  = UNSTUFF_BITS(buf, 480, 16);
592                         ssr->au_size  = UNSTUFF_BITS(buf, 432, 8);
593                         ssr->speed_class  = UNSTUFF_BITS(buf, 440, 8);
594                         ssr->erase_size = UNSTUFF_BITS(buf, 408, 24);
595
596                         return 0;
597                 }
598         }
599
600         return -1;
601 }
602
603
604 void sd_setHightSpeed(Sd *sd)
605 {
606         (void)sd;
607         hsmci_setSpeed(2100000, true);
608 }
609
610
611 static size_t sd_SdReadDirect(struct KBlock *b, block_idx_t idx, void *buf, size_t offset, size_t size)
612 {
613         ASSERT(buf);
614         Sd *sd = SD_CAST(b);
615         LOG_INFO("reading from block %ld, offset %d, size %d\n", idx, offset, size);
616
617         if (sd_selectCard(sd) < 0)
618                 return -1;
619
620         hsmci_prgRxDMA(buf, size / 4, sd->b.blk_size);
621
622         if (hsmci_sendCmd(17, idx * sd->b.blk_size + offset, HSMCI_CMDR_RSPTYP_48_BIT |
623                         BV(HSMCI_CMDR_TRDIR) | HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE))
624         {
625                 LOG_ERR("SIGLE_BLK_READ: %lx\n", HSMCI_SR);
626                 sd_deSelectCard(sd);
627                 return -1;
628         }
629
630         hsmci_readResp(&(sd->status), 1);
631
632         LOG_INFOB(dump("SIGLE_BLK_READ", &(sd->status), 1););
633         LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
634
635         if (sd->status & SD_STATUS_READY)
636         {
637                 hsmci_waitTransfer();
638                 sd_deSelectCard(sd);
639                 return size;
640         }
641
642         sd_deSelectCard(sd);
643         return -1;
644 }
645
646 static size_t sd_SdWriteDirect(KBlock *b, block_idx_t idx, const void *buf, size_t offset, size_t size)
647 {
648         ASSERT(buf);
649         Sd *sd = SD_CAST(b);
650         const uint32_t *_buf = (const uint32_t *)buf;
651         LOG_INFO("reading from block %ld, offset %d, size %d\n", idx, offset, size);
652
653         if (sd_selectCard(sd) < 0)
654                 return 0;
655
656         hsmci_prgTxDMA(_buf, size / 4, sd->b.blk_size);
657
658         if (hsmci_sendCmd(24, idx * sd->b.blk_size + offset, HSMCI_CMDR_RSPTYP_48_BIT |
659                                                 HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRTYP_SINGLE))
660         {
661                 LOG_ERR("SIGLE_BLK_WRITE: %lx\n", HSMCI_SR);
662                 sd_deSelectCard(sd);
663                 return -1;
664         }
665
666         hsmci_readResp(&(sd->status), 1);
667
668         LOG_INFOB(dump("SIGLE_BLK_WR", &(sd->status), 1););
669         LOG_INFO("State[%d]\n", SD_GET_STATE(sd->status));
670
671         if (sd->status & SD_STATUS_READY)
672         {
673                 hsmci_waitTransfer();
674                 sd_deSelectCard(sd);
675                 return size;
676         }
677
678         sd_deSelectCard(sd);
679         return -1;
680 }
681
682
683 static int sd_SdError(KBlock *b)
684 {
685         Sd *sd = SD_CAST(b);
686         return 0;//sd->status;
687 }
688
689 static void sd_SdClearerr(KBlock *b)
690 {
691         Sd *sd = SD_CAST(b);
692         sd->status = 0;
693 }
694
695 static bool sd_blockInit(Sd *sd, KFile *ch)
696 {
697         ASSERT(sd);
698         memset(sd, 0, sizeof(*sd));
699         DB(sd->b.priv.type = KBT_SD);
700
701         /* Wait a few moments for supply voltage to stabilize */
702         timer_delay(SD_START_DELAY);
703
704         sd_sendInit();
705         sd_goIdle();
706
707         sd_sendIfCond(sd);
708
709         ticks_t start = timer_clock();
710         bool sd_power_on = false;
711         do
712         {
713                 if (!sd_sendAppOpCond(sd))
714                 {
715                         sd_power_on = true;
716                         break;
717                 }
718                 cpu_relax();
719         }
720         while (timer_clock() - start < SD_INIT_TIMEOUT);
721
722
723         if (sd_power_on)
724         {
725                 SdCID cid;
726                 if(sd_getCid(sd, &cid, 0, SD_SEND_ALL_CID) < 0)
727                         return false;
728                 else
729                 {
730                         sd_dumpCid(&cid);
731                 }
732
733                 if (sd_getRelativeAddr(sd) < 0)
734                         return false;
735                 else
736                 {
737                         LOG_INFO("RCA: %0lx\n", sd->addr);
738                 }
739
740                 SdCSD csd;
741                 if (sd_getCsd(sd, &csd) < 0)
742                         return false;
743                 else
744                 {
745                         sd->b.blk_cnt = csd.block_num * (csd.block_len / SD_DEFAULT_BLOCKLEN);
746                         LOG_INFO("blk_size %d, blk_cnt %ld\n", sd->b.blk_size, sd->b.blk_cnt);
747                         sd_dumpCsd(&csd);
748                 }
749
750                 if (sd_appStatus(sd) < 0)
751                 {
752                         LOG_INFO("STATUS: %ld\n", sd->status);
753                         return false;
754                 }
755
756                 if (sd->status & SD_CARD_IS_LOCKED)
757                 {
758                         LOG_INFO("SD is locked!\n");
759                         return false;
760                 }
761
762                 if (sd->status & SD_READY_FOR_DATA)
763                 {
764                         sd_selectCard(sd);
765                         sd_set_BlockLen(sd, SD_DEFAULT_BLOCKLEN);
766                         sd_setBus4bit(sd);
767                         sd_setHightSpeed(sd);
768                         sd_deSelectCard(sd);
769
770                         #if CONFIG_SD_AUTOASSIGN_FAT
771                                 disk_assignDrive(&sd->b, 0);
772                         #endif
773
774                         return true;
775                 }
776         }
777
778         return false;
779 }
780
781 static const KBlockVTable sd_unbuffered_vt =
782 {
783         .readDirect = sd_SdReadDirect,
784         .writeDirect = sd_SdWriteDirect,
785
786         .error = sd_SdError,
787         .clearerr = sd_SdClearerr,
788 };
789
790 static const KBlockVTable sd_buffered_vt =
791 {
792         .readDirect = sd_SdReadDirect,
793         .writeDirect = sd_SdWriteDirect,
794
795         .readBuf = kblock_swReadBuf,
796         .writeBuf = kblock_swWriteBuf,
797         .load = kblock_swLoad,
798         .store = kblock_swStore,
799
800         .error = sd_SdError,
801         .clearerr = sd_SdClearerr,
802 };
803
804 bool sd_hw_initUnbuf(Sd *sd, KFile *ch)
805 {
806         if (sd_blockInit(sd, ch))
807         {
808                 sd->b.priv.vt = &sd_unbuffered_vt;
809                 return true;
810         }
811         else
812                 return false;
813 }
814
815 static uint8_t sd_buf[SD_DEFAULT_BLOCKLEN];
816
817 bool sd_hw_initBuf(Sd *sd, KFile *ch)
818 {
819         if (sd_blockInit(sd, ch))
820         {
821                 sd->b.priv.buf = sd_buf;
822                 sd->b.priv.flags |= KB_BUFFERED | KB_PARTIAL_WRITE;
823                 sd->b.priv.vt = &sd_buffered_vt;
824                 sd->b.priv.vt->load(&sd->b, 0);
825                 return true;
826         }
827         else
828                 return false;
829 }
830
831
832