# sd_card

Library for communicating with SD memory cards

Author | Matthew Schinkel - borntechi.com, copyright © 2009..2022, all rights reserved.
Adapted-by | Rob Jansen + Matthew Schinkel
Compiler | 2.5r9

Description

    this library provides functions for SD memory cards.

Sources

    SanDisk Secure Digital Card - http://www.cs.ucr.edu/~amitra/sdcard/ProdManualSDCardv1.9.pdf
    How to use MMC/SDC - http://forums.parallax.com/forums/attach.aspx?a=32012
    http://www.rjhcoding.com/avrc-sd-interface-3.php

Notes

    SD card SPI mode is 1,1

Dependencies

- print
- large_array_6

## Summary

### Global variables/contants

- `const byte SD_COMMAND_CRC_ERROR = 9`
- `var dword sd_error_count = 0`
- `const bit SD_STANDARD_CAPACITY = 1`
- `const byte SD_CRC_ERROR = 8`
- `const byte SD_CLR_WRITE_PROT = 29`
- `const byte SD_TIMED_OUT = 3`
- `var word sd_error_details = 0`
- `const SD_CARD = 1`
- `const byte SD_SEND_IF_COND = 8`
- `const byte SD_ERASE_WR_BLK_END = 33`
- `const DATA_MEDIA = SD_CARD`
- `const byte SD_SEND_WRITE_PROT = 30`
- `const word SD_BYTE_PER_SECTOR = 512`
- `const byte SD_STOP_TRANSMISSION = 12`
- `const byte SD_WRITE_MULTIPLE_BLOCK = 25`
- `const byte SD_SEND_STATUS = 13`
- `const byte SD_INIT_FAILURE = 2`
- `var dword sd_number_of_sectors`
- `const byte SD_PROGRAM_CSD = 27`
- `var byte sd_max_retries = 3`
- `const dword LARGE_ARRAY_6_SIZE = 512`
- `const byte SD_DEVICE_NOT_FOUND = 0`
- `const byte SD_SEND_CSD = 9`
- `const byte SD_CRC_ON_OFF = 59`
- `var dword sd_success_count = 0`
- `const byte SD_SEND_NUM_WR_BLOCKS = 22`
- `var word sd_sector_count = 0`
- `const byte SD_COMMAND_TIME_OUT = 4`
- `const byte SD_READ_SINGLE_BLOCK = 17`
- `const byte SD_SET_CLR_CARD_DETECT = 42`
- `const byte SD_IN_IDLE_STATE = 0`
- `const byte SD_ERASE_WR_BLK_START = 32`
- `var bit sd_card_type = 0`
- `const bit SD_HIGH_CAPACITY = 0`
- `const byte SD_GO_IDLE_STATE = 0`
- `const byte SD_SET_BLOCKLEN = 16`
- `const byte SD_READ_ERROR = 6`
- `var byte sd_retry_count = 0`
- `const byte SD_SD_APP_OP_COND = 41`
- `const byte SD_WRITE_ERROR = 7`
- `const byte SD_ERASE_RESET = 1`
- `const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1`
- `const byte SD_COM_CRC_ERROR = 3`
- `const byte SD_SEND_SCR = 51`
- `var bit sd_has_init = 0`
- `const byte SD_PARAMETER_ERROR = 6`
- `const byte SD_READ_MULTIPLE_BLOCK = 18`
- `const PATA_HARD_DISK = 0`
- `const byte SD_DATA_CRC_ERROR = 10`
- `const byte SD_SEND_OP_COND = 1`
- `const byte SD_READ = 0`
- `const byte SD_ILLEGAL_COMMAND = 2`
- `const byte SD_COMMAND_NOT_SUPPORTED = 5`
- `const byte SD_WRITE = 1`
- `var dword sd_sector_select`
- `const byte SD_WRITE_BLOCK = 24`
- `const byte SD_GEN_CMD = 56`
- `const byte SD_SEND_CID = 10`
- `const byte SD_APP_CMD = 55`
- `const byte SD_SD_STATUS = 13`
- `const byte SD_ERASE = 38`
- `const byte SD_ADDRESS_ERROR = 5`
- `var bit sd_has_error = 0`
- `const byte SD_SET_WR_BLK_ERASE_COUNT = 23`
- `const byte SD_TYPE_NOT_SUPPORTED = 1`
- `const byte SD_READ_OCR = 58`
- `const byte SD_ERASE_SEQUENCE_ERROR = 4`
- `var word sd_byte_count = 0`
- `const byte SD_SET_WRITE_PROT = 28`

### Procedures

- `sd_read_sector_address(dword in address)`
- `sd_write_sector()`
- `sd_stop_read()`
- `sd_error'put(word in error)`
- `sd_write_pulse(byte in count1)`
- `sd_write_sector_with_callback(word in chunk_size)`
- `sd_stop_write()`
- `sd_seperator()`
- `sd_print_response(volatile byte out device,byte in response)`
- `sd_check_crc_errors()`
- `sd_print_enhanced_statistics()`
- `send_command(byte in command,dword in data, byte out response)`
- `sd_enable()`
- `sd_toggle()`
- `sd_reset_error_state()`
- `sd_print_error(volatile byte out device)`
- `sd_set_idle()`
- `sd_print_sector_hex(volatile byte out device,word in bytes_per_line,dword in address)`
- `sd_write_sector_address(dword in address)`
- `sd_retry_operation(dword in sector_address, byte in operation_type)`
- `sd_read_pulse_byte(word in count1)`
- `sd_read_sector_with_callback(word in chunk_size)`
- `sd_start_write(dword in address)`
- `sd_disable()`
- `sd_write_to_sector_end(byte in input_byte)`
- `sd_init()`
- `sd_print_sector(volatile byte out device, dword in address)`
- `sd_write_pulse_byte(word in count1)`
- `sd_read_sector()`
- `sd_start_read(dword in address)`
- `sd_data_byte'put(byte in data_byte)`

Private

- `_sd_read_512()`
- `_sd_write_512()`
- `_sd_read_512_crc()`
- `_sd_write_512_crc()`

### Functions

- `sd_error'get() return word`
- `sd_read_write_next_ready(byte in read_write) return byte`
- `sd_data_byte'get() return byte`
- `sd_ready() return byte`
- `sd_is_inserted() return bit`

## API details

### Global variables/contants

- `const byte SD_COMMAND_CRC_ERROR = 9`

  No documentation found

- `var dword sd_error_count = 0`

  No documentation found

- `const bit SD_STANDARD_CAPACITY = 1`

  No documentation found

- `const byte SD_CRC_ERROR = 8`

  No documentation found

- `const byte SD_CLR_WRITE_PROT = 29`

  No documentation found

- `const byte SD_TIMED_OUT = 3`

  No documentation found

- `var word sd_error_details = 0`

  No documentation found

- `const SD_CARD = 1`

  No documentation found

- `const byte SD_SEND_IF_COND = 8`

      for SDHC only

- `const byte SD_ERASE_WR_BLK_END = 33`

  No documentation found

- `const DATA_MEDIA = SD_CARD`

  No documentation found

- `const byte SD_SEND_WRITE_PROT = 30`

  No documentation found

- `const word SD_BYTE_PER_SECTOR = 512`

  No documentation found

- `const byte SD_STOP_TRANSMISSION = 12`

  No documentation found

- `const byte SD_WRITE_MULTIPLE_BLOCK = 25`

  No documentation found

- `const byte SD_SEND_STATUS = 13`

  No documentation found

- `const byte SD_INIT_FAILURE = 2`

  No documentation found

- `var dword sd_number_of_sectors`

      number of sectors variable

- `const byte SD_PROGRAM_CSD = 27`

  No documentation found

- `var byte sd_max_retries = 3`

      =============================================================================
      Enhanced Error Handling Variables
      =============================================================================

- `const dword LARGE_ARRAY_6_SIZE = 512`

      Define sector buffer for SD card operations
      Use Large Array to set up the sector buffer (512 bytes)

- `const byte SD_DEVICE_NOT_FOUND = 0`

  No documentation found

- `const byte SD_SEND_CSD = 9`

      sd sends "Card Specific Data" standard or high capacity

- `const byte SD_CRC_ON_OFF = 59`

      default is off

- `var dword sd_success_count = 0`

  No documentation found

- `const byte SD_SEND_NUM_WR_BLOCKS = 22`

  No documentation found

- `var word sd_sector_count = 0`

  No documentation found

- `const byte SD_COMMAND_TIME_OUT = 4`

  No documentation found

- `const byte SD_READ_SINGLE_BLOCK = 17`

  No documentation found

- `const byte SD_SET_CLR_CARD_DETECT = 42`

  No documentation found

- `const byte SD_IN_IDLE_STATE = 0`

      R1 RESPONSE BITS

- `const byte SD_ERASE_WR_BLK_START = 32`

      Erase Commands

- `var bit sd_card_type = 0`

      misc variables

- `const bit SD_HIGH_CAPACITY = 0`

  No documentation found

- `const byte SD_GO_IDLE_STATE = 0`

      Basic Commands

- `const byte SD_SET_BLOCKLEN = 16`

      Read Commands

- `const byte SD_READ_ERROR = 6`

  No documentation found

- `var byte sd_retry_count = 0`

  No documentation found

- `const byte SD_SD_APP_OP_COND = 41`

  No documentation found

- `const byte SD_WRITE_ERROR = 7`

  No documentation found

- `const byte SD_ERASE_RESET = 1`

  No documentation found

- `const dword LARGE_ARRAY_6_VARIABLE_SIZE = 1`

      choose bytes size of variables

- `const byte SD_COM_CRC_ERROR = 3`

  No documentation found

- `const byte SD_SEND_SCR = 51`

  No documentation found

- `var bit sd_has_init = 0`

  No documentation found

- `const byte SD_PARAMETER_ERROR = 6`

  No documentation found

- `const byte SD_READ_MULTIPLE_BLOCK = 18`

  No documentation found

- `const PATA_HARD_DISK = 0`

      constants for fat32 library

- `const byte SD_DATA_CRC_ERROR = 10`

  No documentation found

- `const byte SD_SEND_OP_COND = 1`

  No documentation found

- `const byte SD_READ = 0`

      Read/write constants

- `const byte SD_ILLEGAL_COMMAND = 2`

  No documentation found

- `const byte SD_COMMAND_NOT_SUPPORTED = 5`

  No documentation found

- `const byte SD_WRITE = 1`

  No documentation found

- `var dword sd_sector_select`

  No documentation found

- `const byte SD_WRITE_BLOCK = 24`

      Write Commands

- `const byte SD_GEN_CMD = 56`

  No documentation found

- `const byte SD_SEND_CID = 10`

  No documentation found

- `const byte SD_APP_CMD = 55`

      Application Specific Commands

- `const byte SD_SD_STATUS = 13`

      application specific command, must write command 55 first

- `const byte SD_ERASE = 38`

  No documentation found

- `const byte SD_ADDRESS_ERROR = 5`

  No documentation found

- `var bit sd_has_error = 0`

      error codes
      if any are added, they should be added to sd_print_error()

- `const byte SD_SET_WR_BLK_ERASE_COUNT = 23`

  No documentation found

- `const byte SD_TYPE_NOT_SUPPORTED = 1`

  No documentation found

- `const byte SD_READ_OCR = 58`

      Other Commands

- `const byte SD_ERASE_SEQUENCE_ERROR = 4`

  No documentation found

- `var word sd_byte_count = 0`

      counters

- `const byte SD_SET_WRITE_PROT = 28`

      Write Protection Commands

### Procedures

- `sd_read_sector_address(dword in address)`

      Description: Read single sector at specified address
       Convenience function combining start, read, and stop operations
      Parameters:
       address - Sector number to read from
      Returns: None
      Notes: Data is stored in sd_sector_buffer[0-511]
       Automatically handles start and stop of read operation
       Equivalent to calling sd_start_read(), sd_read_sector(), sd_stop_read()
       Use for reading single sectors; for multiple sectors use manual control

- `sd_write_sector()`

      Description: Write one complete 512-byte sector from buffer
       Writes entire sector from sd_sector_buffer to current position
      Parameters: None
      Returns: None
      Notes: Sector data must be in sd_sector_buffer[0-511] before calling
       Performs CRC16 calculation if SD_USE_CRC is enabled
       Uses optimized unrolled loop if SD_WRITE_EXTRA_SPEED is enabled
       Waits for write completion before returning
       Sets SD_CRC_ERROR if CRC calculation fails

- `sd_stop_read()`

      Description: Stop multi-block read operation
       Ends read session and returns SD card to idle state
      Parameters: None
      Returns: None
      Notes: Must be called after sd_start_read() when finished reading
       Required for compatibility with mass media library interface
       Sends STOP_TRANSMISSION command to card

- `sd_error'put(word in error)`

      Description: Set SD card error flag
       Records error by setting corresponding bit in error details register
      Parameters:
       error - Error code number to set (0-15)
      Returns: None
      Notes: Multiple errors can be recorded simultaneously as bit flags
       Sets sd_has_error flag to indicate error state

- `sd_write_pulse(byte in count1)`

      Description: Write zero bytes to SD card (OBSOLETE)
       Writes pairs of zero bytes to advance write position
      Parameters:
       count1 - Number of byte pairs to write (writes count1 * 2 bytes)
      Returns: None
      Notes: This procedure is obsolete - use sd_write_pulse_byte() instead
       Writes two zero bytes per loop iteration
       Kept for backwards compatibility only

- `sd_write_sector_with_callback(word in chunk_size)`

      Description: Write sector in chunks using callback function
       Allows user-provided callback to supply data as it's written
      Parameters:
       chunk_size - Number of bytes per callback (must divide evenly into 512)
      Returns: None
      Notes: Callback function must write chunk_size bytes via spi_master
       User must implement storage_write_callback(word in chunk_size)
       Example: chunk_size of 64 calls callback 8 times (512/64)
       Useful for direct USB or serial streaming without buffering
       Requires SD_WRITE_EXTRA_SPEED to be enabled

- `sd_stop_write()`

      Description: Stop multi-block write operation
       Ends write session and returns SD card to idle state
      Parameters: None
      Returns: None
      Notes: Must be called after sd_start_write() when finished writing
       Automatically pads partial sector with zeros
       Sends stop transmission token (0xFD)
       Waits for card to complete write operation
       Uses delay or polling based on SD_DELAY_AFTER_WRITE setting

- `sd_seperator()`

      Description: Print separator line for debug output
       Outputs visual separator for debugging messages
      Parameters: None
      Returns: None
      Notes: Only prints if serial_data is defined
       Outputs "----" followed by carriage return/line feed

- `sd_print_response(volatile byte out device,byte in response)`

      Description: Print human-readable SD card R1 response byte
       Decodes and displays R1 response status flags
      Parameters:
       device   - Output device for printing (e.g., serial port)
       response - R1 response byte from SD card
      Returns: None
      Notes: Displays card status including idle state, errors, and ready status
       Used for debugging SD card communication

- `sd_check_crc_errors()`

      Description: Check for errors and update error statistics
       Increments error or success counters based on current error state
      Parameters: None
      Returns: None
      Notes: Does not print errors (commented out for performance)
       Updates sd_error_count if errors present
       Updates sd_success_count if no errors
       Can be uncommented to enable detailed error printing

- `sd_print_enhanced_statistics()`

      Description: Print SD card operation statistics
       Outputs detailed statistics about SD operations and errors
      Parameters: None
      Returns: None
      Notes: Only prints if serial_data is defined
       Displays total operations, success count, error count
       Shows error rate percentage
       Indicates if CRC checking is enabled

- `send_command(byte in command,dword in data, byte out response)`

      Description: Send a command to the SD card
       Transmits SD command with parameters and receives R1 response
      Parameters:
       command  - SD command number (0-63)
       data     - 32-bit command argument/parameter
       response - Returns R1 response byte from SD card
      Returns:
       response - R1 response byte (0x00 = success, other values indicate status/errors)
      Notes: Only handles commands with single R1 response
       Automatically calculates CRC7 if SD_USE_CRC is enabled
       For CMD0 and CMD8, uses hardcoded CRC values per SD specification

- `sd_enable()`

      Description: Enable the SD card for SPI communication
       Activates chip select and sends clock pulses to prepare SD card
      Parameters: None
      Returns: None
      Notes: This procedure must be called before any SD card operations
       Sends dummy bytes to ensure proper SPI timing

- `sd_toggle()`

      Description: Toggle SD card chip select (disable then enable)
       Performs a reset of the chip select line
      Parameters: None
      Returns: None
      Notes: Used to reset communication state with SD card
       Sends clock pulse between disable and enable operations

- `sd_reset_error_state()`

      Description: Reset SD card error flags
       Clears all error state for retry operations
      Parameters: None
      Returns: None
      Notes: Called before retry attempts to clear previous error state
       Resets both sd_has_error flag and sd_error_details bitmask

- `sd_print_error(volatile byte out device)`

      Description: Print human-readable SD card error messages
       Outputs all current error flags without clearing error state
      Parameters:
       device - Output device for printing (e.g., serial port)
      Returns: None
      Notes: Does NOT reset error status after printing
       Prints "NO ERROR" if no errors are present
       Multiple error messages may be printed if multiple errors occurred

- `sd_set_idle()`

      Description: Set SD card to idle state
       Stops any ongoing operations and resets card to idle
      Parameters: None
      Returns: None
      Notes: Sends multiple STOP_TRANSMISSION commands to ensure clean stop
       Call this to abort any active read or write operations
       Sends 16 stop commands to ensure card receives at least one

- `sd_print_sector_hex(volatile byte out device,word in bytes_per_line,dword in address)`

      Description: Print sector data in hexadecimal format
       Reads and outputs sector bytes as formatted hex values
      Parameters:
       device         - Output device for printing (e.g., serial port)
       bytes_per_line - Number of hex bytes per line (must divide evenly into 512)
       address        - Sector number to read and print
      Returns: None
      Notes: Outputs data in human-readable hex format with line breaks
       Each byte is displayed as two-digit hex value with space separator
       Useful for debugging and data inspection

- `sd_write_sector_address(dword in address)`

      Description: Write single sector at specified address
       Convenience function combining start, write, and stop operations
      Parameters:
       address - Sector number to write to
      Returns: None
      Notes: Sector data must be in sd_sector_buffer[0-511] before calling
       Automatically handles start and stop of write operation
       Equivalent to calling sd_start_write(), sd_write_sector(), sd_stop_write()
       Use for writing single sectors; for multiple sectors use manual control

- `sd_retry_operation(dword in sector_address, byte in operation_type)`

      Description: Retry failed SD card operation with automatic error recovery
       Attempts operation up to sd_max_retries times
      Parameters:
       sector_address   - Sector number for operation
       operation_type   - Type of operation (1=read, 2=write)
      Returns: None
      Notes: Automatically retries on failure up to configured maximum
       Resets error state before each retry attempt
       Tracks retry count in sd_retry_count variable
       Default maximum retries is 3 (configurable via sd_max_retries)

- `sd_read_pulse_byte(word in count1)`

      Description: Skip forward by reading and discarding bytes
       Advances read position without returning data
      Parameters:
       count1 - Number of bytes to skip
      Returns: None
      Notes: Reads bytes from SD card but discards the data
       Useful for seeking within current sector
       More efficient than reading into unused buffer

- `sd_read_sector_with_callback(word in chunk_size)`

      Description: Read sector in chunks using callback function
       Allows user-provided callback to handle data as it's read
      Parameters:
       chunk_size - Number of bytes per callback (must divide evenly into 512)
      Returns: None
      Notes: Callback function must read chunk_size bytes via spi_master
       User must implement storage_read_callback(word in chunk_size)
       Example: chunk_size of 64 calls callback 8 times (512/64)
       Useful for direct USB or serial streaming without buffering
       Only available if SD_READ_EXTRA_SPEED is enabled

- `sd_start_write(dword in address)`

      Description: Start writing multiple blocks to SD card
       Initiates multi-block write operation at specified sector
      Parameters:
       address - Sector number to start writing to
      Returns: None
      Notes: Do not interrupt write process by switching to another SPI component
       Must write complete sectors (512 bytes each)
       Must call sd_stop_write() when finished
       For standard capacity cards, converts sector address to byte address
       Resets internal byte and sector counters

- `sd_disable()`

      Description: Disable the SD card and release SPI bus
       Deactivates chip select and sends final clock pulse
      Parameters: None
      Returns: None
      Notes: Called after SD card operations are complete
       Releases the SD card from SPI communication

- `sd_write_to_sector_end(byte in input_byte)`

      Description: Fill remainder of current sector with specified byte
       Pads sector to 512 bytes with repeated byte value
      Parameters:
       input_byte - Byte value to use for padding
      Returns: None
      Notes: Data is not written to card until sector is complete
       Useful for partial sector writes
       Automatically sends CRC and waits for write completion
       Only writes if not at sector boundary (byte_count != 0)

- `sd_init()`

      Description: Initialize SD card for read/write operations
       Detects card type (Standard/High/Extended capacity) and prepares for use
      Parameters: None
      Returns: None
      Notes: Must be called before any SD card operations
       Detects SD card version (Spec 1 or Spec 2)
       Determines card capacity type (SDSC, SDHC, SDXC)
       Retrieves total sector count from card
       Sets SD_INIT_FAILURE error if initialization fails
       Initializes CRC system if SD_USE_CRC is enabled

- `sd_print_sector(volatile byte out device, dword in address)`

      Description: Print sector data to output device
       Reads and outputs raw sector bytes
      Parameters:
       device  - Output device for printing (e.g., serial port)
       address - Sector number to read and print
      Returns: None
      Notes: Outputs 512 bytes of raw binary data
       Useful for debugging or data inspection
       Data is sent directly without formatting

- `sd_write_pulse_byte(word in count1)`

      Description: Write zero bytes to SD card
       Advances write position by writing specified number of zeros
      Parameters:
       count1 - Number of zero bytes to write
      Returns: None
      Notes: Useful for padding or creating empty space in sectors
       More efficient than sd_write_pulse() (writes 1 byte per loop vs 2)
       Commonly used for sector padding operations

- `sd_read_sector()`

      Description: Read one complete 512-byte sector into buffer
       Reads entire sector from current position into sd_sector_buffer
      Parameters: None
      Returns: None
      Notes: Sector data is stored in sd_sector_buffer[0-511]
       Performs CRC16 validation if SD_USE_CRC is enabled
       Uses optimized unrolled loop if SD_READ_EXTRA_SPEED is enabled
       Sets SD_DATA_CRC_ERROR if CRC validation fails
       Automatically waits for data ready token before reading

- `sd_start_read(dword in address)`

      Description: Start reading multiple blocks from SD card
       Initiates multi-block read operation at specified sector
      Parameters:
       address - Sector number to start reading from
      Returns: None
      Notes: Do not interrupt read process by switching to another SPI component
       Must call sd_stop_read() when finished
       For standard capacity cards, converts sector address to byte address
       Resets internal byte and sector counters

- `sd_data_byte'put(byte in data_byte)`

      Description: Write one byte to SD card during multi-block write
       Pseudo-variable for sequential byte writing
      Parameters:
       data_byte - Byte value to write to SD card
      Returns: None
      Notes: Must be called after sd_start_write()
       Automatically handles sector boundaries and CRC bytes
       Sends start token at beginning of each sector
       Waits for write completion at end of each sector
       Increments internal byte counter

Private

- `_sd_read_512()`

      Description: Read 512 bytes from SD card into sector buffer (optimized, no CRC)
       High-speed unrolled loop for maximum read performance
      Parameters: None
      Returns: None
      Notes: Internal procedure - not intended for direct use by applications
       Reads directly into sd_sector_buffer
       Does not perform CRC validation
       Loop is fully unrolled for speed (512 individual SPI reads)
       Use sd_read_sector() for public API

- `_sd_write_512()`

      Description: Write 512 bytes from sector buffer to SD card (optimized, no CRC)
       High-speed unrolled loop for maximum write performance
      Parameters: None
      Returns: None
      Notes: Internal procedure - not intended for direct use by applications
       Writes from sd_sector_buffer to SD card
       Does not calculate or send CRC
       Loop is fully unrolled for speed (512 individual SPI writes)
       Use sd_write_sector() for public API

- `_sd_read_512_crc()`

  No documentation found

- `_sd_write_512_crc()`

  No documentation found

### Functions

- `sd_error'get() return word`

      Description: Read and clear SD card error flags
       Returns current error details and resets error state
      Parameters: None
      Returns:
       word - Bitmask of error codes that occurred
      Notes: This function clears the error state after reading
       Each bit represents a different error code
       Returns 0 if no errors occurred

- `sd_read_write_next_ready(byte in read_write) return byte`

      Description: Wait for SD card to be ready for next byte transfer
       Checks for data ready token at start of each sector
      Parameters:
       read_write - Operation type (SD_READ or SD_WRITE)
      Returns:
       1 - SD card is ready for next byte
       0 - Timeout waiting for ready signal
      Notes: Called automatically during multi-block operations
       Waits for 0xFE data token at beginning of each sector
       Sets SD_READ_ERROR or SD_WRITE_ERROR on timeout
       Timeout occurs after 10,000 polling attempts

- `sd_data_byte'get() return byte`

      Description: Read one byte from SD card during multi-block read
       Pseudo-variable for sequential byte reading
      Parameters: None
      Returns:
       byte - Data byte read from SD card
      Notes: Must be called after sd_start_read()
       Automatically handles sector boundaries and CRC bytes
       Increments internal byte counter
       Returns after setting error if read fails

- `sd_ready() return byte`

      Description: Check if SD card is ready after initialization
       Polls SD card using SEND_OP_COND command until ready or timeout
      Parameters: None
      Returns:
       1 - SD card is ready
       0 - SD card not ready (timeout occurred)
      Notes: Waits for SD card to complete power-up initialization
       Sets SD_TIMED_OUT error if card doesn't respond within timeout
       Maximum 100 polling attempts

- `sd_is_inserted() return bit`

      Description: Check if SD card is present and responsive
       Attempts to detect and initialize communication with SD card
      Parameters: None
      Returns:
       1 (TRUE)  - SD card detected and responding
       0 (FALSE) - SD card not found or not responding
      Notes: Sends GO_IDLE_STATE command and waits for valid response
       Clears any previous error flags before detection
       Tries up to 100 times with delays between attempts
       Sets SD_DEVICE_NOT_FOUND error if card doesn't respond

## Related samples

Here are the list of samples which use this library:

16f18857 | 16f18857_glcd_ili9341_fat32_sd_card.jal
18f26j50 | 18f26j50_sd_card.jal
18f26j50 | 18f26j50_fat32_sd_card.jal
18f27j53 | 18f27j53_sd_card_minix_demo.jal
18f27j53 | 18f27j53_sd_card_minix_read.jal
18f27j53 | 18f27j53_sd_card_minix_readi.jal
18f452 | 18f452_fat32_small_sd_card.jal
18f452 | 18f452_sd_card.jal
18f4525 | 18f4525_fat32_sd_card.jal
18f4525 | 18f4525_mp3_decoder_vs1053b_sd_card.jal
18f4525 | 18f4525_sd_card.jal
18f4525 | 18f4525_fat32_small_sd_card.jal
18f4550 | 18f4550_sd_card.jal
18f4550 | 18f4550_fat32_small_sd_card.jal
18f4620 | 18f4620_mp3_decoder_vs1053b_sd_card.jal
18f4620 | 18f4620_sd_card.jal
18f4620 | 18f4620_fat32_small_sd_card.jal
18f4620 | 18f4620_fat32_sd_card.jal
18f67j50 | 18f67j50_sd_card.jal
18f67j50 | 18f67j50_mp3_decoder_vs1053b_sd_card.jal
18f67j50 | 18f67j50_sd_card_crc.jal
18f67j50 | 18f67j50_usb_msd_sd_card.jal
18f67j50 | 18f67j50_fat32_usb_msd_sd_card.jal
18f67j50 | 18f67j50_fat32_sd_card.jal
18f67j50 | 18f67j50_fat32_small_sd_card.jal
18f67j60 | 18f67j60_fat32_sd_card.jal