PageRenderTime 53ms CodeModel.GetById 16ms app.highlight 28ms RepoModel.GetById 1ms app.codeStats 1ms

/firmware/src/Motherboard/lib_sd/sd_raw.c

http://github.com/makerbot/G3Firmware
C | 994 lines | 613 code | 113 blank | 268 comment | 105 complexity | 9e49e700d36a684db7e72d25c1e0f3c3 MD5 | raw file
  1
  2/*
  3 * Copyright (c) 2006-2010 by Roland Riegel <feedback@roland-riegel.de>
  4 *
  5 * This file is free software; you can redistribute it and/or modify
  6 * it under the terms of either the GNU General Public License version 2
  7 * or the GNU Lesser General Public License version 2.1, both as
  8 * published by the Free Software Foundation.
  9 */
 10
 11#include <string.h>
 12#include <avr/io.h>
 13#include "sd_raw.h"
 14
 15/**
 16 * \addtogroup sd_raw MMC/SD/SDHC card raw access
 17 *
 18 * This module implements read and write access to MMC, SD
 19 * and SDHC cards. It serves as a low-level driver for the
 20 * higher level modules such as partition and file system
 21 * access.
 22 *
 23 * @{
 24 */
 25/**
 26 * \file
 27 * MMC/SD/SDHC raw access implementation (license: GPLv2 or LGPLv2.1)
 28 *
 29 * \author Roland Riegel
 30 */
 31
 32/**
 33 * \addtogroup sd_raw_config MMC/SD configuration
 34 * Preprocessor defines to configure the MMC/SD support.
 35 */
 36
 37/**
 38 * @}
 39 */
 40
 41/* commands available in SPI mode */
 42
 43/* CMD0: response R1 */
 44#define CMD_GO_IDLE_STATE 0x00
 45/* CMD1: response R1 */
 46#define CMD_SEND_OP_COND 0x01
 47/* CMD8: response R7 */
 48#define CMD_SEND_IF_COND 0x08
 49/* CMD9: response R1 */
 50#define CMD_SEND_CSD 0x09
 51/* CMD10: response R1 */
 52#define CMD_SEND_CID 0x0a
 53/* CMD12: response R1 */
 54#define CMD_STOP_TRANSMISSION 0x0c
 55/* CMD13: response R2 */
 56#define CMD_SEND_STATUS 0x0d
 57/* CMD16: arg0[31:0]: block length, response R1 */
 58#define CMD_SET_BLOCKLEN 0x10
 59/* CMD17: arg0[31:0]: data address, response R1 */
 60#define CMD_READ_SINGLE_BLOCK 0x11
 61/* CMD18: arg0[31:0]: data address, response R1 */
 62#define CMD_READ_MULTIPLE_BLOCK 0x12
 63/* CMD24: arg0[31:0]: data address, response R1 */
 64#define CMD_WRITE_SINGLE_BLOCK 0x18
 65/* CMD25: arg0[31:0]: data address, response R1 */
 66#define CMD_WRITE_MULTIPLE_BLOCK 0x19
 67/* CMD27: response R1 */
 68#define CMD_PROGRAM_CSD 0x1b
 69/* CMD28: arg0[31:0]: data address, response R1b */
 70#define CMD_SET_WRITE_PROT 0x1c
 71/* CMD29: arg0[31:0]: data address, response R1b */
 72#define CMD_CLR_WRITE_PROT 0x1d
 73/* CMD30: arg0[31:0]: write protect data address, response R1 */
 74#define CMD_SEND_WRITE_PROT 0x1e
 75/* CMD32: arg0[31:0]: data address, response R1 */
 76#define CMD_TAG_SECTOR_START 0x20
 77/* CMD33: arg0[31:0]: data address, response R1 */
 78#define CMD_TAG_SECTOR_END 0x21
 79/* CMD34: arg0[31:0]: data address, response R1 */
 80#define CMD_UNTAG_SECTOR 0x22
 81/* CMD35: arg0[31:0]: data address, response R1 */
 82#define CMD_TAG_ERASE_GROUP_START 0x23
 83/* CMD36: arg0[31:0]: data address, response R1 */
 84#define CMD_TAG_ERASE_GROUP_END 0x24
 85/* CMD37: arg0[31:0]: data address, response R1 */
 86#define CMD_UNTAG_ERASE_GROUP 0x25
 87/* CMD38: arg0[31:0]: stuff bits, response R1b */
 88#define CMD_ERASE 0x26
 89/* ACMD41: arg0[31:0]: OCR contents, response R1 */
 90#define CMD_SD_SEND_OP_COND 0x29
 91/* CMD42: arg0[31:0]: stuff bits, response R1b */
 92#define CMD_LOCK_UNLOCK 0x2a
 93/* CMD55: arg0[31:0]: stuff bits, response R1 */
 94#define CMD_APP 0x37
 95/* CMD58: arg0[31:0]: stuff bits, response R3 */
 96#define CMD_READ_OCR 0x3a
 97/* CMD59: arg0[31:1]: stuff bits, arg0[0:0]: crc option, response R1 */
 98#define CMD_CRC_ON_OFF 0x3b
 99
100/* command responses */
101/* R1: size 1 byte */
102#define R1_IDLE_STATE 0
103#define R1_ERASE_RESET 1
104#define R1_ILL_COMMAND 2
105#define R1_COM_CRC_ERR 3
106#define R1_ERASE_SEQ_ERR 4
107#define R1_ADDR_ERR 5
108#define R1_PARAM_ERR 6
109/* R1b: equals R1, additional busy bytes */
110/* R2: size 2 bytes */
111#define R2_CARD_LOCKED 0
112#define R2_WP_ERASE_SKIP 1
113#define R2_ERR 2
114#define R2_CARD_ERR 3
115#define R2_CARD_ECC_FAIL 4
116#define R2_WP_VIOLATION 5
117#define R2_INVAL_ERASE 6
118#define R2_OUT_OF_RANGE 7
119#define R2_CSD_OVERWRITE 7
120#define R2_IDLE_STATE (R1_IDLE_STATE + 8)
121#define R2_ERASE_RESET (R1_ERASE_RESET + 8)
122#define R2_ILL_COMMAND (R1_ILL_COMMAND + 8)
123#define R2_COM_CRC_ERR (R1_COM_CRC_ERR + 8)
124#define R2_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 8)
125#define R2_ADDR_ERR (R1_ADDR_ERR + 8)
126#define R2_PARAM_ERR (R1_PARAM_ERR + 8)
127/* R3: size 5 bytes */
128#define R3_OCR_MASK (0xffffffffUL)
129#define R3_IDLE_STATE (R1_IDLE_STATE + 32)
130#define R3_ERASE_RESET (R1_ERASE_RESET + 32)
131#define R3_ILL_COMMAND (R1_ILL_COMMAND + 32)
132#define R3_COM_CRC_ERR (R1_COM_CRC_ERR + 32)
133#define R3_ERASE_SEQ_ERR (R1_ERASE_SEQ_ERR + 32)
134#define R3_ADDR_ERR (R1_ADDR_ERR + 32)
135#define R3_PARAM_ERR (R1_PARAM_ERR + 32)
136/* Data Response: size 1 byte */
137#define DR_STATUS_MASK 0x0e
138#define DR_STATUS_ACCEPTED 0x05
139#define DR_STATUS_CRC_ERR 0x0a
140#define DR_STATUS_WRITE_ERR 0x0c
141
142/* status bits for card types */
143#define SD_RAW_SPEC_1 0
144#define SD_RAW_SPEC_2 1
145#define SD_RAW_SPEC_SDHC 2
146
147#if !SD_RAW_SAVE_RAM
148/* static data buffer for acceleration */
149static uint8_t raw_block[512];
150/* offset where the data within raw_block lies on the card */
151static offset_t raw_block_address;
152#if SD_RAW_WRITE_BUFFERING
153/* flag to remember if raw_block was written to the card */
154static uint8_t raw_block_written;
155#endif
156#endif
157
158/* card type state */
159static uint8_t sd_raw_card_type;
160
161/* private helper functions */
162static void sd_raw_send_byte(uint8_t b);
163static uint8_t sd_raw_rec_byte();
164static uint8_t sd_raw_send_command(uint8_t command, uint32_t arg);
165
166/**
167 * \ingroup sd_raw
168 * Initializes memory card communication.
169 *
170 * \returns 0 on failure, 1 on success.
171 */
172uint8_t sd_raw_init()
173{
174    /* enable inputs for reading card status */
175    configure_pin_available();
176    configure_pin_locked();
177
178    /* enable outputs for MOSI, SCK, SS, input for MISO */
179    configure_pin_mosi();
180    configure_pin_sck();
181    configure_pin_ss();
182    configure_pin_miso();
183
184    unselect_card();
185
186    /* initialize SPI with lowest frequency; max. 400kHz during identification mode of card */
187    SPCR = (0 << SPIE) | /* SPI Interrupt Enable */
188           (1 << SPE)  | /* SPI Enable */
189           (0 << DORD) | /* Data Order: MSB first */
190           (1 << MSTR) | /* Master mode */
191           (0 << CPOL) | /* Clock Polarity: SCK low when idle */
192           (0 << CPHA) | /* Clock Phase: sample on rising SCK edge */
193           (1 << SPR1) | /* Clock Frequency: f_OSC / 128 */
194           (1 << SPR0);
195    SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */
196
197    /* initialization procedure */
198    sd_raw_card_type = 0;
199    
200    if(!sd_raw_available())
201        return 0;
202
203    /* card needs 74 cycles minimum to start up */
204    for(uint8_t i = 0; i < 10; ++i)
205    {
206        /* wait 8 clock cycles */
207        sd_raw_rec_byte();
208    }
209
210    /* address card */
211    select_card();
212
213    /* reset card */
214    uint8_t response;
215    for(uint16_t i = 0; ; ++i)
216    {
217        response = sd_raw_send_command(CMD_GO_IDLE_STATE, 0);
218        if(response == (1 << R1_IDLE_STATE))
219            break;
220
221        if(i == 0x1ff)
222        {
223            unselect_card();
224            return 0;
225        }
226    }
227
228#if SD_RAW_SDHC
229    /* check for version of SD card specification */
230    response = sd_raw_send_command(CMD_SEND_IF_COND, 0x100 /* 2.7V - 3.6V */ | 0xaa /* test pattern */);
231    if((response & (1 << R1_ILL_COMMAND)) == 0)
232    {
233        sd_raw_rec_byte();
234        sd_raw_rec_byte();
235        if((sd_raw_rec_byte() & 0x01) == 0)
236            return 0; /* card operation voltage range doesn't match */
237        if(sd_raw_rec_byte() != 0xaa)
238            return 0; /* wrong test pattern */
239
240        /* card conforms to SD 2 card specification */
241        sd_raw_card_type |= (1 << SD_RAW_SPEC_2);
242    }
243    else
244#endif
245    {
246        /* determine SD/MMC card type */
247        sd_raw_send_command(CMD_APP, 0);
248        response = sd_raw_send_command(CMD_SD_SEND_OP_COND, 0);
249        if((response & (1 << R1_ILL_COMMAND)) == 0)
250        {
251            /* card conforms to SD 1 card specification */
252            sd_raw_card_type |= (1 << SD_RAW_SPEC_1);
253        }
254        else
255        {
256            /* MMC card */
257        }
258    }
259
260    /* wait for card to get ready */
261    for(uint16_t i = 0; ; ++i)
262    {
263        if(sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << SD_RAW_SPEC_2)))
264        {
265            uint32_t arg = 0;
266#if SD_RAW_SDHC
267            if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
268                arg = 0x40000000;
269#endif
270            sd_raw_send_command(CMD_APP, 0);
271            response = sd_raw_send_command(CMD_SD_SEND_OP_COND, arg);
272        }
273        else
274        {
275            response = sd_raw_send_command(CMD_SEND_OP_COND, 0);
276        }
277
278        if((response & (1 << R1_IDLE_STATE)) == 0)
279            break;
280
281        if(i == 0x7fff)
282        {
283            unselect_card();
284            return 0;
285        }
286    }
287
288#if SD_RAW_SDHC
289    if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
290    {
291        if(sd_raw_send_command(CMD_READ_OCR, 0))
292        {
293            unselect_card();
294            return 0;
295        }
296
297        if(sd_raw_rec_byte() & 0x40)
298            sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC);
299
300        sd_raw_rec_byte();
301        sd_raw_rec_byte();
302        sd_raw_rec_byte();
303    }
304#endif
305
306    /* set block size to 512 bytes */
307    if(sd_raw_send_command(CMD_SET_BLOCKLEN, 512))
308    {
309        unselect_card();
310        return 0;
311    }
312
313    /* deaddress card */
314    unselect_card();
315
316    /* switch to highest SPI frequency possible */
317    SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 */
318    SPSR |= (1 << SPI2X); /* Doubled Clock Frequency: f_OSC / 2 */
319
320#if !SD_RAW_SAVE_RAM
321    /* the first block is likely to be accessed first, so precache it here */
322    raw_block_address = (offset_t) -1;
323#if SD_RAW_WRITE_BUFFERING
324    raw_block_written = 1;
325#endif
326    if(!sd_raw_read(0, raw_block, sizeof(raw_block)))
327        return 0;
328#endif
329
330    return 1;
331}
332
333/**
334 * \ingroup sd_raw
335 * Checks wether a memory card is located in the slot.
336 *
337 * \returns 1 if the card is available, 0 if it is not.
338 */
339uint8_t sd_raw_available()
340{
341    return get_pin_available() == 0x00;
342}
343
344/**
345 * \ingroup sd_raw
346 * Checks wether the memory card is locked for write access.
347 *
348 * \returns 1 if the card is locked, 0 if it is not.
349 */
350uint8_t sd_raw_locked()
351{
352    return get_pin_locked() == 0x00;
353}
354
355/**
356 * \ingroup sd_raw
357 * Sends a raw byte to the memory card.
358 *
359 * \param[in] b The byte to sent.
360 * \see sd_raw_rec_byte
361 */
362void sd_raw_send_byte(uint8_t b)
363{
364    SPDR = b;
365    /* wait for byte to be shifted out */
366    while(!(SPSR & (1 << SPIF)));
367    SPSR &= ~(1 << SPIF);
368}
369
370/**
371 * \ingroup sd_raw
372 * Receives a raw byte from the memory card.
373 *
374 * \returns The byte which should be read.
375 * \see sd_raw_send_byte
376 */
377uint8_t sd_raw_rec_byte()
378{
379    /* send dummy data for receiving some */
380    SPDR = 0xff;
381    while(!(SPSR & (1 << SPIF)));
382    SPSR &= ~(1 << SPIF);
383
384    return SPDR;
385}
386
387/**
388 * \ingroup sd_raw
389 * Send a command to the memory card which responses with a R1 response (and possibly others).
390 *
391 * \param[in] command The command to send.
392 * \param[in] arg The argument for command.
393 * \returns The command answer.
394 */
395uint8_t sd_raw_send_command(uint8_t command, uint32_t arg)
396{
397    uint8_t response;
398
399    /* wait some clock cycles */
400    sd_raw_rec_byte();
401
402    /* send command via SPI */
403    sd_raw_send_byte(0x40 | command);
404    sd_raw_send_byte((arg >> 24) & 0xff);
405    sd_raw_send_byte((arg >> 16) & 0xff);
406    sd_raw_send_byte((arg >> 8) & 0xff);
407    sd_raw_send_byte((arg >> 0) & 0xff);
408    switch(command)
409    {
410        case CMD_GO_IDLE_STATE:
411           sd_raw_send_byte(0x95);
412           break;
413        case CMD_SEND_IF_COND:
414           sd_raw_send_byte(0x87);
415           break;
416        default:
417           sd_raw_send_byte(0xff);
418           break;
419    }
420    
421    /* receive response */
422    for(uint8_t i = 0; i < 10; ++i)
423    {
424        response = sd_raw_rec_byte();
425        if(response != 0xff)
426            break;
427    }
428
429    return response;
430}
431
432/**
433 * \ingroup sd_raw
434 * Reads raw data from the card.
435 *
436 * \param[in] offset The offset from which to read.
437 * \param[out] buffer The buffer into which to write the data.
438 * \param[in] length The number of bytes to read.
439 * \returns 0 on failure, 1 on success.
440 * \see sd_raw_read_interval, sd_raw_write, sd_raw_write_interval
441 */
442uint8_t sd_raw_read(offset_t offset, uint8_t* buffer, uintptr_t length)
443{
444    offset_t block_address;
445    uint16_t block_offset;
446    uint16_t read_length;
447    while(length > 0)
448    {
449        /* determine byte count to read at once */
450        block_offset = offset & 0x01ff;
451        block_address = offset - block_offset;
452        read_length = 512 - block_offset; /* read up to block border */
453        if(read_length > length)
454            read_length = length;
455        
456#if !SD_RAW_SAVE_RAM
457        /* check if the requested data is cached */
458        if(block_address != raw_block_address)
459#endif
460        {
461#if SD_RAW_WRITE_BUFFERING
462            if(!sd_raw_sync())
463                return 0;
464#endif
465
466            /* address card */
467            select_card();
468
469            /* send single block request */
470#if SD_RAW_SDHC
471            if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
472#else
473            if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, block_address))
474#endif
475            {
476                unselect_card();
477                return 0;
478            }
479
480            /* wait for data block (start byte 0xfe) */
481            while(sd_raw_rec_byte() != 0xfe);
482
483#if SD_RAW_SAVE_RAM
484            /* read byte block */
485            uint16_t read_to = block_offset + read_length;
486            for(uint16_t i = 0; i < 512; ++i)
487            {
488                uint8_t b = sd_raw_rec_byte();
489                if(i >= block_offset && i < read_to)
490                    *buffer++ = b;
491            }
492#else
493            /* read byte block */
494            uint8_t* cache = raw_block;
495            for(uint16_t i = 0; i < 512; ++i)
496                *cache++ = sd_raw_rec_byte();
497            raw_block_address = block_address;
498
499            memcpy(buffer, raw_block + block_offset, read_length);
500            buffer += read_length;
501#endif
502            
503            /* read crc16 */
504            sd_raw_rec_byte();
505            sd_raw_rec_byte();
506            
507            /* deaddress card */
508            unselect_card();
509
510            /* let card some time to finish */
511            sd_raw_rec_byte();
512        }
513#if !SD_RAW_SAVE_RAM
514        else
515        {
516            /* use cached data */
517            memcpy(buffer, raw_block + block_offset, read_length);
518            buffer += read_length;
519        }
520#endif
521
522        length -= read_length;
523        offset += read_length;
524    }
525
526    return 1;
527}
528
529/**
530 * \ingroup sd_raw
531 * Continuously reads units of \c interval bytes and calls a callback function.
532 *
533 * This function starts reading at the specified offset. Every \c interval bytes,
534 * it calls the callback function with the associated data buffer.
535 *
536 * By returning zero, the callback may stop reading.
537 *
538 * \note Within the callback function, you can not start another read or
539 *       write operation.
540 * \note This function only works if the following conditions are met:
541 *       - (offset - (offset % 512)) % interval == 0
542 *       - length % interval == 0
543 *
544 * \param[in] offset Offset from which to start reading.
545 * \param[in] buffer Pointer to a buffer which is at least interval bytes in size.
546 * \param[in] interval Number of bytes to read before calling the callback function.
547 * \param[in] length Number of bytes to read altogether.
548 * \param[in] callback The function to call every interval bytes.
549 * \param[in] p An opaque pointer directly passed to the callback function.
550 * \returns 0 on failure, 1 on success
551 * \see sd_raw_write_interval, sd_raw_read, sd_raw_write
552 */
553uint8_t sd_raw_read_interval(offset_t offset, uint8_t* buffer, uintptr_t interval, uintptr_t length, sd_raw_read_interval_handler_t callback, void* p)
554{
555    if(!buffer || interval == 0 || length < interval || !callback)
556        return 0;
557
558#if !SD_RAW_SAVE_RAM
559    while(length >= interval)
560    {
561        /* as reading is now buffered, we directly
562         * hand over the request to sd_raw_read()
563         */
564        if(!sd_raw_read(offset, buffer, interval))
565            return 0;
566        if(!callback(buffer, offset, p))
567            break;
568        offset += interval;
569        length -= interval;
570    }
571
572    return 1;
573#else
574    /* address card */
575    select_card();
576
577    uint16_t block_offset;
578    uint16_t read_length;
579    uint8_t* buffer_cur;
580    uint8_t finished = 0;
581    do
582    {
583        /* determine byte count to read at once */
584        block_offset = offset & 0x01ff;
585        read_length = 512 - block_offset;
586        
587        /* send single block request */
588#if SD_RAW_SDHC
589        if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? offset / 512 : offset - block_offset)))
590#else
591        if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, offset - block_offset))
592#endif
593        {
594            unselect_card();
595            return 0;
596        }
597
598        /* wait for data block (start byte 0xfe) */
599        while(sd_raw_rec_byte() != 0xfe);
600
601        /* read up to the data of interest */
602        for(uint16_t i = 0; i < block_offset; ++i)
603            sd_raw_rec_byte();
604
605        /* read interval bytes of data and execute the callback */
606        do
607        {
608            if(read_length < interval || length < interval)
609                break;
610
611            buffer_cur = buffer;
612            for(uint16_t i = 0; i < interval; ++i)
613                *buffer_cur++ = sd_raw_rec_byte();
614
615            if(!callback(buffer, offset + (512 - read_length), p))
616            {
617                finished = 1;
618                break;
619            }
620
621            read_length -= interval;
622            length -= interval;
623
624        } while(read_length > 0 && length > 0);
625        
626        /* read rest of data block */
627        while(read_length-- > 0)
628            sd_raw_rec_byte();
629        
630        /* read crc16 */
631        sd_raw_rec_byte();
632        sd_raw_rec_byte();
633
634        if(length < interval)
635            break;
636
637        offset = offset - block_offset + 512;
638
639    } while(!finished);
640    
641    /* deaddress card */
642    unselect_card();
643
644    /* let card some time to finish */
645    sd_raw_rec_byte();
646
647    return 1;
648#endif
649}
650
651#if DOXYGEN || SD_RAW_WRITE_SUPPORT
652/**
653 * \ingroup sd_raw
654 * Writes raw data to the card.
655 *
656 * \note If write buffering is enabled, you might have to
657 *       call sd_raw_sync() before disconnecting the card
658 *       to ensure all remaining data has been written.
659 *
660 * \param[in] offset The offset where to start writing.
661 * \param[in] buffer The buffer containing the data to be written.
662 * \param[in] length The number of bytes to write.
663 * \returns 0 on failure, 1 on success.
664 * \see sd_raw_write_interval, sd_raw_read, sd_raw_read_interval
665 */
666uint8_t sd_raw_write(offset_t offset, const uint8_t* buffer, uintptr_t length)
667{
668    if(sd_raw_locked())
669        return 0;
670
671    offset_t block_address;
672    uint16_t block_offset;
673    uint16_t write_length;
674    while(length > 0)
675    {
676        /* determine byte count to write at once */
677        block_offset = offset & 0x01ff;
678        block_address = offset - block_offset;
679        write_length = 512 - block_offset; /* write up to block border */
680        if(write_length > length)
681            write_length = length;
682        
683        /* Merge the data to write with the content of the block.
684         * Use the cached block if available.
685         */
686        if(block_address != raw_block_address)
687        {
688#if SD_RAW_WRITE_BUFFERING
689            if(!sd_raw_sync())
690                return 0;
691#endif
692
693            if(block_offset || write_length < 512)
694            {
695                if(!sd_raw_read(block_address, raw_block, sizeof(raw_block)))
696                    return 0;
697            }
698            raw_block_address = block_address;
699        }
700
701        if(buffer != raw_block)
702        {
703            memcpy(raw_block + block_offset, buffer, write_length);
704
705#if SD_RAW_WRITE_BUFFERING
706            raw_block_written = 0;
707
708            if(length == write_length)
709                return 1;
710#endif
711        }
712
713        /* address card */
714        select_card();
715
716        /* send single block request */
717#if SD_RAW_SDHC
718        if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address)))
719#else
720        if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, block_address))
721#endif
722        {
723            unselect_card();
724            return 0;
725        }
726
727        /* send start byte */
728        sd_raw_send_byte(0xfe);
729
730        /* write byte block */
731        uint8_t* cache = raw_block;
732        for(uint16_t i = 0; i < 512; ++i)
733            sd_raw_send_byte(*cache++);
734
735        /* write dummy crc16 */
736        sd_raw_send_byte(0xff);
737        sd_raw_send_byte(0xff);
738
739        /* wait while card is busy */
740        while(sd_raw_rec_byte() != 0xff);
741        sd_raw_rec_byte();
742
743        /* deaddress card */
744        unselect_card();
745
746        buffer += write_length;
747        offset += write_length;
748        length -= write_length;
749
750#if SD_RAW_WRITE_BUFFERING
751        raw_block_written = 1;
752#endif
753    }
754
755    return 1;
756}
757#endif
758
759#if DOXYGEN || SD_RAW_WRITE_SUPPORT
760/**
761 * \ingroup sd_raw
762 * Writes a continuous data stream obtained from a callback function.
763 *
764 * This function starts writing at the specified offset. To obtain the
765 * next bytes to write, it calls the callback function. The callback fills the
766 * provided data buffer and returns the number of bytes it has put into the buffer.
767 *
768 * By returning zero, the callback may stop writing.
769 *
770 * \param[in] offset Offset where to start writing.
771 * \param[in] buffer Pointer to a buffer which is used for the callback function.
772 * \param[in] length Number of bytes to write in total. May be zero for endless writes.
773 * \param[in] callback The function used to obtain the bytes to write.
774 * \param[in] p An opaque pointer directly passed to the callback function.
775 * \returns 0 on failure, 1 on success
776 * \see sd_raw_read_interval, sd_raw_write, sd_raw_read
777 */
778uint8_t sd_raw_write_interval(offset_t offset, uint8_t* buffer, uintptr_t length, sd_raw_write_interval_handler_t callback, void* p)
779{
780#if SD_RAW_SAVE_RAM
781    #error "SD_RAW_WRITE_SUPPORT is not supported together with SD_RAW_SAVE_RAM"
782#endif
783
784    if(!buffer || !callback)
785        return 0;
786
787    uint8_t endless = (length == 0);
788    while(endless || length > 0)
789    {
790        uint16_t bytes_to_write = callback(buffer, offset, p);
791        if(!bytes_to_write)
792            break;
793        if(!endless && bytes_to_write > length)
794            return 0;
795
796        /* as writing is always buffered, we directly
797         * hand over the request to sd_raw_write()
798         */
799        if(!sd_raw_write(offset, buffer, bytes_to_write))
800            return 0;
801
802        offset += bytes_to_write;
803        length -= bytes_to_write;
804    }
805
806    return 1;
807}
808#endif
809
810#if DOXYGEN || SD_RAW_WRITE_SUPPORT
811/**
812 * \ingroup sd_raw
813 * Writes the write buffer's content to the card.
814 *
815 * \note When write buffering is enabled, you should
816 *       call this function before disconnecting the
817 *       card to ensure all remaining data has been
818 *       written.
819 *
820 * \returns 0 on failure, 1 on success.
821 * \see sd_raw_write
822 */
823uint8_t sd_raw_sync()
824{
825#if SD_RAW_WRITE_BUFFERING
826    if(raw_block_written)
827        return 1;
828    if(!sd_raw_write(raw_block_address, raw_block, sizeof(raw_block)))
829        return 0;
830    raw_block_written = 1;
831#endif
832    return 1;
833}
834#endif
835
836/**
837 * \ingroup sd_raw
838 * Reads informational data from the card.
839 *
840 * This function reads and returns the card's registers
841 * containing manufacturing and status information.
842 *
843 * \note: The information retrieved by this function is
844 *        not required in any way to operate on the card,
845 *        but it might be nice to display some of the data
846 *        to the user.
847 *
848 * \param[in] info A pointer to the structure into which to save the information.
849 * \returns 0 on failure, 1 on success.
850 */
851uint8_t sd_raw_get_info(struct sd_raw_info* info)
852{
853    if(!info || !sd_raw_available())
854        return 0;
855
856    memset(info, 0, sizeof(*info));
857
858    select_card();
859
860    /* read cid register */
861    if(sd_raw_send_command(CMD_SEND_CID, 0))
862    {
863        unselect_card();
864        return 0;
865    }
866    while(sd_raw_rec_byte() != 0xfe);
867    for(uint8_t i = 0; i < 18; ++i)
868    {
869        uint8_t b = sd_raw_rec_byte();
870
871        switch(i)
872        {
873            case 0:
874                info->manufacturer = b;
875                break;
876            case 1:
877            case 2:
878                info->oem[i - 1] = b;
879                break;
880            case 3:
881            case 4:
882            case 5:
883            case 6:
884            case 7:
885                info->product[i - 3] = b;
886                break;
887            case 8:
888                info->revision = b;
889                break;
890            case 9:
891            case 10:
892            case 11:
893            case 12:
894                info->serial |= (uint32_t) b << ((12 - i) * 8);
895                break;
896            case 13:
897                info->manufacturing_year = b << 4;
898                break;
899            case 14:
900                info->manufacturing_year |= b >> 4;
901                info->manufacturing_month = b & 0x0f;
902                break;
903        }
904    }
905
906    /* read csd register */
907    uint8_t csd_read_bl_len = 0;
908    uint8_t csd_c_size_mult = 0;
909#if SD_RAW_SDHC
910    uint16_t csd_c_size = 0;
911#else
912    uint32_t csd_c_size = 0;
913#endif
914    if(sd_raw_send_command(CMD_SEND_CSD, 0))
915    {
916        unselect_card();
917        return 0;
918    }
919    while(sd_raw_rec_byte() != 0xfe);
920    for(uint8_t i = 0; i < 18; ++i)
921    {
922        uint8_t b = sd_raw_rec_byte();
923
924        if(i == 14)
925        {
926            if(b & 0x40)
927                info->flag_copy = 1;
928            if(b & 0x20)
929                info->flag_write_protect = 1;
930            if(b & 0x10)
931                info->flag_write_protect_temp = 1;
932            info->format = (b & 0x0c) >> 2;
933        }
934        else
935        {
936#if SD_RAW_SDHC
937            if(sd_raw_card_type & (1 << SD_RAW_SPEC_2))
938            {
939                switch(i)
940                {
941                    case 7:
942                        b &= 0x3f;
943                    case 8:
944                    case 9:
945                        csd_c_size <<= 8;
946                        csd_c_size |= b;
947                        break;
948                }
949                if(i == 9)
950                {
951                    ++csd_c_size;
952                    info->capacity = (offset_t) csd_c_size * 512 * 1024;
953                }
954            }
955            else
956#endif
957            {
958                switch(i)
959                {
960                    case 5:
961                        csd_read_bl_len = b & 0x0f;
962                        break;
963                    case 6:
964                        csd_c_size = b & 0x03;
965                        csd_c_size <<= 8;
966                        break;
967                    case 7:
968                        csd_c_size |= b;
969                        csd_c_size <<= 2;
970                        break;
971                    case 8:
972                        csd_c_size |= b >> 6;
973                        ++csd_c_size;
974                        break;
975                    case 9:
976                        csd_c_size_mult = b & 0x03;
977                        csd_c_size_mult <<= 1;
978                        break;
979                    case 10:
980                        csd_c_size_mult |= b >> 7;
981
982                        info->capacity = (uint32_t) csd_c_size << (csd_c_size_mult + csd_read_bl_len + 2);
983
984                        break;
985                }
986            }
987        }
988    }
989
990    unselect_card();
991
992    return 1;
993}
994