MMC/SD/SDHC card raw access

Collaboration diagram for MMC/SD/SDHC card raw access:

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)

Detailed Description

This module implements read and write access to MMC, SD and SDHC cards. It serves as a low-level driver for the higher level modules such as partition and file system access.

Define Documentation

#define SD_RAW_FORMAT_HARDDISK   0

The card's layout is harddisk-like, which means it contains a master boot record with a partition table.

Definition at line 38 of file sd_raw.h.

#define SD_RAW_FORMAT_SUPERFLOPPY   1

The card contains a single filesystem and no partition table.

Definition at line 42 of file sd_raw.h.

#define SD_RAW_FORMAT_UNIVERSAL   2

The card's layout follows the Universal File Format.

Definition at line 46 of file sd_raw.h.

#define SD_RAW_FORMAT_UNKNOWN   3

The card's layout is unknown.

Definition at line 50 of file sd_raw.h.


Typedef Documentation

typedef uint8_t(* sd_raw_read_interval_handler_t)(uint8_t *buffer, offset_t offset, void *p)

Definition at line 124 of file sd_raw.h.

typedef uintptr_t(* sd_raw_write_interval_handler_t)(uint8_t *buffer, offset_t offset, void *p)

Definition at line 125 of file sd_raw.h.


Function Documentation

uint8_t sd_raw_available (  ) 

Checks wether a memory card is located in the slot.

Returns:
1 if the card is available, 0 if it is not.

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.

Note:
: The information retrieved by this function is not required in any way to operate on the card, but it might be nice to display some of the data to the user.
Parameters:
[in] info A pointer to the structure into which to save the information.
Returns:
0 on failure, 1 on success.

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

uint8_t sd_raw_init (  ) 

Initializes memory card communication.

Returns:
0 on failure, 1 on success.

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

uint8_t sd_raw_locked (  ) 

Checks wether the memory card is locked for write access.

Returns:
1 if the card is locked, 0 if it is not.

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.

Parameters:
[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.
Returns:
0 on failure, 1 on success.
See also:
sd_raw_read_interval, sd_raw_write, sd_raw_write_interval

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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.

Note:
Within the callback function, you can not start another read or write operation.

This function only works if the following conditions are met:

  • (offset - (offset % 512)) % interval == 0
  • length % interval == 0
Parameters:
[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.
Returns:
0 on failure, 1 on success
See also:
sd_raw_write_interval, sd_raw_read, sd_raw_write

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

uint8_t sd_raw_rec_byte (  )  [static]

Receives a raw byte from the memory card.

Returns:
The byte which should be read.
See also:
sd_raw_send_byte

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 }

Here is the caller graph for this function:

void sd_raw_send_byte ( uint8_t  b  )  [static]

Sends a raw byte to the memory card.

Parameters:
[in] b The byte to sent.
See also:
sd_raw_rec_byte

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 }

Here is the caller graph for this function:

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).

Parameters:
[in] command The command to send.
[in] arg The argument for command.
Returns:
The command answer.

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

uint8_t sd_raw_sync (  ) 

Writes the write buffer's content to the card.

Note:
When write buffering is enabled, you should call this function before disconnecting the card to ensure all remaining data has been written.
Returns:
0 on failure, 1 on success.
See also:
sd_raw_write

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

uint8_t sd_raw_write ( offset_t  offset,
const uint8_t *  buffer,
uintptr_t  length 
)

Writes raw data to the card.

Note:
If write buffering is enabled, you might have to call sd_raw_sync() before disconnecting the card to ensure all remaining data has been written.
Parameters:
[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.
Returns:
0 on failure, 1 on success.
See also:
sd_raw_write_interval, sd_raw_read, sd_raw_read_interval

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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.

Parameters:
[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.
Returns:
0 on failure, 1 on success
See also:
sd_raw_read_interval, sd_raw_write, sd_raw_read

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 }

Here is the call graph for this function:

Here is the caller graph for this function:


Generated on Tue Jul 20 09:31:00 2010 for WaspmoteAPI by  doxygen 1.5.6