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