|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
SD card driver in SPI-mode (PMOD-attached cards). More...
Go to the source code of this file.
Data Structures | |
| struct | ra8_sdmmc_spi_transport_t |
| Driver-to-bus binding (Dependency Inversion seam). More... | |
| struct | ra8_sdmmc_spi_sci_pins_t |
| The four bus pins of an SCI Simple-SPI SD slot. More... | |
Typedefs | |
| typedef ra8_err_t(* | ra8_sdmmc_spi_set_clock_fn_t) (void *ctx, uint32_t hz) |
| Set the SPI clock frequency. | |
| typedef ra8_err_t(* | ra8_sdmmc_spi_cs_fn_t) (void *ctx, bool asserted) |
| Drive the chip-select line of the SD card. | |
| typedef ra8_err_t(* | ra8_sdmmc_spi_xfer_fn_t) (void *ctx, const uint8_t *tx, uint8_t *rx, uint32_t len) |
| Exchange len bytes full-duplex on the SPI bus. | |
Enumerations | |
| enum | ra8_sdmmc_spi_limits_t : uint16_t { k_ra8_sdmmc_spi_block_size = 512U , k_ra8_sdmmc_spi_cmd_frame_bytes = 6U , k_ra8_sdmmc_spi_csd_response_len = 16U } |
| Block-I/O size constants. More... | |
| enum | ra8_sdmmc_spi_clock_t : uint32_t { k_ra8_sdmmc_spi_clock_init_hz = 400000U , k_ra8_sdmmc_spi_clock_data_hz = 25000000U } |
| Canonical SPI clock rates used by ra8_sdmmc_spi_init. More... | |
| enum | ra8_sdmmc_spi_card_type_t : uint8_t { k_ra8_sdmmc_spi_type_unknown = 0U , k_ra8_sdmmc_spi_type_sdv1 = 1U , k_ra8_sdmmc_spi_type_sdv2 = 2U , k_ra8_sdmmc_spi_type_sdhc = 3U } |
| Detected SD card capacity / addressing class. More... | |
Functions | |
| ra8_err_t | ra8_sdmmc_spi_transport_sci (uint8_t sci_channel, uint32_t pclk_hz, const ra8_sdmmc_spi_sci_pins_t *pins, ra8_sdmmc_spi_transport_t *out) |
| Build the standard EK-RA8D2 SCI Simple-SPI transport for an SD card. | |
| ra8_err_t | ra8_sdmmc_spi_init (const ra8_sdmmc_spi_transport_t *transport) |
| Run the SD SPI-mode identification sequence on a card. | |
| ra8_err_t | ra8_sdmmc_spi_deinit (void) |
| Tear down the driver and release the transport binding. | |
| ra8_err_t | ra8_sdmmc_spi_read_block (uint32_t lba, uint8_t *buf) |
| Read one 512-byte block at logical block address lba. | |
| ra8_err_t | ra8_sdmmc_spi_read_blocks (uint32_t lba, uint8_t *buf, uint32_t count) |
Read count contiguous 512-byte blocks in one CMD18 transaction. | |
| ra8_err_t | ra8_sdmmc_spi_write_block (uint32_t lba, const uint8_t *buf) |
| Write one 512-byte block at logical block address lba. | |
| ra8_err_t | ra8_sdmmc_spi_write_blocks (uint32_t lba, const uint8_t *buf, uint32_t count) |
Write count contiguous 512-byte blocks in one CMD25 transaction. | |
| ra8_err_t | ra8_sdmmc_spi_erase_blocks (uint32_t lba, uint32_t count) |
Bulk-erase count blocks at lba, guaranteeing a zero read-back. | |
| ra8_err_t | ra8_sdmmc_spi_get_capacity (uint32_t *out_blocks) |
| Return the card capacity in 512-byte blocks. | |
| ra8_err_t | ra8_sdmmc_spi_get_card_type (ra8_sdmmc_spi_card_type_t *out_type) |
| Return the detected card type. | |
| ra8_err_t | ra8_sdmmc_spi_bind_fs_backend (ra8_fs_backend_t *out_backend) |
| Populate an ra8_fs_backend_t that mounts onto this SD driver. | |
| uint8_t | ra8_sdmmc_spi_crc7 (const uint8_t *data, uint32_t len) |
| Compute the SD-spec CRC7 over an arbitrary byte run. | |
| uint16_t | ra8_sdmmc_spi_crc16 (const uint8_t *data, uint32_t len) |
| Compute the SD-spec CRC16-CCITT over an arbitrary byte run. | |
SD card driver in SPI-mode (PMOD-attached cards).
SPI-mode SD/SDHC/SDXC card driver. The card sits on an SPI bus (RSPI / SPI_B or any compatible 8-bit full-duplex transport) and answers the standard SD command set wrapped in the SPI-mode framing defined in SD Specification Part 1 Physical Layer Simplified Specification v9.10 section 7 ("SPI Mode").
The driver is transport-agnostic. Callers wire it up by passing a ra8_sdmmc_spi_transport_t descriptor that holds three function pointers (clock-rate set, CS drive, full-duplex byte exchange). The host-side unit tests inject a mock transport; the firmware application binds the real ra8_spi HAL driver through a tiny adapter that lives in the example app.
Public API:
The block I/O API takes a logical block address. Inside the driver the address is converted to a byte address for SDSC cards (CMD17/24 argument is in bytes for v1.x cards) and left as a block address for SDHC / SDXC cards (CMD17/24 argument is in blocks for v2.x cards with the CCS bit set). Callers always speak in 512-byte blocks.
The driver also exposes a small ra8_fs_backend_t adapter (ra8_sdmmc_spi_bind_fs_backend) that plugs the SD card straight into the ra8_fs FAT filesystem layer without any extra glue in the application.
Definition in file ra8_sdmmc_spi.h.
| typedef ra8_err_t(* ra8_sdmmc_spi_cs_fn_t) (void *ctx, bool asserted) |
Drive the chip-select line of the SD card.
| [in] | ctx | Transport context cookie. |
| [in] | asserted | true to drive CS low (selected), false to release CS high. |
Definition at line 135 of file ra8_sdmmc_spi.h.
| typedef ra8_err_t(* ra8_sdmmc_spi_set_clock_fn_t) (void *ctx, uint32_t hz) |
Set the SPI clock frequency.
| [in] | ctx | Transport context cookie. |
| [in] | hz | Target clock rate in Hz. |
| k_ra8_ok | Clock applied. |
| k_ra8_err_invalid_arg | hz outside the transport's range. |
Definition at line 122 of file ra8_sdmmc_spi.h.
| typedef ra8_err_t(* ra8_sdmmc_spi_xfer_fn_t) (void *ctx, const uint8_t *tx, uint8_t *rx, uint32_t len) |
Exchange len bytes full-duplex on the SPI bus.
| [in] | ctx | Transport context cookie. |
| [in] | tx | TX buffer; if NULL the transport shall shift out 0xFF (idle pattern – SD spec PHY v9 section 7.2.4). |
| [out] | rx | RX buffer; if NULL the transport shall discard. |
| [in] | len | Number of bytes to exchange; must be > 0. |
Definition at line 150 of file ra8_sdmmc_spi.h.
| enum ra8_sdmmc_spi_card_type_t : uint8_t |
Detected SD card capacity / addressing class.
Definition at line 98 of file ra8_sdmmc_spi.h.
| enum ra8_sdmmc_spi_clock_t : uint32_t |
Canonical SPI clock rates used by ra8_sdmmc_spi_init.
The SD spec mandates the host opens the bus at 100-400 kHz for the identification sequence (CMD0 ... ACMD41 ... CMD58) and only then escalates to data-transfer speed (default-speed = 25 MHz, high-speed = 50 MHz). We pick 25 MHz as the default-speed target – it is the universal floor the v1.x and v2.x card families all support.
| Enumerator | |
|---|---|
| k_ra8_sdmmc_spi_clock_init_hz | Mandatory init clock floor. |
| k_ra8_sdmmc_spi_clock_data_hz | Default-speed data clock. |
Definition at line 89 of file ra8_sdmmc_spi.h.
| enum ra8_sdmmc_spi_limits_t : uint16_t |
Block-I/O size constants.
Definition at line 72 of file ra8_sdmmc_spi.h.
|
nodiscard |
Populate an ra8_fs_backend_t that mounts onto this SD driver.
Once ra8_sdmmc_spi_init has returned k_ra8_ok, the caller can invoke this helper to bind the SD card into the ra8_fs FAT layer:
The backend forwards read_block / write_block to the SD driver one block at a time and reports the capacity in 512-byte blocks. The ctx field is left NULL because the SD driver has a single global instance.
| [out] | out_backend | Populated backend descriptor; non-NULL. |
| k_ra8_ok | Backend populated. |
| k_ra8_err_null_ptr | out_backend is NULL. |
| k_ra8_err_invalid_state | Driver not initialized. |
Definition at line 767 of file ra8_sdmmc_spi_io.c.
References ra8_fs_backend_t::ctx, ra8_fs_backend_t::erase_blocks, g_sdmmc_spi_state, ra8_fs_backend_t::get_capacity, internal_fs_erase_block(), internal_fs_get_capacity(), internal_fs_read_block(), internal_fs_write_block(), k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_fs_backend_t::read_block, s_tag, and ra8_fs_backend_t::write_block.
Referenced by eoh_mount_or_halt(), etoc_mount_or_halt(), fs_fmt_run_exfat(), fs_fmt_run_one_type(), imp_mount_or_halt(), internal_mount(), internal_mount_sd(), internal_pc_mount_or_halt(), sd_demo_mount_or_halt(), and sh_sd_mount().
| uint16_t ra8_sdmmc_spi_crc16 | ( | const uint8_t * | data, |
| uint32_t | len ) |
Compute the SD-spec CRC16-CCITT over an arbitrary byte run.
Polynomial 0x1021 (x^16 + x^12 + x^5 + 1), seed 0x0000, as defined in SD spec PHY v9 section 4.5 "CRC16". The wire format is big-endian.
| [in] | data | Buffer to hash; non-NULL when len > 0. |
| [in] | len | Byte count; may be zero. |
| 0..0xFFFF | Computed CRC16. Returns 0 on NULL input. |
Definition at line 192 of file ra8_sdmmc_spi.c.
References k_sd_bit_byte, k_sd_crc16_msb_test, and k_sd_crc16_poly.
Referenced by internal_read_block_crc_check(), and internal_write_data_block().
| uint8_t ra8_sdmmc_spi_crc7 | ( | const uint8_t * | data, |
| uint32_t | len ) |
Compute the SD-spec CRC7 over an arbitrary byte run.
Polynomial 0x09 (x^7 + x^3 + 1), left-shifted, as defined in SD spec PHY v9 section 4.5 "CRC7". Used internally to seed every CMD frame's trailing CRC byte (the bottom bit of the CRC byte is the "end bit", always 1, so the wire value is (crc7 << 1) | 1U).
| [in] | data | Buffer to hash; non-NULL when len > 0. |
| [in] | len | Byte count; may be zero. |
| 0..0x7F | Computed CRC7. Returns 0 on NULL input. |
Definition at line 171 of file ra8_sdmmc_spi.c.
References k_sd_bit_byte, k_sd_crc7_byte_msb, k_sd_crc7_msb_test, k_sd_crc7_poly_low7, and k_sd_crc7_register_mask.
Referenced by internal_build_frame().
|
nodiscard |
Tear down the driver and release the transport binding.
| k_ra8_ok | Always (idempotent). |
Definition at line 279 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, k_ra8_ok, and k_ra8_sdmmc_spi_type_unknown.
|
nodiscard |
Bulk-erase count blocks at lba, guaranteeing a zero read-back.
The CMD32/CMD33/CMD38 erase sequence. The card erases the range internally in one operation – vastly faster than streaming zeros for a large region (e.g. the ~30 MB FAT of a 128 GB FAT32 card). The post-erase value is card-dependent (0x00 on some cards, 0xFF on others), and the SCR DATA_STAT_AFTER_ERASE bit's polarity is unreliable in practice, so this call probes: it erases only the first block, reads it back, and proceeds to erase the rest of the range only when that block is actually all-zero. A non-zero probe yields k_ra8_err_not_supported (the card erases to ones), letting the caller fall back to writing zeros without having wasted a full-region erase. A k_ra8_ok return is therefore a verified "this region now reads as all-zero bytes".
| [in] | lba | First LBA in 512-byte units. lba + count <= capacity. |
| [in] | count | Number of contiguous blocks to erase (>= 1). |
| k_ra8_ok | Range erased AND verified to read back as zero. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_invalid_arg | count is 0. |
| k_ra8_err_out_of_range | lba + count exceeds capacity. |
| k_ra8_err_not_supported | Card erases to a non-zero value (read-back != 0). |
| k_ra8_err_protocol_error | A command R1 was rejected. |
| k_ra8_err_hw_timeout | The post-erase busy wait timed out. |
Definition at line 637 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, internal_erase_range(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_not_supported, k_ra8_err_out_of_range, k_ra8_ok, k_ra8_sdmmc_spi_block_size, and ra8_sdmmc_spi_read_block().
Referenced by internal_fs_erase_block(), and internal_sdspi_erase().
|
nodiscard |
Return the card capacity in 512-byte blocks.
| [out] | out_blocks | Receives the block count; non-NULL. |
| k_ra8_ok | Success. |
| k_ra8_err_null_ptr | out_blocks is NULL. |
| k_ra8_err_invalid_state | Driver not initialized. |
Definition at line 679 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.
Referenced by internal_sdspi_get_caps(), microsd_sd_snapshot(), sd_demo_print_capacity(), and sdmsc_card_up().
|
nodiscard |
Return the detected card type.
| [out] | out_type | Receives the card type; non-NULL. |
| k_ra8_ok | Success. |
| k_ra8_err_null_ptr | out_type is NULL. |
| k_ra8_err_invalid_state | Driver not initialized. |
Definition at line 689 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, and s_tag.
|
nodiscard |
Run the SD SPI-mode identification sequence on a card.
Steps (SD spec PHY v9 section 7.2.1 "Mode Selection and Initialization"):
| [in] | transport | Non-NULL transport descriptor with all three function pointers populated. The struct is copied so the caller may free its storage on return. |
| k_ra8_ok | Card probed and ready. |
| k_ra8_err_null_ptr | transport or any callback is NULL. |
| k_ra8_err_invalid_state | Driver already initialized. |
| k_ra8_err_hw_timeout | CMD0 / ACMD41 never produced a response. |
| k_ra8_err_protocol_error | CMD8 echo mismatch, unexpected R1 bits. |
| k_ra8_err_crc_mismatch | CMD response CRC7 mismatch. |
| k_ra8_err_hw_init_failed | ACMD41 init loop exceeded retry budget. |
Definition at line 266 of file ra8_sdmmc_spi_io.c.
References internal_finalize_init(), internal_prepare_init(), k_ra8_ok, priv_sdmmc_spi_run_init_sequence(), priv_sdmmc_spi_validate_transport(), RA8_RETURN_ON_ERROR, and s_tag.
Referenced by eoh_init_card_or_halt(), etoc_init_card_or_halt(), fs_fmt_init_card_or_halt(), imp_init_card_or_halt(), internal_mount(), internal_mount_sd(), internal_pc_init_card_or_halt(), internal_sd_demo_init_card_or_halt(), microsd_sd_snapshot(), sd_demo_init_card_or_halt(), sdmsc_card_up(), and sh_sd_mount().
|
nodiscard |
Read one 512-byte block at logical block address lba.
Issues CMD17 (READ_SINGLE_BLOCK) with the appropriate byte/block address conversion for the detected card type. Waits for the data token (0xFE), drains 512 payload bytes, then drains the trailing 2-byte CRC16 (SD spec PHY v9 section 7.3.3.2 "Start Block Token"). The CRC16 is checked.
| [in] | lba | LBA in 512-byte units. Must satisfy lba < capacity. |
| [out] | buf | Destination buffer, exactly 512 bytes. |
| k_ra8_ok | Block read and CRC verified. |
| k_ra8_err_null_ptr | buf is NULL. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_out_of_range | lba >= capacity. |
| k_ra8_err_hw_timeout | Data token never arrived. |
| k_ra8_err_crc_mismatch | CRC16 mismatch on the payload. |
| k_ra8_err_protocol_error | Card returned non-zero R1. |
Definition at line 398 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, internal_read_data_phase(), k_ra8_err_invalid_state, k_ra8_err_out_of_range, priv_sdmmc_spi_cs_assert(), priv_sdmmc_spi_cs_release(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
Referenced by microsd_sd_snapshot(), ra8_sdmmc_spi_erase_blocks(), and ra8_sdmmc_spi_read_blocks().
|
nodiscard |
Read count contiguous 512-byte blocks in one CMD18 transaction.
The fast bulk-read path and the mirror of ra8_sdmmc_spi_write_blocks: a single READ_MULTIPLE_BLOCK (CMD18) command streams every block – data-start token (0xFE), 512 payload bytes, and a verified CRC16 trailer per block – and is terminated by CMD12 (STOP_TRANSMISSION). One command for the whole run instead of count CMD17 single-block reads. Falls back to ra8_sdmmc_spi_read_block when count == 1. On a mid-stream error (missing token, CRC mismatch, bus fault) CMD12 is still issued so the card leaves the data state before CS is released; the stream error takes precedence over any stop error.
| [in] | lba | First LBA in 512-byte units. lba + count <= capacity. |
| [out] | buf | Destination buffer of exactly count * 512 bytes. |
| [in] | count | Number of contiguous blocks to read (0 is a no-op). |
| k_ra8_ok | All blocks read and every CRC16 verified (also returned for the count == 0 no-op). |
| k_ra8_err_null_ptr | buf is NULL. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_out_of_range | lba + count exceeds capacity. |
| k_ra8_err_hw_timeout | A data token never arrived. |
| k_ra8_err_crc_mismatch | CRC16 mismatch on a block payload. |
| k_ra8_err_protocol_error | CMD18 or CMD12 returned non-zero R1. |
Definition at line 451 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, internal_lba_to_arg(), internal_read_multi_stop(), internal_read_multi_stream(), k_ra8_err_invalid_state, k_ra8_err_out_of_range, k_ra8_err_protocol_error, k_ra8_ok, k_sd_cmd_read_multi_block, priv_sdmmc_spi_cs_assert(), priv_sdmmc_spi_cs_release(), priv_sdmmc_spi_send_command(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, ra8_sdmmc_spi_read_block(), and s_tag.
Referenced by internal_fs_read_block(), internal_sdspi_read(), and sdmsc_msc_read().
|
nodiscard |
Build the standard EK-RA8D2 SCI Simple-SPI transport for an SD card.
One-line bring-up that gives SD-over-SPI the same ergonomics the SDHI host controller already has: instead of every app hand-writing the three set_clock / cs / xfer callbacks plus the pin routing, this factory does all of it and hands back a ready-to-use transport descriptor.
Concretely it:
pins->sck / cipo / copi to the SCI Simple-SPI function via ra8_pfs_route_peripheral (PSEL = SCI async) and claims pins->cs as a GPIO output held high (card deselected).The returned transport is then passed straight to ra8_sdmmc_spi_init:
The factory is an opt-in convenience: ra8_sdmmc_spi_init still accepts any caller-built ra8_sdmmc_spi_transport_t, so an app needing a custom bus (different SCI channel mux, bit-banged transport, mock) skips this helper and populates the descriptor itself.
| [in] | sci_channel | SCI channel index (0..9) wired to Simple-SPI mode. |
| [in] | pclk_hz | PCLKA rate (Hz) feeding the SCI baud divider; non-zero. |
| [in] | pins | Non-NULL SCK / CIPO / COPI / CS pin descriptor. |
| [out] | out | Non-NULL transport descriptor populated on success. |
| k_ra8_ok | Pins routed, SCI up, out populated. |
| k_ra8_err_null_ptr | pins or out is NULL. |
| k_ra8_err_invalid_arg | pclk_hz is 0. |
| other | Propagated from ra8_pfs_route_peripheral / ra8_gpio_output_init / ra8_sci_spi_init. |
pclk_hz is the live PCLKA rate. pins references four pins free for the SCI Simple-SPI mux. out carries non-NULL set_clock / cs / xfer pointers and a ctx cookie pointing at module-private bus state. Definition at line 208 of file ra8_sdmmc_spi_io.c.
References ra8_sdmmc_spi_sci_pins_t::cs, ra8_sdmmc_spi_transport_t::cs, ra8_sdmmc_spi_transport_t::ctx, internal_sci_transport_bringup(), internal_sci_transport_cs(), internal_sci_transport_set_clock(), internal_sci_transport_xfer(), k_ra8_err_invalid_arg, k_ra8_ok, RA8_CHECK_NULL_PTR, s_sci_ctx, s_tag, ra8_sdmmc_spi_transport_t::set_clock, and ra8_sdmmc_spi_transport_t::xfer.
Referenced by imp_init_card_or_halt(), internal_mount_sd(), internal_sd_demo_init_card_or_halt(), and sdmsc_card_up().
|
nodiscard |
Write one 512-byte block at logical block address lba.
Issues CMD24 (WRITE_BLOCK), sends the data-block token (0xFE), the 512 payload bytes, the 2-byte CRC16, then polls until the card de-asserts the busy-token (CIPO == 0xFF). The data-response token is checked for "data accepted" (xxx00101).
| [in] | lba | LBA in 512-byte units. Must satisfy lba < capacity. |
| [in] | buf | Source buffer, exactly 512 bytes. |
| k_ra8_ok | Block written and card became idle. |
| k_ra8_err_null_ptr | buf is NULL. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_out_of_range | lba >= capacity. |
| k_ra8_err_hw_timeout | Card never released busy. |
| k_ra8_err_protocol_error | Data-response token != "accepted". |
Definition at line 530 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, internal_lba_to_arg(), internal_write_data_block(), k_ra8_err_invalid_state, k_ra8_err_out_of_range, k_ra8_err_protocol_error, k_ra8_ok, k_sd_cmd_write_single_block, k_sd_token_data_start_single, priv_sdmmc_spi_cs_assert(), priv_sdmmc_spi_cs_release(), priv_sdmmc_spi_send_command(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, and s_tag.
Referenced by ra8_sdmmc_spi_write_blocks().
|
nodiscard |
Write count contiguous 512-byte blocks in one CMD25 transaction.
The fast bulk-write path: ACMD23 pre-erase hint (best-effort) plus a single WRITE_MULTIPLE_BLOCK streaming every block, terminated by the stop token. One command for the whole run instead of count CMD24 single-block writes – far faster for clearing a large region such as a multi-MB FAT during format. Falls back to ra8_sdmmc_spi_write_block when count == 1.
| [in] | lba | First LBA in 512-byte units. lba + count <= capacity. |
| [in] | buf | Source buffer of exactly count * 512 bytes. |
| [in] | count | Number of contiguous blocks to write (>= 1). |
| k_ra8_ok | All blocks written and the card became idle. |
| k_ra8_err_null_ptr | buf is NULL. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_out_of_range | lba + count exceeds capacity. |
| k_ra8_err_protocol_error | A command R1 or data-response token rejected. |
Write count contiguous 512-byte blocks in one CMD25 transaction.
The fast bulk-write path: an optional ACMD23 pre-erase hint, then a single WRITE_MULTIPLE_BLOCK (CMD25) streaming every block with the multi-block data-start token (0xFC), terminated by the stop-tran token (0xFD). One command for the whole run instead of count single-block CMD24 writes – the SD spec fast path for clearing a large region (e.g. a multi-MB FAT during format).
| [in] | lba | First logical block address. |
| [in] | buf | Source buffer of count * 512 bytes. |
| [in] | count | Number of contiguous blocks (>= 1). |
| k_ra8_ok | All count blocks were accepted and programmed. |
| k_ra8_err_null_ptr | buf is NULL. |
| k_ra8_err_invalid_state | The driver is not initialised. |
| k_ra8_err_out_of_range | lba + count exceeds the card capacity. |
| k_ra8_err_protocol_error | A command R1 or data-response token rejected. |
buf holds at least count * 512 bytes. Definition at line 604 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, internal_lba_to_arg(), internal_write_multi_stream(), k_ra8_err_invalid_state, k_ra8_err_out_of_range, k_ra8_err_protocol_error, k_ra8_ok, k_sd_acmd_set_wr_blk_erase_count, k_sd_cmd_write_multi_block, priv_sdmmc_spi_cs_assert(), priv_sdmmc_spi_cs_release(), priv_sdmmc_spi_send_acmd(), priv_sdmmc_spi_send_command(), RA8_CHECK_NULL_PTR, RA8_RETURN_ON_ERROR, ra8_sdmmc_spi_write_block(), and s_tag.
Referenced by internal_fs_write_block(), internal_sdspi_write(), and sdmsc_msc_write().