00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "contiki.h"
00041 #include "sd.h"
00042 #include "sd-arch.h"
00043
00044 #include <string.h>
00045
00046 #define DEBUG 0
00047 #if DEBUG
00048 #include <stdio.h>
00049 #define PRINTF(...) printf(__VA_ARGS__)
00050 #else
00051 #define PRINTF(...)
00052 #endif
00053
00054 #ifndef MIN
00055 #define MIN(a, b) ((a) < (b) ? (a) : (b))
00056 #endif
00057
00058 #define SPI_IDLE 0xff
00059
00060
00061 #define GO_IDLE_STATE 0
00062 #define SEND_OP_COND 1
00063 #define SWITCH_FUNC 6
00064 #define SEND_IF_COND 8
00065 #define SEND_CSD 9
00066 #define SEND_CID 10
00067 #define STOP_TRANSMISSION 12
00068 #define SEND_STATUS 13
00069 #define READ_SINGLE_BLOCK 17
00070 #define WRITE_BLOCK 24
00071 #define READ_OCR 58
00072
00073
00074 #define R1 1
00075 #define R2 2
00076 #define R3 5
00077 #define R7 5
00078
00079 #define START_BLOCK_TOKEN 0xfe
00080
00081
00082 #define DATA_ACCEPTED 2
00083 #define DATA_CRC_ERROR 5
00084 #define DATA_WRITE_ERROR 6
00085
00086 static uint16_t rw_block_size;
00087 static uint16_t block_size;
00088
00089 static int read_register(int register_cmd, char *buf, int register_size);
00090
00091 static int
00092 send_command(uint8_t cmd, uint32_t argument)
00093 {
00094 uint8_t req[6];
00095
00096 req[0] = 0x40 | cmd;
00097 req[1] = argument >> 24;
00098 req[2] = argument >> 16;
00099 req[3] = argument >> 8;
00100 req[4] = argument;
00101
00102
00103 req[5] = 0x95;
00104
00105 sd_arch_spi_write(SPI_IDLE);
00106 sd_arch_spi_write_block(req, sizeof(req));
00107 sd_arch_spi_write(SPI_IDLE);
00108
00109 return 0;
00110 }
00111
00112 static uint8_t *
00113 get_response(int length)
00114 {
00115 int i;
00116 int x;
00117 static uint8_t r[R7];
00118
00119 for(i = 0; i < SD_READ_RESPONSE_ATTEMPTS; i++) {
00120 x = sd_arch_spi_read();
00121 if((x & 0x80) == 0) {
00122
00123 r[0] = x;
00124 break;
00125 }
00126 }
00127
00128 if(i == SD_READ_RESPONSE_ATTEMPTS) {
00129 return NULL;
00130 }
00131
00132 for(i = 1; i < length; i++) {
00133 r[i] = sd_arch_spi_read();
00134 }
00135
00136 return r;
00137 }
00138
00139 static unsigned char *
00140 transaction(int command, unsigned long argument,
00141 int response_type, unsigned attempts)
00142 {
00143 unsigned i;
00144 unsigned char *r;
00145
00146 LOCK_SPI();
00147 r = NULL;
00148 for(i = 0; i < attempts; i++) {
00149 LOWER_CS();
00150 send_command(command, argument);
00151 r = get_response(response_type);
00152 RAISE_CS();
00153 if(r != NULL) {
00154 break;
00155 }
00156 }
00157 UNLOCK_SPI();
00158
00159 return r;
00160 }
00161
00162 int
00163 sd_initialize(void)
00164 {
00165 unsigned char reg[16];
00166 int i;
00167 uint8_t *r, read_bl_len;
00168
00169 if(sd_arch_init() < 0) {
00170 return SD_INIT_ERROR_ARCH;
00171 }
00172
00173 if(SD_CONNECTED() < 0) {
00174 return SD_INIT_ERROR_NO_CARD;
00175 }
00176
00177 r = transaction(GO_IDLE_STATE, 0, R1, SD_TRANSACTION_ATTEMPTS);
00178 if(r != NULL) {
00179 PRINTF("Go-idle result: %d\n", r[0]);
00180 } else {
00181 PRINTF("Failed to get go-idle response\n");
00182 }
00183
00184 r = transaction(SEND_IF_COND, 0, R7, SD_TRANSACTION_ATTEMPTS);
00185 if(r != NULL) {
00186 PRINTF("IF cond: %d %d %d %d %d\n", r[0], r[1], r[2], r[3], r[4]);
00187 } else {
00188 PRINTF("failed to get IF cond\n");
00189 return SD_INIT_ERROR_NO_IF_COND;
00190 }
00191
00192 LOCK_SPI();
00193
00194 for(i = 0; i < SD_TRANSACTION_ATTEMPTS; i++) {
00195 LOWER_CS();
00196 send_command(SEND_OP_COND, 0);
00197 r = get_response(R1);
00198 RAISE_CS();
00199 if(r != NULL && !(r[0] & 1)) {
00200 break;
00201 }
00202 }
00203
00204 UNLOCK_SPI();
00205
00206 if(r != NULL) {
00207 PRINTF("OP cond: %d (%d iterations)\n", r[0], i);
00208 } else {
00209 PRINTF("Failed to get OP cond get_response\n");
00210 }
00211
00212 LOCK_SPI();
00213
00214 for(i = 0; i < SD_TRANSACTION_ATTEMPTS; i++) {
00215 LOWER_CS();
00216 send_command(READ_OCR, 0);
00217 r = get_response(R3);
00218 RAISE_CS();
00219 if(r != NULL) {
00220 break;
00221 }
00222 }
00223
00224 UNLOCK_SPI();
00225
00226 if(r != NULL) {
00227 PRINTF("OCR: %d %d %d %d %d\n", r[0], r[1], r[2], r[3], r[4]);
00228 }
00229
00230
00231 if(read_register(SEND_CSD, reg, sizeof(reg)) < 0) {
00232 PRINTF("Failed to get block size of SD card\n");
00233 return SD_INIT_ERROR_NO_BLOCK_SIZE;
00234 }
00235
00236 read_bl_len = reg[5] & 0x0f;
00237 block_size = 1 << read_bl_len;
00238 rw_block_size = (block_size > SD_DEFAULT_BLOCK_SIZE) ?
00239 SD_DEFAULT_BLOCK_SIZE : block_size;
00240 PRINTF("Found block size %d\n", block_size);
00241
00242
00243 MS_DELAY(5);
00244
00245 return SD_OK;
00246 }
00247
00248 int
00249 sd_write_block(sd_offset_t offset, char *buf)
00250 {
00251 unsigned char *r;
00252 int retval;
00253 int i;
00254 unsigned char data_response;
00255 unsigned char status_code;
00256
00257 LOCK_SPI();
00258 r = NULL;
00259 retval = SD_WRITE_ERROR_NO_CMD_RESPONSE;
00260 for(i = 0; i < SD_TRANSACTION_ATTEMPTS; i++) {
00261 LOWER_CS();
00262 send_command(WRITE_BLOCK, offset);
00263 r = get_response(R1);
00264 if(r != NULL) {
00265 break;
00266 }
00267 RAISE_CS();
00268 }
00269
00270 if(r != NULL && r[0] == 0) {
00271
00272
00273 sd_arch_spi_write(START_BLOCK_TOKEN);
00274
00275
00276 sd_arch_spi_write_block(buf, rw_block_size);
00277
00278
00279 retval = SD_WRITE_ERROR_NO_BLOCK_RESPONSE;
00280 for(i = 0; i < SD_TRANSACTION_ATTEMPTS; i++) {
00281 data_response = sd_arch_spi_read();
00282 if((data_response & 0x11) == 1) {
00283
00284 status_code = (data_response >> 1) & 0x7;
00285 if(status_code == DATA_ACCEPTED) {
00286 retval = rw_block_size;
00287 } else {
00288 retval = SD_WRITE_ERROR_PROGRAMMING;
00289 }
00290 break;
00291 }
00292 }
00293 }
00294
00295 RAISE_CS();
00296 UNLOCK_SPI();
00297
00298 return retval;
00299 }
00300
00301 static int
00302 read_block(unsigned read_cmd, sd_offset_t offset, char *buf, int len)
00303 {
00304 unsigned char *r;
00305 int i;
00306 int token;
00307 int retval;
00308
00309 LOCK_SPI();
00310
00311 r = NULL;
00312 for(i = 0; i < SD_TRANSACTION_ATTEMPTS; i++) {
00313 LOWER_CS();
00314 send_command(read_cmd, offset);
00315 r = get_response(R1);
00316 if(r != NULL) {
00317 break;
00318 }
00319 RAISE_CS();
00320 }
00321
00322 if(r != NULL && r[0] == 0) {
00323
00324
00325 for(i = 0; i < SD_TRANSACTION_ATTEMPTS; i++) {
00326 token = sd_arch_spi_read();
00327 if(token == START_BLOCK_TOKEN || (token > 0 && token <= 8)) {
00328 break;
00329 }
00330 }
00331
00332 if(token == START_BLOCK_TOKEN) {
00333
00334 for(i = 0; i < len; i++) {
00335 buf[i] = sd_arch_spi_read();
00336 }
00337
00338
00339 sd_arch_spi_read();
00340 sd_arch_spi_read();
00341
00342 retval = len;
00343 } else if(token > 0 && token <= 8) {
00344
00345 retval = SD_READ_ERROR_TOKEN;
00346 } else {
00347
00348 retval = SD_READ_ERROR_NO_TOKEN;
00349 }
00350
00351 RAISE_CS();
00352 UNLOCK_SPI();
00353 return retval;
00354 }
00355
00356 RAISE_CS();
00357 UNLOCK_SPI();
00358
00359 if(r != NULL) {
00360 PRINTF("status during read: %d\n", r[0]);
00361 }
00362
00363 return SD_READ_ERROR_NO_CMD_RESPONSE;
00364 }
00365
00366 int
00367 sd_read_block(sd_offset_t offset, char *buf)
00368 {
00369 return read_block(READ_SINGLE_BLOCK, offset, buf, rw_block_size);
00370 }
00371
00372 static int
00373 read_register(int register_cmd, char *buf, int register_size)
00374 {
00375 return read_block(register_cmd, 0, buf, register_size);
00376 }
00377
00378 sd_offset_t
00379 sd_get_capacity(void)
00380 {
00381 unsigned char reg[16];
00382 int r;
00383 uint16_t c_size;
00384 uint8_t c_size_mult;
00385 sd_offset_t block_nr;
00386 sd_offset_t mult;
00387
00388 r = read_register(SEND_CSD, reg, sizeof(reg));
00389 if(r < 0) {
00390 return r;
00391 }
00392
00393 c_size = ((reg[6] & 3) << 10) + (reg[7] << 2) + ((reg[8] >> 6) & 3);
00394 c_size_mult = ((reg[9] & 3) << 1) + ((reg[10] & 0x80) >> 7);
00395 mult = 1 << (c_size_mult + 2);
00396 block_nr = (c_size + 1) * mult;
00397
00398 return block_nr * block_size;
00399 }
00400
00401 char *
00402 sd_error_string(int error_code)
00403 {
00404 #if DEBUG
00405 switch(error_code) {
00406 case SD_OK:
00407 return "operation succeeded";
00408 case SD_INIT_ERROR_NO_CARD:
00409 return "no card was found";
00410 case SD_INIT_ERROR_ARCH:
00411 return "architecture-dependent initialization failed";
00412 case SD_INIT_ERROR_NO_IF_COND:
00413 return "unable to obtain the interface condition";
00414 case SD_INIT_ERROR_NO_BLOCK_SIZE:
00415 return "unable to obtain the block size";
00416 case SD_WRITE_ERROR_NO_CMD_RESPONSE:
00417 return "no response from the card after submitting a write request";
00418 case SD_WRITE_ERROR_NO_BLOCK_RESPONSE:
00419 return "no response from the card after sending a data block";
00420 case SD_WRITE_ERROR_PROGRAMMING:
00421 return "the write request failed because of a card error";
00422 case SD_WRITE_ERROR_TOKEN:
00423 return "the card is not ready to grant a write request";
00424 case SD_READ_ERROR_NO_TOKEN:
00425 case SD_WRITE_ERROR_NO_TOKEN:
00426 return "did not receive a start block token";
00427 case SD_READ_ERROR_INVALID_SIZE:
00428 return "invalid read block size";
00429 case SD_READ_ERROR_TOKEN:
00430 return "the card is not ready to read a data block";
00431 case SD_READ_ERROR_NO_CMD_RESPONSE:
00432 return "no response from the card after submitting a read request";
00433 default:
00434 break;
00435 }
00436 #endif
00437 return "unspecified error";
00438 }
00439
00440 int
00441 sd_write(sd_offset_t offset, char *buf, size_t size)
00442 {
00443 sd_offset_t address;
00444 uint16_t offset_in_block;
00445 int r, i;
00446 size_t written;
00447 size_t to_write;
00448 char sd_buf[rw_block_size];
00449
00450
00451 memset(sd_buf, 0, sizeof(sd_buf));
00452 written = 0;
00453 offset_in_block = offset & (rw_block_size - 1);
00454
00455 do {
00456 to_write = MIN(size - written, rw_block_size - offset_in_block);
00457 address = (offset + written) & ~(rw_block_size - 1);
00458
00459 for(i = 0; i < SD_READ_BLOCK_ATTEMPTS; i++) {
00460 r = sd_read_block(address, sd_buf);
00461 if(r == sizeof(sd_buf)) {
00462 break;
00463 }
00464 }
00465 if(r != sizeof(sd_buf)) {
00466 return r;
00467 }
00468
00469 memcpy(&sd_buf[offset_in_block], &buf[written], to_write);
00470 r = sd_write_block(address, sd_buf);
00471 if(r != sizeof(sd_buf)) {
00472 return r;
00473 }
00474 written += to_write;
00475 offset_in_block = 0;
00476 } while(written < size);
00477
00478 return written;
00479 }
00480
00481 int
00482 sd_read(sd_offset_t offset, char *buf, size_t size)
00483 {
00484 size_t total_read;
00485 size_t to_read;
00486 char sd_buf[rw_block_size];
00487 uint16_t offset_in_block;
00488 int r, i;
00489
00490
00491 total_read = 0;
00492 offset_in_block = offset & (rw_block_size - 1);
00493
00494 do {
00495 to_read = MIN(size - total_read, rw_block_size - offset_in_block);
00496 for(i = 0; i < SD_READ_BLOCK_ATTEMPTS; i++) {
00497 r = sd_read_block((offset + total_read) & ~(rw_block_size - 1), sd_buf);
00498 if(r == sizeof(sd_buf)) {
00499 break;
00500 }
00501 }
00502 if(r != sizeof(sd_buf)) {
00503 return r;
00504 }
00505
00506 memcpy(&buf[total_read], &sd_buf[offset_in_block], to_read);
00507 total_read += to_read;
00508 offset_in_block = 0;
00509 } while(total_read < size);
00510
00511 return size;
00512 }
00513