|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
SD card driver in SPI-mode – public block I/O and SCI factory. More...
#include <stdint.h>#include <string.h>#include "ra8_check.h"#include "ra8_err.h"#include "ra8_gpio_constants.h"#include "ra8_log.h"#include "ra8_port_utils.h"#include "ra8_sci_spi.h"#include "ra8_sdmmc_spi.h"#include "ra8_sdmmc_spi_internal.h"#include "ra8_sdmmc_spi_io_contracts_internal.h"#include "ra8_spi.h"Go to the source code of this file.
Data Structures | |
| struct | sci_bus_ctx_t |
| Bus context handed to the factory's transport callbacks. More... | |
Functions | |
| static ra8_err_t | internal_sci_transport_set_clock (void *ctx, uint32_t hz) |
| Factory transport set-clock shim: retune the SCI baud divider. | |
| static ra8_err_t | internal_sci_transport_cs (void *ctx, bool asserted) |
| Factory transport chip-select shim: drive CS low (asserted) or high. | |
| static ra8_err_t | internal_sci_transport_xfer (void *ctx, const uint8_t *tx, uint8_t *rx, uint32_t len) |
| Factory transport transfer shim: full-duplex byte exchange. | |
| static ra8_err_t | internal_sci_transport_bringup (uint8_t channel, uint32_t pclk_hz, const ra8_sdmmc_spi_sci_pins_t *pins) |
| Route the four Pmod SPI pins and bring up the SCI Simple-SPI channel. | |
| 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. | |
| static ra8_err_t | internal_prepare_init (const ra8_sdmmc_spi_transport_t *transport) |
| static ra8_err_t | internal_finalize_init (void) |
| 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. | |
| static uint32_t | internal_lba_to_arg (uint32_t lba) |
| static ra8_err_t | internal_cmd_require_ready (sd_cmd_t cmd, uint32_t arg) |
| static ra8_err_t | internal_erase_range (uint32_t lba, uint32_t count) |
| static ra8_err_t | internal_read_block_payload (uint8_t *buf) |
| static ra8_err_t | internal_read_block_crc_check (const uint8_t *buf) |
| static ra8_err_t | internal_read_data_phase (uint32_t lba, uint8_t *buf) |
| ra8_err_t | ra8_sdmmc_spi_read_block (uint32_t lba, uint8_t *buf) |
| Read one 512-byte block at logical block address lba. | |
| static ra8_err_t | internal_read_multi_stream (uint8_t *buf, uint32_t count) |
| static ra8_err_t | internal_read_multi_stop (void) |
| 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. | |
| static ra8_err_t | internal_write_data_block (const uint8_t *buf, uint8_t start_token) |
| 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. | |
| static ra8_err_t | internal_write_multi_stream (const uint8_t *buf, uint32_t count) |
| ra8_err_t | ra8_sdmmc_spi_write_blocks (uint32_t lba, const uint8_t *buf, uint32_t count) |
Write count contiguous 512-byte blocks with 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. | |
| static ra8_err_t | internal_fs_read_block (void *ctx, uint64_t lba, uint32_t count, uint8_t *buf) |
| static ra8_err_t | internal_fs_write_block (void *ctx, uint64_t lba, uint32_t count, const uint8_t *buf) |
| static ra8_err_t | internal_fs_erase_block (void *ctx, uint64_t lba, uint64_t count) |
| static ra8_err_t | internal_fs_get_capacity (void *ctx, uint64_t *block_count, uint32_t *block_size) |
| 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. | |
Variables | |
| static const char * | s_tag = "SDSPI" |
| Log tag for diagnostics emitted by this module. | |
| static sci_bus_ctx_t | s_sci_ctx |
| Single-shot bus context backing the factory's transport callbacks. | |
SD card driver in SPI-mode – public block I/O and SCI factory.
Block-level public API of the SPI-mode SD card driver declared in ra8_sdmmc_spi.h: init/deinit, single- and multi-block read/write, erase, capacity/type queries, the ra8_fs backend adapter, and the convenience SCI Simple-SPI transport factory (Pmod SD on EK-RA8D2).
The wire-level protocol primitives (CRC, command framing, the card identification sequence) live in the sibling translation unit ra8_sdmmc_spi.c; this unit reaches them through the module-private ra8_sdmmc_spi_internal.h surface. All data-token, data-response, and CRC behaviour follows SD Specification Part 1 Physical Layer Simplified Specification v9.10 section 7 ("SPI Mode").
Definition in file ra8_sdmmc_spi_io.c.
Definition at line 297 of file ra8_sdmmc_spi_io.c.
References k_ra8_err_protocol_error, k_ra8_ok, priv_sdmmc_spi_cs_assert(), priv_sdmmc_spi_cs_release(), priv_sdmmc_spi_send_command(), and RA8_INTERNAL.
Referenced by internal_erase_range().
|
static |
Definition at line 316 of file ra8_sdmmc_spi_io.c.
References internal_cmd_require_ready(), internal_lba_to_arg(), k_ra8_err_protocol_error, k_ra8_ok, k_sd_cmd_erase, k_sd_cmd_erase_wr_blk_end, k_sd_cmd_erase_wr_blk_start, k_sd_max_erase_poll_bytes, priv_sdmmc_spi_cs_assert(), priv_sdmmc_spi_cs_release(), priv_sdmmc_spi_send_command(), priv_sdmmc_spi_wait_not_busy_bounded(), and RA8_INTERNAL.
Referenced by ra8_sdmmc_spi_erase_blocks().
|
static |
Definition at line 255 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, k_ra8_ok, k_ra8_sdmmc_spi_clock_data_hz, and RA8_INTERNAL.
Referenced by ra8_sdmmc_spi_init().
|
static |
Definition at line 741 of file ra8_sdmmc_spi_io.c.
References k_ra8_err_out_of_range, RA8_INTERNAL, and ra8_sdmmc_spi_erase_blocks().
Referenced by ra8_sdmmc_spi_bind_fs_backend().
|
static |
Definition at line 753 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_ok, and k_ra8_sdmmc_spi_block_size.
|
static |
Definition at line 706 of file ra8_sdmmc_spi_io.c.
References k_ra8_err_null_ptr, k_ra8_err_out_of_range, and ra8_sdmmc_spi_read_blocks().
Referenced by ra8_sdmmc_spi_bind_fs_backend().
|
static |
Definition at line 725 of file ra8_sdmmc_spi_io.c.
References k_ra8_err_null_ptr, k_ra8_err_out_of_range, and ra8_sdmmc_spi_write_blocks().
Referenced by ra8_sdmmc_spi_bind_fs_backend().
|
static |
Definition at line 288 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, k_ra8_sdmmc_spi_block_size, k_ra8_sdmmc_spi_type_sdhc, and RA8_INTERNAL.
Referenced by internal_erase_range(), internal_read_data_phase(), ra8_sdmmc_spi_read_blocks(), ra8_sdmmc_spi_write_block(), and ra8_sdmmc_spi_write_blocks().
|
static |
Definition at line 241 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, k_ra8_err_invalid_state, k_ra8_sdmmc_spi_clock_init_hz, k_ra8_sdmmc_spi_type_unknown, RA8_INTERNAL, ra8_log_error, and s_tag.
Referenced by ra8_sdmmc_spi_init().
|
static |
Definition at line 361 of file ra8_sdmmc_spi_io.c.
References k_ra8_err_crc_mismatch, k_ra8_ok, k_ra8_sdmmc_spi_block_size, k_sd_bit_byte, k_sd_token_idle, priv_sdmmc_spi_xfer_one(), RA8_INTERNAL, and ra8_sdmmc_spi_crc16().
Referenced by internal_read_data_phase(), and internal_read_multi_stream().
|
static |
Definition at line 349 of file ra8_sdmmc_spi_io.c.
References k_ra8_ok, k_ra8_sdmmc_spi_block_size, k_sd_token_idle, priv_sdmmc_spi_xfer_one(), and RA8_INTERNAL.
Referenced by internal_read_data_phase(), and internal_read_multi_stream().
|
static |
Definition at line 376 of file ra8_sdmmc_spi_io.c.
References internal_lba_to_arg(), internal_read_block_crc_check(), internal_read_block_payload(), k_ra8_err_protocol_error, k_ra8_ok, k_sd_cmd_read_single_block, priv_sdmmc_spi_send_command(), priv_sdmmc_spi_wait_data_token(), and RA8_INTERNAL.
Referenced by ra8_sdmmc_spi_read_block().
|
static |
Definition at line 437 of file ra8_sdmmc_spi_io.c.
References k_ra8_err_protocol_error, k_ra8_ok, priv_sdmmc_spi_send_stop_transmission(), priv_sdmmc_spi_wait_not_busy(), and RA8_INTERNAL.
Referenced by ra8_sdmmc_spi_read_blocks().
|
static |
Definition at line 416 of file ra8_sdmmc_spi_io.c.
References internal_read_block_crc_check(), internal_read_block_payload(), k_ra8_ok, k_ra8_sdmmc_spi_block_size, priv_sdmmc_spi_wait_data_token(), and RA8_INTERNAL.
Referenced by ra8_sdmmc_spi_read_blocks().
|
static |
Route the four Pmod SPI pins and bring up the SCI Simple-SPI channel.
Muxes SCK/CIPO/COPI to the SCI async function, claims CS as a GPIO output held high, then initialises the SCI channel at the SD power-on clock. All HAL calls are reused (no register access here).
| [in] | channel | SCI channel index (0..9). |
| [in] | pclk_hz | PCLKA rate (Hz) feeding the baud divider; non-zero. |
| [in] | pins | Non-NULL SCK / CIPO / COPI / CS descriptor. |
| k_ra8_ok | Pins routed, CS claimed high, SCI channel up. |
| k_ra8_err_null_ptr | pins is NULL. |
| other | Propagated from ra8_pfs_route_peripheral / ra8_gpio_output_init / ra8_sci_spi_init. |
pclk_hz is the live PCLKA rate. pins are free (not routed to another peripheral). Definition at line 177 of file ra8_sdmmc_spi_io.c.
References ra8_sdmmc_spi_sci_pins_t::cipo, ra8_sdmmc_spi_sci_pins_t::copi, ra8_sdmmc_spi_sci_pins_t::cs, k_ra8_level_high, k_ra8_ok, k_ra8_psel_sci_async, k_ra8_sdmmc_spi_clock_init_hz, k_ra8_spi_mode_0, RA8_CHECK_NULL_PTR, ra8_gpio_output_init(), RA8_INTERNAL, ra8_pfs_route_peripheral(), ra8_sci_spi_init(), s_tag, and ra8_sdmmc_spi_sci_pins_t::sck.
Referenced by ra8_sdmmc_spi_transport_sci().
|
static |
Factory transport chip-select shim: drive CS low (asserted) or high.
Drives the chip-select GPIO from the bus context (active-low select); carries no register access of its own.
| [in] | ctx | Bus context (sci_bus_ctx_t*); must be non-NULL. |
| [in] | asserted | true to select (CS low), false to release (CS high). |
| k_ra8_ok | CS driven to the requested level. |
| k_ra8_err_null_ptr | ctx is NULL. |
ctx points to the live s_sci_ctx. asserted. Definition at line 123 of file ra8_sdmmc_spi_io.c.
References sci_bus_ctx_t::cs, k_ra8_level_high, k_ra8_level_low, RA8_CHECK_NULL_PTR, ra8_gpio_write(), RA8_INTERNAL, and s_tag.
Referenced by ra8_sdmmc_spi_transport_sci().
|
static |
Factory transport set-clock shim: retune the SCI baud divider.
Recovers the SCI channel + PCLKA from the bus context and forwards to ra8_sci_spi_set_clock; carries no register access of its own.
| [in] | ctx | Bus context (sci_bus_ctx_t*); must be non-NULL. |
| [in] | hz | Target SPI clock in Hz. |
| k_ra8_ok | Baud divider retuned. |
| k_ra8_err_null_ptr | ctx is NULL. |
ctx points to the live s_sci_ctx. hz. Definition at line 98 of file ra8_sdmmc_spi_io.c.
References sci_bus_ctx_t::channel, sci_bus_ctx_t::pclka_hz, RA8_CHECK_NULL_PTR, RA8_INTERNAL, ra8_sci_spi_set_clock(), and s_tag.
Referenced by ra8_sdmmc_spi_transport_sci().
|
static |
Factory transport transfer shim: full-duplex byte exchange.
Forwards a full-duplex byte exchange to the SCI channel from the bus context; carries no register access of its own.
| [in] | ctx | Bus context (sci_bus_ctx_t*); must be non-NULL. |
| [in] | tx | TX bytes, or NULL to shift idle 0xFF. |
| [out] | rx | RX buffer, or NULL to discard. |
| [in] | len | Byte count; must be > 0. |
| k_ra8_ok | len bytes clocked on the bus. |
| k_ra8_err_null_ptr | ctx is NULL. |
ctx points to the live s_sci_ctx. rx holds the received bytes when non-NULL. rx and the SCI data registers is modified. Definition at line 150 of file ra8_sdmmc_spi_io.c.
References sci_bus_ctx_t::channel, RA8_CHECK_NULL_PTR, ra8_sci_spi_xfer(), and s_tag.
Referenced by ra8_sdmmc_spi_transport_sci().
|
static |
Definition at line 489 of file ra8_sdmmc_spi_io.c.
References g_sdmmc_spi_state, k_ra8_err_protocol_error, k_ra8_ok, k_ra8_sdmmc_spi_block_size, k_sd_bit_byte, k_sd_data_response_accepted, k_sd_data_response_mask, k_sd_mask_byte, k_sd_token_idle, priv_sdmmc_spi_send_idle(), priv_sdmmc_spi_wait_not_busy(), priv_sdmmc_spi_xfer_one(), RA8_INTERNAL, and ra8_sdmmc_spi_crc16().
Referenced by internal_write_multi_stream(), and ra8_sdmmc_spi_write_block().
|
static |
Definition at line 557 of file ra8_sdmmc_spi_io.c.
References internal_write_data_block(), k_ra8_ok, k_ra8_sdmmc_spi_block_size, k_sd_token_data_start_multi, k_sd_token_stop_multi, priv_sdmmc_spi_send_idle(), priv_sdmmc_spi_wait_not_busy(), priv_sdmmc_spi_xfer_one(), and RA8_INTERNAL.
Referenced by ra8_sdmmc_spi_write_blocks().
|
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().
|
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 with one CMD25 transaction.
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().
|
static |
Single-shot bus context backing the factory's transport callbacks.
Definition at line 79 of file ra8_sdmmc_spi_io.c.
Referenced by ra8_sdmmc_spi_transport_sci().
|
static |
Log tag for diagnostics emitted by this module.
Definition at line 51 of file ra8_sdmmc_spi_io.c.