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