|
Files | |
| file | sd_raw.c |
| file | sd_raw.h |
| file | sd_raw_config.h |
Modules | |
| MMC/SD configuration | |
Data Structures | |
| struct | sd_raw_info |
Defines | |
| #define | SD_RAW_FORMAT_HARDDISK 0 |
| #define | SD_RAW_FORMAT_SUPERFLOPPY 1 |
| #define | SD_RAW_FORMAT_UNIVERSAL 2 |
| #define | SD_RAW_FORMAT_UNKNOWN 3 |
Typedefs | |
| typedef uint8_t(* | sd_raw_read_interval_handler_t )(uint8_t *buffer, offset_t offset, void *p) |
| typedef uintptr_t(* | sd_raw_write_interval_handler_t )(uint8_t *buffer, offset_t offset, void *p) |
Functions | |
| uint8_t | sd_raw_init () |
| uint8_t | sd_raw_available () |
| uint8_t | sd_raw_locked () |
| static void | sd_raw_send_byte (uint8_t b) |
| static uint8_t | sd_raw_rec_byte () |
| static uint8_t | sd_raw_send_command (uint8_t command, uint32_t arg) |
| uint8_t | sd_raw_read (offset_t offset, uint8_t *buffer, uintptr_t length) |
| uint8_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) |
| uint8_t | sd_raw_write (offset_t offset, const uint8_t *buffer, uintptr_t length) |
| uint8_t | sd_raw_write_interval (offset_t offset, uint8_t *buffer, uintptr_t length, sd_raw_write_interval_handler_t callback, void *p) |
| uint8_t | sd_raw_sync () |
| uint8_t | sd_raw_get_info (struct sd_raw_info *info) |
| #define SD_RAW_FORMAT_HARDDISK 0 |
| #define SD_RAW_FORMAT_SUPERFLOPPY 1 |
| #define SD_RAW_FORMAT_UNIVERSAL 2 |
| #define SD_RAW_FORMAT_UNKNOWN 3 |
| typedef uint8_t(* sd_raw_read_interval_handler_t)(uint8_t *buffer, offset_t offset, void *p) |
| typedef uintptr_t(* sd_raw_write_interval_handler_t)(uint8_t *buffer, offset_t offset, void *p) |
| uint8_t sd_raw_available | ( | ) |
Checks wether a memory card is located in the slot.
Definition at line 346 of file sd_raw.c.
References get_pin_available.
00347 { 00348 return get_pin_available() == 0x00; 00349 }
| uint8_t sd_raw_get_info | ( | struct sd_raw_info * | info | ) |
Reads informational data from the card.
This function reads and returns the card's registers containing manufacturing and status information.
| [in] | info | A pointer to the structure into which to save the information. |
Definition at line 866 of file sd_raw.c.
References sd_raw_info::capacity, CMD_SEND_CID, CMD_SEND_CSD, sd_raw_info::flag_copy, sd_raw_info::flag_write_protect, sd_raw_info::flag_write_protect_temp, sd_raw_info::format, sd_raw_info::manufacturer, sd_raw_info::manufacturing_month, sd_raw_info::manufacturing_year, sd_raw_info::oem, sd_raw_info::product, sd_raw_info::revision, sd_raw_card_type, sd_raw_rec_byte(), sd_raw_send_command(), SD_RAW_SPEC_2, and sd_raw_info::serial.
Referenced by WaspSD::print_disk_info().
00867 { 00868 uint16_t i=0; 00869 00870 // if(!info || !sd_raw_available()) 00871 // return 0; 00872 00873 if(!info ) 00874 return 0; 00875 00876 memset(info, 0, sizeof(*info)); 00877 00878 select_card(); 00879 00880 /* read cid register */ 00881 if(sd_raw_send_command(CMD_SEND_CID, 0)) 00882 { 00883 unselect_card(); 00884 return 0; 00885 } 00886 while(sd_raw_rec_byte() != 0xfe); 00887 for( i = 0; i < 18; ++i) 00888 { 00889 uint8_t b = sd_raw_rec_byte(); 00890 00891 switch(i) 00892 { 00893 case 0: 00894 info->manufacturer = b; 00895 break; 00896 case 1: 00897 case 2: 00898 info->oem[i - 1] = b; 00899 break; 00900 case 3: 00901 case 4: 00902 case 5: 00903 case 6: 00904 case 7: 00905 info->product[i - 3] = b; 00906 break; 00907 case 8: 00908 info->revision = b; 00909 break; 00910 case 9: 00911 case 10: 00912 case 11: 00913 case 12: 00914 info->serial |= (uint32_t) b << ((12 - i) * 8); 00915 break; 00916 case 13: 00917 info->manufacturing_year = b << 4; 00918 break; 00919 case 14: 00920 info->manufacturing_year |= b >> 4; 00921 info->manufacturing_month = b & 0x0f; 00922 break; 00923 } 00924 } 00925 00926 /* read csd register */ 00927 uint8_t csd_read_bl_len = 0; 00928 uint8_t csd_c_size_mult = 0; 00929 #if SD_RAW_SDHC 00930 uint16_t csd_c_size = 0; 00931 #else 00932 uint32_t csd_c_size = 0; 00933 #endif 00934 if(sd_raw_send_command(CMD_SEND_CSD, 0)) 00935 { 00936 unselect_card(); 00937 return 0; 00938 } 00939 while(sd_raw_rec_byte() != 0xfe); 00940 for( i = 0; i < 18; ++i) 00941 { 00942 uint8_t b = sd_raw_rec_byte(); 00943 00944 if(i == 14) 00945 { 00946 if(b & 0x40) 00947 info->flag_copy = 1; 00948 if(b & 0x20) 00949 info->flag_write_protect = 1; 00950 if(b & 0x10) 00951 info->flag_write_protect_temp = 1; 00952 info->format = (b & 0x0c) >> 2; 00953 } 00954 else 00955 { 00956 #if SD_RAW_SDHC 00957 if(sd_raw_card_type & (1 << SD_RAW_SPEC_2)) 00958 { 00959 switch(i) 00960 { 00961 case 7: 00962 b &= 0x3f; 00963 case 8: 00964 case 9: 00965 csd_c_size <<= 8; 00966 csd_c_size |= b; 00967 break; 00968 } 00969 if(i == 9) 00970 { 00971 ++csd_c_size; 00972 info->capacity = (offset_t) csd_c_size * 512 * 1024; 00973 } 00974 } 00975 else 00976 #endif 00977 { 00978 switch(i) 00979 { 00980 case 5: 00981 csd_read_bl_len = b & 0x0f; 00982 break; 00983 case 6: 00984 csd_c_size = b & 0x03; 00985 csd_c_size <<= 8; 00986 break; 00987 case 7: 00988 csd_c_size |= b; 00989 csd_c_size <<= 2; 00990 break; 00991 case 8: 00992 csd_c_size |= b >> 6; 00993 ++csd_c_size; 00994 break; 00995 case 9: 00996 csd_c_size_mult = b & 0x03; 00997 csd_c_size_mult <<= 1; 00998 break; 00999 case 10: 01000 csd_c_size_mult |= b >> 7; 01001 01002 info->capacity = (uint32_t) csd_c_size << (csd_c_size_mult + csd_read_bl_len + 2); 01003 01004 break; 01005 } 01006 } 01007 } 01008 } 01009 01010 unselect_card(); 01011 01012 return 1; 01013 }


| uint8_t sd_raw_init | ( | ) |
Initializes memory card communication.
Definition at line 173 of file sd_raw.c.
References CMD_APP, CMD_GO_IDLE_STATE, CMD_READ_OCR, CMD_SD_SEND_OP_COND, CMD_SEND_IF_COND, CMD_SEND_OP_COND, CMD_SET_BLOCKLEN, configure_pin_available, R1_IDLE_STATE, R1_ILL_COMMAND, raw_block, raw_block_address, raw_block_written, sd_raw_card_type, sd_raw_read(), sd_raw_rec_byte(), sd_raw_send_command(), SD_RAW_SPEC_1, SD_RAW_SPEC_2, and SD_RAW_SPEC_SDHC.
Referenced by WaspSD::init().
00174 { 00175 /* enable inputs for reading card status */ 00176 configure_pin_available(); 00177 00178 00179 //FIXME: in Wasp we dont lock the card 00180 // configure_pin_locked(); 00181 00182 /* initialize SPI with lowest frequency; max. 400kHz during identification mode of card */ 00183 SPCR = (0 << SPIE) | /* SPI Interrupt Enable */ 00184 (1 << SPE) | /* SPI Enable */ 00185 (0 << DORD) | /* Data Order: MSB first */ 00186 (1 << MSTR) | /* Master mode */ 00187 (0 << CPOL) | /* Clock Polarity: SCK low when idle */ 00188 (0 << CPHA) | /* Clock Phase: sample on rising SCK edge */ 00189 (1 << SPR1) | /* Clock Frequency: f_OSC / 128 */ 00190 (1 << SPR0); 00191 SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */ 00192 00193 /* enable outputs for MOSI, SCK, SS, input for MISO */ 00194 configure_pin_mosi(); 00195 configure_pin_sck(); 00196 configure_pin_ss(); 00197 configure_pin_miso(); 00198 00199 00200 /* unselect_card();*/ 00201 00202 /* initialization procedure */ 00203 sd_raw_card_type = 0; 00204 00205 // Already checked in WaspSD library 00206 // if(!sd_raw_available()) 00207 // return 0; 00208 00209 uint16_t i=0; 00210 /* card needs 74 cycles minimum to start up */ 00211 for(i = 0; i < 10; ++i) 00212 { 00213 /* wait 8 clock cycles */ 00214 sd_raw_rec_byte(); 00215 } 00216 00217 /* address card */ 00218 select_card(); 00219 00220 /* reset card */ 00221 uint8_t response; 00222 for( i = 0; ; ++i) 00223 { 00224 response = sd_raw_send_command(CMD_GO_IDLE_STATE, 0); 00225 if(response == (1 << R1_IDLE_STATE)) 00226 break; 00227 00228 if(i == 0x1ff) 00229 { 00230 unselect_card(); 00231 return 0; 00232 } 00233 } 00234 00235 #if SD_RAW_SDHC 00236 /* check for version of SD card specification */ 00237 response = sd_raw_send_command(CMD_SEND_IF_COND, 0x100 /* 2.7V - 3.6V */ | 0xaa /* test pattern */); 00238 if((response & (1 << R1_ILL_COMMAND)) == 0) 00239 { 00240 sd_raw_rec_byte(); 00241 sd_raw_rec_byte(); 00242 if((sd_raw_rec_byte() & 0x01) == 0) 00243 return 0; /* card operation voltage range doesn't match */ 00244 if(sd_raw_rec_byte() != 0xaa) 00245 return 0; /* wrong test pattern */ 00246 00247 /* card conforms to SD 2 card specification */ 00248 sd_raw_card_type |= (1 << SD_RAW_SPEC_2); 00249 } 00250 else 00251 #endif 00252 { 00253 /* determine SD/MMC card type */ 00254 sd_raw_send_command(CMD_APP, 0); 00255 response = sd_raw_send_command(CMD_SD_SEND_OP_COND, 0); 00256 if((response & (1 << R1_ILL_COMMAND)) == 0) 00257 { 00258 /* card conforms to SD 1 card specification */ 00259 sd_raw_card_type |= (1 << SD_RAW_SPEC_1); 00260 } 00261 else 00262 { 00263 /* MMC card */ 00264 } 00265 } 00266 00267 /* wait for card to get ready */ 00268 for( i = 0; ; ++i) 00269 { 00270 if(sd_raw_card_type & ((1 << SD_RAW_SPEC_1) | (1 << SD_RAW_SPEC_2))) 00271 { 00272 uint32_t arg = 0; 00273 #if SD_RAW_SDHC 00274 if(sd_raw_card_type & (1 << SD_RAW_SPEC_2)) 00275 arg = 0x40000000; 00276 #endif 00277 sd_raw_send_command(CMD_APP, 0); 00278 response = sd_raw_send_command(CMD_SD_SEND_OP_COND, arg); 00279 } 00280 else 00281 { 00282 response = sd_raw_send_command(CMD_SEND_OP_COND, 0); 00283 } 00284 00285 if((response & (1 << R1_IDLE_STATE)) == 0) 00286 break; 00287 00288 if(i == 0x7fff) 00289 { 00290 unselect_card(); 00291 return 0; 00292 } 00293 } 00294 00295 #if SD_RAW_SDHC 00296 if(sd_raw_card_type & (1 << SD_RAW_SPEC_2)) 00297 { 00298 if(sd_raw_send_command(CMD_READ_OCR, 0)) 00299 { 00300 unselect_card(); 00301 return 0; 00302 } 00303 00304 if(sd_raw_rec_byte() & 0x40) 00305 sd_raw_card_type |= (1 << SD_RAW_SPEC_SDHC); 00306 00307 sd_raw_rec_byte(); 00308 sd_raw_rec_byte(); 00309 sd_raw_rec_byte(); 00310 } 00311 #endif 00312 00313 /* set block size to 512 bytes */ 00314 if(sd_raw_send_command(CMD_SET_BLOCKLEN, 512)) 00315 { 00316 unselect_card(); 00317 return 0; 00318 } 00319 00320 /* deaddress card */ 00321 unselect_card(); 00322 00323 /* switch to highest SPI frequency possible */ 00324 SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 */ 00325 SPSR |= (1 << SPI2X); /* Doubled Clock Frequency: f_OSC / 2 */ 00326 00327 #if !SD_RAW_SAVE_RAM 00328 /* the first block is likely to be accessed first, so precache it here */ 00329 raw_block_address = (offset_t) -1; 00330 #if SD_RAW_WRITE_BUFFERING 00331 raw_block_written = 1; 00332 #endif 00333 if(!sd_raw_read(0, raw_block, sizeof(raw_block))) 00334 return 0; 00335 #endif 00336 00337 return 1; 00338 }


| uint8_t sd_raw_locked | ( | ) |
Checks wether the memory card is locked for write access.
Definition at line 357 of file sd_raw.c.
References get_pin_locked.
00358 { 00359 return get_pin_locked() == 0x00; 00360 }
| uint8_t sd_raw_read | ( | offset_t | offset, | |
| uint8_t * | buffer, | |||
| uintptr_t | length | |||
| ) |
Reads raw data from the card.
| [in] | offset | The offset from which to read. |
| [out] | buffer | The buffer into which to write the data. |
| [in] | length | The number of bytes to read. |
Definition at line 450 of file sd_raw.c.
References CMD_READ_SINGLE_BLOCK, raw_block, raw_block_address, sd_raw_card_type, sd_raw_rec_byte(), sd_raw_send_command(), SD_RAW_SPEC_SDHC, and sd_raw_sync().
Referenced by WaspSD::init(), sd_raw_init(), sd_raw_read_interval(), and sd_raw_write().
00451 { 00452 offset_t block_address; 00453 uint16_t block_offset; 00454 uint16_t read_length; 00455 uint16_t i=0; 00456 00457 while(length > 0) 00458 { 00459 /* determine byte count to read at once */ 00460 block_offset = offset & 0x01ff; 00461 block_address = offset - block_offset; 00462 read_length = 512 - block_offset; /* read up to block border */ 00463 if(read_length > length) 00464 read_length = length; 00465 00466 #if !SD_RAW_SAVE_RAM 00467 /* check if the requested data is cached */ 00468 if(block_address != raw_block_address) 00469 #endif 00470 { 00471 #if SD_RAW_WRITE_BUFFERING 00472 if(!sd_raw_sync()) 00473 return 0; 00474 #endif 00475 00476 /* address card */ 00477 select_card(); 00478 00479 /* send single block request */ 00480 #if SD_RAW_SDHC 00481 if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address))) 00482 #else 00483 if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, block_address)) 00484 #endif 00485 { 00486 unselect_card(); 00487 return 0; 00488 } 00489 00490 /* wait for data block (start byte 0xfe) */ 00491 while(sd_raw_rec_byte() != 0xfe); 00492 00493 #if SD_RAW_SAVE_RAM 00494 /* read byte block */ 00495 uint16_t read_to = block_offset + read_length; 00496 for( i = 0; i < 512; ++i) 00497 { 00498 uint8_t b = sd_raw_rec_byte(); 00499 if(i >= block_offset && i < read_to) 00500 *buffer++ = b; 00501 } 00502 #else 00503 /* read byte block */ 00504 uint8_t* cache = raw_block; 00505 for( i = 0; i < 512; ++i) 00506 *cache++ = sd_raw_rec_byte(); 00507 raw_block_address = block_address; 00508 00509 memcpy(buffer, raw_block + block_offset, read_length); 00510 buffer += read_length; 00511 #endif 00512 00513 /* read crc16 */ 00514 sd_raw_rec_byte(); 00515 sd_raw_rec_byte(); 00516 00517 /* deaddress card */ 00518 unselect_card(); 00519 00520 /* let card some time to finish */ 00521 sd_raw_rec_byte(); 00522 } 00523 #if !SD_RAW_SAVE_RAM 00524 else 00525 { 00526 /* use cached data */ 00527 memcpy(buffer, raw_block + block_offset, read_length); 00528 buffer += read_length; 00529 } 00530 #endif 00531 00532 length -= read_length; 00533 offset += read_length; 00534 } 00535 00536 return 1; 00537 }


| uint8_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 | |||
| ) |
Continuously reads units of interval bytes and calls a callback function.
This function starts reading at the specified offset. Every interval bytes, it calls the callback function with the associated data buffer.
By returning zero, the callback may stop reading.
This function only works if the following conditions are met:
| [in] | offset | Offset from which to start reading. |
| [in] | buffer | Pointer to a buffer which is at least interval bytes in size. |
| [in] | interval | Number of bytes to read before calling the callback function. |
| [in] | length | Number of bytes to read altogether. |
| [in] | callback | The function to call every interval bytes. |
| [in] | p | An opaque pointer directly passed to the callback function. |
Definition at line 563 of file sd_raw.c.
References CMD_READ_SINGLE_BLOCK, sd_raw_card_type, sd_raw_read(), sd_raw_rec_byte(), sd_raw_send_command(), and SD_RAW_SPEC_SDHC.
Referenced by WaspSD::init().
00564 { 00565 if(!buffer || interval == 0 || length < interval || !callback) 00566 return 0; 00567 00568 #if !SD_RAW_SAVE_RAM 00569 while(length >= interval) 00570 { 00571 /* as reading is now buffered, we directly 00572 * hand over the request to sd_raw_read() 00573 */ 00574 if(!sd_raw_read(offset, buffer, interval)) 00575 return 0; 00576 if(!callback(buffer, offset, p)) 00577 break; 00578 offset += interval; 00579 length -= interval; 00580 } 00581 00582 return 1; 00583 #else 00584 /* address card */ 00585 select_card(); 00586 00587 uint16_t block_offset; 00588 uint16_t read_length; 00589 uint8_t* buffer_cur; 00590 uint8_t finished = 0; 00591 uint16_t i=0; 00592 00593 do 00594 { 00595 /* determine byte count to read at once */ 00596 block_offset = offset & 0x01ff; 00597 read_length = 512 - block_offset; 00598 00599 /* send single block request */ 00600 #if SD_RAW_SDHC 00601 if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? offset / 512 : offset - block_offset))) 00602 #else 00603 if(sd_raw_send_command(CMD_READ_SINGLE_BLOCK, offset - block_offset)) 00604 #endif 00605 { 00606 unselect_card(); 00607 return 0; 00608 } 00609 00610 /* wait for data block (start byte 0xfe) */ 00611 while(sd_raw_rec_byte() != 0xfe); 00612 00613 /* read up to the data of interest */ 00614 for( i = 0; i < block_offset; ++i) 00615 sd_raw_rec_byte(); 00616 00617 /* read interval bytes of data and execute the callback */ 00618 do 00619 { 00620 if(read_length < interval || length < interval) 00621 break; 00622 00623 buffer_cur = buffer; 00624 for( i = 0; i < interval; ++i) 00625 *buffer_cur++ = sd_raw_rec_byte(); 00626 00627 if(!callback(buffer, offset + (512 - read_length), p)) 00628 { 00629 finished = 1; 00630 break; 00631 } 00632 00633 read_length -= interval; 00634 length -= interval; 00635 00636 } while(read_length > 0 && length > 0); 00637 00638 /* read rest of data block */ 00639 while(read_length-- > 0) 00640 sd_raw_rec_byte(); 00641 00642 /* read crc16 */ 00643 sd_raw_rec_byte(); 00644 sd_raw_rec_byte(); 00645 00646 if(length < interval) 00647 break; 00648 00649 offset = offset - block_offset + 512; 00650 00651 } while(!finished); 00652 00653 /* deaddress card */ 00654 unselect_card(); 00655 00656 /* let card some time to finish */ 00657 sd_raw_rec_byte(); 00658 00659 return 1; 00660 #endif 00661 }


| uint8_t sd_raw_rec_byte | ( | ) | [static] |
Receives a raw byte from the memory card.
Definition at line 384 of file sd_raw.c.
Referenced by sd_raw_get_info(), sd_raw_init(), sd_raw_read(), sd_raw_read_interval(), sd_raw_send_command(), and sd_raw_write().
00385 { 00386 /* send dummy data for receiving some */ 00387 SPDR = 0xff; 00388 while(!(SPSR & (1 << SPIF))); 00389 SPSR &= ~(1 << SPIF); 00390 00391 return SPDR; 00392 }

| void sd_raw_send_byte | ( | uint8_t | b | ) | [static] |
Sends a raw byte to the memory card.
| [in] | b | The byte to sent. |
Definition at line 369 of file sd_raw.c.
Referenced by sd_raw_send_command(), and sd_raw_write().
00370 { 00371 SPDR = b; 00372 /* wait for byte to be shifted out */ 00373 while(!(SPSR & (1 << SPIF))); 00374 SPSR &= ~(1 << SPIF); 00375 }

| uint8_t sd_raw_send_command | ( | uint8_t | command, | |
| uint32_t | arg | |||
| ) | [static] |
Send a command to the memory card which responses with a R1 response (and possibly others).
| [in] | command | The command to send. |
| [in] | arg | The argument for command. |
Definition at line 402 of file sd_raw.c.
References CMD_GO_IDLE_STATE, CMD_SEND_IF_COND, sd_raw_rec_byte(), and sd_raw_send_byte().
Referenced by sd_raw_get_info(), sd_raw_init(), sd_raw_read(), sd_raw_read_interval(), and sd_raw_write().
00403 { 00404 uint8_t response; 00405 00406 /* wait some clock cycles */ 00407 sd_raw_rec_byte(); 00408 00409 /* send command via SPI */ 00410 sd_raw_send_byte(0x40 | command); 00411 sd_raw_send_byte((arg >> 24) & 0xff); 00412 sd_raw_send_byte((arg >> 16) & 0xff); 00413 sd_raw_send_byte((arg >> 8) & 0xff); 00414 sd_raw_send_byte((arg >> 0) & 0xff); 00415 switch(command) 00416 { 00417 case CMD_GO_IDLE_STATE: 00418 sd_raw_send_byte(0x95); 00419 break; 00420 case CMD_SEND_IF_COND: 00421 sd_raw_send_byte(0x87); 00422 break; 00423 default: 00424 sd_raw_send_byte(0xff); 00425 break; 00426 } 00427 00428 /* receive response */ 00429 uint8_t i=0; 00430 for( i = 0; i < 10; ++i) 00431 { 00432 response = sd_raw_rec_byte(); 00433 if(response != 0xff) 00434 break; 00435 } 00436 00437 return response; 00438 }


| uint8_t sd_raw_sync | ( | ) |
Writes the write buffer's content to the card.
Definition at line 838 of file sd_raw.c.
References raw_block, raw_block_address, raw_block_written, and sd_raw_write().
Referenced by sd_raw_read(), and sd_raw_write().
00839 { 00840 #if SD_RAW_WRITE_BUFFERING 00841 if(raw_block_written) 00842 return 1; 00843 if(!sd_raw_write(raw_block_address, raw_block, sizeof(raw_block))) 00844 return 0; 00845 raw_block_written = 1; 00846 #endif 00847 return 1; 00848 }


| uint8_t sd_raw_write | ( | offset_t | offset, | |
| const uint8_t * | buffer, | |||
| uintptr_t | length | |||
| ) |
Writes raw data to the card.
| [in] | offset | The offset where to start writing. |
| [in] | buffer | The buffer containing the data to be written. |
| [in] | length | The number of bytes to write. |
Definition at line 678 of file sd_raw.c.
References CMD_WRITE_SINGLE_BLOCK, raw_block, raw_block_address, raw_block_written, sd_raw_card_type, sd_raw_read(), sd_raw_rec_byte(), sd_raw_send_byte(), sd_raw_send_command(), SD_RAW_SPEC_SDHC, and sd_raw_sync().
Referenced by WaspSD::init(), sd_raw_sync(), and sd_raw_write_interval().
00679 { 00680 // if(sd_raw_locked()) 00681 // return 0; 00682 00683 offset_t block_address; 00684 uint16_t block_offset; 00685 uint16_t write_length; 00686 uint16_t i=0; 00687 00688 while(length > 0) 00689 { 00690 /* determine byte count to write at once */ 00691 block_offset = offset & 0x01ff; 00692 block_address = offset - block_offset; 00693 write_length = 512 - block_offset; /* write up to block border */ 00694 if(write_length > length) 00695 write_length = length; 00696 00697 /* Merge the data to write with the content of the block. 00698 * Use the cached block if available. 00699 */ 00700 if(block_address != raw_block_address) 00701 { 00702 #if SD_RAW_WRITE_BUFFERING 00703 if(!sd_raw_sync()) 00704 return 0; 00705 #endif 00706 00707 if(block_offset || write_length < 512) 00708 { 00709 if(!sd_raw_read(block_address, raw_block, sizeof(raw_block))){ 00710 return 0; 00711 } 00712 } 00713 raw_block_address = block_address; 00714 } 00715 00716 if(buffer != raw_block) 00717 { 00718 memcpy(raw_block + block_offset, buffer, write_length); 00719 00720 #if SD_RAW_WRITE_BUFFERING 00721 raw_block_written = 0; 00722 00723 if(length == write_length){ 00724 return 1; 00725 } 00726 #endif 00727 } 00728 00729 /* address card */ 00730 select_card(); 00731 00732 /* send single block request */ 00733 #if SD_RAW_SDHC 00734 if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, (sd_raw_card_type & (1 << SD_RAW_SPEC_SDHC) ? block_address / 512 : block_address))) 00735 #else 00736 if(sd_raw_send_command(CMD_WRITE_SINGLE_BLOCK, block_address)) 00737 #endif 00738 { 00739 unselect_card(); 00740 return 0; 00741 } 00742 00743 /* send start byte */ 00744 sd_raw_send_byte(0xfe); 00745 00746 /* write byte block */ 00747 uint8_t* cache = raw_block; 00748 for( i = 0; i < 512; ++i) 00749 sd_raw_send_byte(*cache++); 00750 00751 /* write dummy crc16 */ 00752 sd_raw_send_byte(0xff); 00753 sd_raw_send_byte(0xff); 00754 00755 /* wait while card is busy */ 00756 while(sd_raw_rec_byte() != 0xff); 00757 sd_raw_rec_byte(); 00758 00759 /* deaddress card */ 00760 unselect_card(); 00761 00762 buffer += write_length; 00763 offset += write_length; 00764 length -= write_length; 00765 00766 #if SD_RAW_WRITE_BUFFERING 00767 raw_block_written = 1; 00768 #endif 00769 } 00770 return 1; 00771 }


| uint8_t sd_raw_write_interval | ( | offset_t | offset, | |
| uint8_t * | buffer, | |||
| uintptr_t | length, | |||
| sd_raw_write_interval_handler_t | callback, | |||
| void * | p | |||
| ) |
Writes a continuous data stream obtained from a callback function.
This function starts writing at the specified offset. To obtain the next bytes to write, it calls the callback function. The callback fills the provided data buffer and returns the number of bytes it has put into the buffer.
By returning zero, the callback may stop writing.
| [in] | offset | Offset where to start writing. |
| [in] | buffer | Pointer to a buffer which is used for the callback function. |
| [in] | length | Number of bytes to write in total. May be zero for endless writes. |
| [in] | callback | The function used to obtain the bytes to write. |
| [in] | p | An opaque pointer directly passed to the callback function. |
Definition at line 793 of file sd_raw.c.
References sd_raw_write().
Referenced by WaspSD::init().
00794 { 00795 #if SD_RAW_SAVE_RAM 00796 #error "SD_RAW_WRITE_SUPPORT is not supported together with SD_RAW_SAVE_RAM" 00797 #endif 00798 00799 if(!buffer || !callback) 00800 return 0; 00801 00802 uint8_t endless = (length == 0); 00803 while(endless || length > 0) 00804 { 00805 uint16_t bytes_to_write = callback(buffer, offset, p); 00806 if(!bytes_to_write) 00807 break; 00808 if(!endless && bytes_to_write > length) 00809 return 0; 00810 00811 /* as writing is always buffered, we directly 00812 * hand over the request to sd_raw_write() 00813 */ 00814 if(!sd_raw_write(offset, buffer, bytes_to_write)) 00815 return 0; 00816 00817 offset += bytes_to_write; 00818 length -= bytes_to_write; 00819 } 00820 00821 return 1; 00822 }


1.5.6