ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
ra8_sdcard.c File Reference

SD card driver implementation – SD Physical Layer state machine. More...

#include "ra8_sdcard.h"
#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_log.h"
#include "ra8_sdhi.h"
Include dependency graph for ra8_sdcard.c:

Go to the source code of this file.

Data Structures

struct  ra8_sdcard_state_t
 Internal per-driver state. More...

Enumerations

enum  sd_csd_field_t : uint32_t {
  k_sd_block_size_bytes = 512U ,
  k_sd_csd_struct_shift = 30U ,
  k_sd_rca_mask = 0xFFFFU ,
  k_sd_read_bl_mask = 0xFU ,
  k_sd_csize_v2_lo_mask = 0x0000003FUL ,
  k_sd_csize_v2_mid_mask = 0x0000FFFFUL ,
  k_sd_csize_v2_mask = 0x003FFFFFUL ,
  k_sd_csize_v1_shift = 10U ,
  k_sd_csize_v1_lo_shift = 22U ,
  k_sd_csize_v1_lo_mask = 0x000003FFUL ,
  k_sd_csize_v1_mask = 0xFFFU ,
  k_sd_csize_mult_shift = 7U ,
  k_sd_csize_mult_mask = 0x7U
}
 SD CSD register field masks, shifts and block size. More...
enum  ra8_sdcard_cmd_t : uint8_t {
  k_ra8_sdcard_cmd0_go_idle = 0U ,
  k_ra8_sdcard_cmd2_all_send_cid = 2U ,
  k_ra8_sdcard_cmd3_send_rca = 3U ,
  k_ra8_sdcard_cmd7_select_card = 7U ,
  k_ra8_sdcard_cmd8_send_if_cond = 8U ,
  k_ra8_sdcard_cmd9_send_csd = 9U ,
  k_ra8_sdcard_cmd55_app_cmd = 55U ,
  k_ra8_sdcard_acmd41_send_op_cond = 41U
}
 SD Physical Layer command indices used by ra8_sdcard_init. More...
enum  ra8_sdcard_proto_t : uint32_t {
  k_ra8_sdcard_cmd8_pattern = 0x000001AAUL ,
  k_ra8_sdcard_cmd8_pattern_mask = 0x00000FFFUL ,
  k_ra8_sdcard_acmd41_hcs = 0x40000000UL ,
  k_ra8_sdcard_acmd41_voltage_win = 0x00FF8000UL ,
  k_ra8_sdcard_ocr_busy_done_mask = 0x80000000UL ,
  k_ra8_sdcard_ocr_ccs_mask = 0x40000000UL ,
  k_ra8_sdcard_init_retry_max = 1000U ,
  k_ra8_sdcard_default_clk_div = 0x00000004UL
}
 SD protocol-level constants. More...
enum  ra8_sdcard_csd_t : uint32_t {
  k_ra8_sdcard_csd_v2_blocks_per_unit = 1024UL ,
  k_ra8_sdcard_sdhc_threshold_blocks = 4194304UL
}
 CSD register decoding constants. More...

Functions

static ra8_err_t internal_run_acmd41 (uint8_t instance, uint32_t *out_ocr)
static ra8_err_t internal_decode_csd (const uint32_t *rsp, uint32_t *out_blocks)
 Decode a CSD response (v1 or v2) into a capacity-in-blocks count.
static ra8_err_t internal_sdcard_identify (uint8_t instance)
 Drive CMD0 + CMD8 to take the card from power-on into idle.
static ra8_err_t internal_sdcard_publish_rca (uint8_t instance, uint16_t *out_rca)
 Run CMD2 + CMD3 so the card publishes its relative address.
static ra8_err_t internal_sdcard_publish_and_select (uint8_t instance, uint16_t *out_rca, uint32_t *out_blocks)
 Publish the RCA, decode the CSD, and put the card in TRAN.
static ra8_sdcard_card_type_t internal_classify (uint8_t high_capacity, uint32_t blocks)
 Classify card type from OCR.CCS and decoded block count.
static void internal_sdcard_negotiate_width (uint8_t instance, ra8_sdhi_bus_width_t width, uint16_t rca)
 Negotiate the requested SD data-bus width after card selection.
static ra8_err_t internal_sdcard_card_online (uint8_t instance, uint16_t *out_rca, uint32_t *out_blocks, uint8_t *out_high_capacity)
 Take an identified SDHI card from power-on to TRAN state.
ra8_err_t ra8_sdcard_init (const ra8_sdcard_cfg_t *cfg)
 Bring up the SDHI block and perform full SD card initialization.
static uint32_t internal_to_card_address (uint32_t lba)
 Translate a logical block address into the SD on-card argument.
ra8_err_t ra8_sdcard_read_blocks (uint32_t lba, uint8_t *buf, uint32_t count)
 Read count 512-byte blocks starting at lba.
ra8_err_t ra8_sdcard_write_blocks (uint32_t lba, const uint8_t *buf, uint32_t count)
 Write count 512-byte blocks starting at lba.
ra8_err_t ra8_sdcard_get_capacity (uint32_t *out_blocks)
 Return card capacity in 512-byte blocks.
ra8_err_t ra8_sdcard_get_type (ra8_sdcard_card_type_t *out_type)
 Return the detected card type (SDSC / SDHC / SDXC).
ra8_err_t ra8_sdcard_deinit (void)
 Tear down the card driver and release the SDHI block.

Variables

static const char * s_tag = "SDCARD"
 Module log tag.
static ra8_sdcard_state_t s_sdcard
 Module-private state.

Detailed Description

SD card driver implementation – SD Physical Layer state machine.

Tag
[Ring 3 / HAL] {World: NS}

Implements the SD Physical Layer initialization sequence on top of the lower-level ra8_sdhi register driver:

CMD0 -> CMD8 -> ACMD41 (loop) -> CMD2 -> CMD3 -> CMD9 -> CMD7

After the card is parked in TRAN state the bus clock is bumped from the 400 kHz identification rate to 25 MHz default-speed by way of ra8_sdhi_set_clock. Block I/O calls fall through to the polled ra8_sdhi_read_block / ra8_sdhi_write_block primitives.

The CSD register is decoded for both v1 (SDSC byte-addressed) and v2 (SDHC/SDXC block-addressed) layouts. Capacity is normalized to 512-byte blocks regardless of card class so callers always speak in sector counts.

Every SDHI register access cites HUM Ch 47 "SD/MMC Host Interface (SDHI)" (HUM pages 3122-3179). SD command numbers and response formats follow the SD Physical Layer Specification v6.00 – HUM Ch 47.1 "Overview" pins SDHI to that document directly.

Definition in file ra8_sdcard.c.

Enumeration Type Documentation

◆ ra8_sdcard_cmd_t

enum ra8_sdcard_cmd_t : uint8_t

SD Physical Layer command indices used by ra8_sdcard_init.

Matches the SD Physical Layer Specification v6.00, Table 4-24 "Card commands". Values are bare command indices; SDHI infers the response type and data direction from the index for the standard commands used here.

Enumerator
k_ra8_sdcard_cmd0_go_idle 

CMD0 GO_IDLE_STATE.

k_ra8_sdcard_cmd2_all_send_cid 

CMD2 ALL_SEND_CID.

k_ra8_sdcard_cmd3_send_rca 

CMD3 SEND_RELATIVE_ADDR.

k_ra8_sdcard_cmd7_select_card 

CMD7 SELECT_CARD.

k_ra8_sdcard_cmd8_send_if_cond 

CMD8 SEND_IF_COND.

k_ra8_sdcard_cmd9_send_csd 

CMD9 SEND_CSD.

k_ra8_sdcard_cmd55_app_cmd 

CMD55 APP_CMD prefix.

k_ra8_sdcard_acmd41_send_op_cond 

ACMD41 SD_SEND_OP_COND.

Definition at line 73 of file ra8_sdcard.c.

◆ ra8_sdcard_csd_t

enum ra8_sdcard_csd_t : uint32_t

CSD register decoding constants.

SD CSD layout (Section 5.3 of the Physical Layer Spec):

  • CSD_STRUCTURE lives in CSD[127:126] (top 2 bits of word [3]).
  • V2 (SDHC/SDXC): C_SIZE in CSD[69:48] (22 bits), capacity = (C_SIZE + 1) * 1024 blocks of 512 bytes (i.e. 512 KiB units).
  • V1 (SDSC): C_SIZE in CSD[73:62] (12 bits), C_SIZE_MULT in CSD[49:47] (3 bits), READ_BL_LEN in CSD[83:80] (4 bits); capacity in bytes = (C_SIZE+1) * 2^(C_SIZE_MULT+2) * 2^READ_BL_LEN.

The SDHI hardware drops the 8-bit CRC and 1-bit end bit, so what shows up in out_rsp[0..3] is bits [127:8] left-shifted by 8. The decoder below expects that 120-bit format – matching FSP r_sdhi_csd_extract.

Enumerator
k_ra8_sdcard_csd_v2_blocks_per_unit 

512 KiB / 512 B

k_ra8_sdcard_sdhc_threshold_blocks 

2 GiB / 512 B = SDXC boundary

Definition at line 123 of file ra8_sdcard.c.

◆ ra8_sdcard_proto_t

enum ra8_sdcard_proto_t : uint32_t

SD protocol-level constants.

Magic numbers from the SD Physical Layer Specification v6.00. The CMD8 check-pattern is fixed at 0xAA and the voltage-supplied field is set to b0001 ("2.7-3.6 V") – the only voltage range the host supports.

Enumerator
k_ra8_sdcard_cmd8_pattern 

VHS=0001, check=0xAA.

k_ra8_sdcard_cmd8_pattern_mask 

low 12 bits echoed

k_ra8_sdcard_acmd41_hcs 

HCS bit – request HC support.

k_ra8_sdcard_acmd41_voltage_win 

OCR voltage window 2.7-3.6 V.

k_ra8_sdcard_ocr_busy_done_mask 

OCR.busy clears when ready.

k_ra8_sdcard_ocr_ccs_mask 

OCR.CCS = 1 -> SDHC/SDXC.

k_ra8_sdcard_init_retry_max 

ACMD41 retry budget.

k_ra8_sdcard_default_clk_div 

CLKSEL=4 -> 25 MHz at 200 MHz PCLKB.

Definition at line 94 of file ra8_sdcard.c.

◆ sd_csd_field_t

enum sd_csd_field_t : uint32_t

SD CSD register field masks, shifts and block size.

Enumerator
k_sd_block_size_bytes 

SD logical block size.

k_sd_csd_struct_shift 

CSD_STRUCTURE field shift.

k_sd_rca_mask 

Relative card address (16-bit).

k_sd_read_bl_mask 

READ_BL_LEN (4-bit).

k_sd_csize_v2_lo_mask 

CSD v2 C_SIZE byte-2 bits.

k_sd_csize_v2_mid_mask 

CSD v2 C_SIZE byte-1 bits.

k_sd_csize_v2_mask 

CSD v2 C_SIZE (22-bit).

k_sd_csize_v1_shift 

CSD v1 C_SIZE high-bit shift.

k_sd_csize_v1_lo_shift 

CSD v1 C_SIZE low-bit shift.

k_sd_csize_v1_lo_mask 

CSD v1 C_SIZE low 10 bits.

k_sd_csize_v1_mask 

CSD v1 C_SIZE (12-bit).

k_sd_csize_mult_shift 

C_SIZE_MULT shift.

k_sd_csize_mult_mask 

C_SIZE_MULT (3-bit).

Definition at line 47 of file ra8_sdcard.c.

Function Documentation

◆ internal_classify()

ra8_sdcard_card_type_t internal_classify ( uint8_t high_capacity,
uint32_t blocks )
static

Classify card type from OCR.CCS and decoded block count.

SDA marketing tiers: SDSC < 2 GiB (byte-addressed), SDHC up to 32 GiB, SDXC above. The exact cutover is fuzzy; treat anything above a generous 32 GB as SDXC and the rest as SDHC.

Parameters
[in]high_capacityNon-zero if OCR.CCS = 1.
[in]blocksCapacity in 512-byte blocks.
Returns
ra8_sdcard_card_type_t classification.
Return values
k_ra8_sdcard_type_sdschigh_capacity == 0 (byte-addressed card).
k_ra8_sdcard_type_sdhchigh_capacity != 0 and blocks <= 32 GiB threshold.
k_ra8_sdcard_type_sdxchigh_capacity != 0 and blocks > 32 GiB threshold.
Precondition
OCR has been validated by ACMD41.
blocks is the decoded CSD block count (512-byte units).
Postcondition
Return value is one of the three documented types.
No global or module-private state is mutated.
Note
Pure function; reentrant and ISR-safe.
Since
0.1.0

Definition at line 434 of file ra8_sdcard.c.

References k_ra8_sdcard_sdhc_threshold_blocks, k_ra8_sdcard_type_sdhc, k_ra8_sdcard_type_sdsc, and k_ra8_sdcard_type_sdxc.

Referenced by ra8_sdcard_init().

◆ internal_decode_csd()

ra8_err_t internal_decode_csd ( const uint32_t * rsp,
uint32_t * out_blocks )
static

Decode a CSD response (v1 or v2) into a capacity-in-blocks count.

Parameters
[in]rspCSD register contents from CMD9 (rsp[0..3]).
[out]out_blocksReceives the 512-byte block count.

The SDHI hardware strips the CRC + end bit, so each rsp word holds the 32-bit CSD slice already shifted to the standard layout. rsp[3] carries the high 32 bits; CSD_STRUCTURE sits at rsp[3][31:30].

Precondition
rsp is non-NULL.
out_blocks is non-NULL.
Postcondition
On v2 success *out_blocks = (C_SIZE + 1) * 1024.
Since
0.1.0
Returns
Result code or value; see implementation.
Return values
0Success or default value.
Postcondition
Side effects bounded to documented state.
Note
Not thread-safe unless documented otherwise.

Definition at line 212 of file ra8_sdcard.c.

References k_ra8_err_hw_init_failed, k_ra8_ok, k_ra8_sdcard_csd_v2_blocks_per_unit, k_sd_block_size_bytes, k_sd_csd_struct_shift, k_sd_csize_mult_mask, k_sd_csize_mult_shift, k_sd_csize_v1_lo_mask, k_sd_csize_v1_lo_shift, k_sd_csize_v1_mask, k_sd_csize_v1_shift, k_sd_csize_v2_lo_mask, k_sd_csize_v2_mask, k_sd_csize_v2_mid_mask, k_sd_read_bl_mask, RA8_CHECK_NULL_PTR, and s_tag.

Referenced by internal_sdcard_publish_and_select().

◆ internal_run_acmd41()

◆ internal_sdcard_card_online()

ra8_err_t internal_sdcard_card_online ( uint8_t instance,
uint16_t * out_rca,
uint32_t * out_blocks,
uint8_t * out_high_capacity )
static

Take an identified SDHI card from power-on to TRAN state.

Brings up the SDHI module, then runs the SD Physical Layer chain: CMD0/CMD8 identification, the ACMD41 op-cond loop (capturing OCR.CCS), then CMD2/CMD3/CMD9/CMD7 to publish the RCA, decode the CSD, and select the card. On any failure after the module came up the SDHI module is deinit'd, so the caller simply propagates the error.

Parameters
[in]instanceSDHI instance index.
[out]out_rcaReceives the published relative address.
[out]out_blocksReceives capacity in 512-byte blocks.
[out]out_high_capacityReceives 1 when OCR.CCS = 1 (SDHC/SDXC).
Returns
ra8_err_t error code.
Return values
k_ra8_okCard parked in TRAN, outputs valid.
k_ra8_err_hw_init_failedIdentification / CSD decode failed.
Precondition
The SDHI module for instance is not yet initialized.
All three output pointers are non-NULL.
Postcondition
On success the card is in TRAN and every output is populated.
On error SDHI has been (or remained) deinitialized.
Note
Not thread-safe; single-threaded init context.
Since
0.1.0

Definition at line 512 of file ra8_sdcard.c.

References internal_run_acmd41(), internal_sdcard_identify(), internal_sdcard_publish_and_select(), k_ra8_ok, k_ra8_sdcard_ocr_ccs_mask, RA8_RETURN_ON_ERROR, ra8_sdhi_deinit(), ra8_sdhi_init(), and s_tag.

Referenced by ra8_sdcard_init().

◆ internal_sdcard_identify()

ra8_err_t internal_sdcard_identify ( uint8_t instance)
static

Drive CMD0 + CMD8 to take the card from power-on into idle.

HUM Ch 47.2.1 SD_CMD command sequence. CMD0 has no response but still drives the RSPEND handshake; CMD8 echoes the low 12 bits of the argument back through R7. Mismatch indicates a v1 (no-CMD8) card or no card present.

Parameters
[in]instanceSDHI instance index.
Returns
ra8_err_t error code.
Return values
k_ra8_okIdentification echo matched.
k_ra8_err_hw_init_failedCMD8 pattern mismatch.
Precondition
ra8_sdhi_init() succeeded for instance.
Single-threaded init context.
Postcondition
Card is in IDLE with v2 interface confirmed.
No host-side global state is modified.
Note
Not thread-safe.
Since
0.1.0

Definition at line 275 of file ra8_sdcard.c.

References k_ra8_err_hw_init_failed, k_ra8_ok, k_ra8_sdcard_cmd0_go_idle, k_ra8_sdcard_cmd8_pattern, k_ra8_sdcard_cmd8_pattern_mask, k_ra8_sdcard_cmd8_send_if_cond, RA8_RETURN_ON_ERROR, ra8_sdhi_send_command(), and s_tag.

Referenced by internal_sdcard_card_online().

◆ internal_sdcard_negotiate_width()

void internal_sdcard_negotiate_width ( uint8_t instance,
ra8_sdhi_bus_width_t width,
uint16_t rca )
static

Negotiate the requested SD data-bus width after card selection.

Only the SD 4-bit path is negotiable from the SD-card driver; 1-bit needs no action and any other request (including the eMMC-only 8-bit width) is treated as "stay 1-bit". Widening is a best-effort optimization: the card was already identified and selected at 1-bit, so ANY ACMD6 failure (a card that declines, or a bus timeout) simply falls back to the proven 1-bit mode and is logged – it never fails ra8_sdcard_init, which is why this returns void.

Parameters
[in]instanceSDHI instance index.
[in]widthRequested bus width from ra8_sdcard_cfg_t.
[in]rcaCard relative address published by CMD3.
Precondition
Card is in TRAN state with a valid rca.
ra8_sdhi_init has been called for instance.
Postcondition
On a clean ACMD6 the host SD_OPTION reflects the 4-bit width.
On any ACMD6 failure the host is left at the 1-bit default.
Note
Not thread-safe; single-threaded init context.
Since
0.1.0

Definition at line 471 of file ra8_sdcard.c.

References k_ra8_ok, k_ra8_sdhi_bus_width_4bit, ra8_log_info_val, ra8_sdhi_set_bus_width_4bit(), and s_tag.

Referenced by ra8_sdcard_init().

◆ internal_sdcard_publish_and_select()

ra8_err_t internal_sdcard_publish_and_select ( uint8_t instance,
uint16_t * out_rca,
uint32_t * out_blocks )
static

Publish the RCA, decode the CSD, and put the card in TRAN.

HUM Ch 47.2.5 response registers / SD Physical Layer Spec Section 4.7. Delegates CMD2/CMD3 to internal_sdcard_publish_rca, then runs CMD9 (CSD) and CMD7 with the published RCA to move the card into TRAN.

Parameters
[in]instanceSDHI instance index.
[out]out_rcaReceives the card's relative address.
[out]out_blocksReceives capacity in 512-byte blocks.
Returns
ra8_err_t error code.
Return values
k_ra8_okCard parked in TRAN.
k_ra8_err_hw_init_failedCSD decode rejected the layout.
Precondition
Card has cleared ACMD41 (ready state).
Both output pointers are non-NULL.
Postcondition
Card is in TRAN; *out_rca / *out_blocks populated.
On error the card may be in any state; caller deinits SDHI.
Note
Not thread-safe.
Since
0.1.0

Definition at line 376 of file ra8_sdcard.c.

References internal_decode_csd(), internal_sdcard_publish_rca(), k_ra8_ok, k_ra8_sdcard_cmd7_select_card, k_ra8_sdcard_cmd9_send_csd, RA8_RETURN_ON_ERROR, ra8_sdhi_send_command(), and s_tag.

Referenced by internal_sdcard_card_online().

◆ internal_sdcard_publish_rca()

ra8_err_t internal_sdcard_publish_rca ( uint8_t instance,
uint16_t * out_rca )
static

Run CMD2 + CMD3 so the card publishes its relative address.

SD Physical Layer Spec Section 4.2.2 identification flow: CMD2 ALL_SEND_CID broadcasts the 136-bit CID (which this host does not decode), then CMD3 SEND_RELATIVE_ADDR asks the card to publish the 16-bit RCA in rsp[0][31:16].

Parameters
[in]instanceSDHI instance index.
[out]out_rcaReceives the card-published relative address.
Returns
ra8_err_t error code.
Return values
k_ra8_okRCA published and captured.
Precondition
Card has cleared ACMD41 (ready state).
out_rca is non-NULL.
Postcondition
*out_rca holds the published RCA on success.
On error the card may be in any state; caller deinits SDHI.
Note
Not thread-safe.
Since
0.1.0

Definition at line 327 of file ra8_sdcard.c.

References k_ra8_ok, k_ra8_sdcard_cmd2_all_send_cid, k_ra8_sdcard_cmd3_send_rca, k_sd_rca_mask, RA8_RETURN_ON_ERROR, ra8_sdhi_send_command(), and s_tag.

Referenced by internal_sdcard_publish_and_select().

◆ internal_to_card_address()

uint32_t internal_to_card_address ( uint32_t lba)
static

Translate a logical block address into the SD on-card argument.

SDSC cards expect a byte address, SDHC/SDXC cards expect a block index. The host always speaks in block indices; this helper applies the byte-multiplication where it is needed.

Parameters
[in]lbaLogical block address.
Returns
Argument value to load into SD_ARG.
Since
0.1.0
Return values
0Success or default value.
Precondition
Module has been initialized.
Caller has validated arguments.
Postcondition
Side effects bounded to documented state.
State reflects operation result.
Note
Not thread-safe unless documented otherwise.

Definition at line 604 of file ra8_sdcard.c.

References k_ra8_sdcard_type_sdsc, k_sd_block_size_bytes, and s_sdcard.

Referenced by ra8_sdcard_read_blocks(), and ra8_sdcard_write_blocks().

◆ ra8_sdcard_deinit()

ra8_err_t ra8_sdcard_deinit ( void )
nodiscard

Tear down the card driver and release the SDHI block.

Resets the internal protocol state (capacity, RCA, type) and calls ra8_sdhi_deinit on the underlying instance. After this call ra8_sdcard_init may be invoked again.

Returns
ra8_err_t Error code.
Return values
k_ra8_okSuccess (or already-deinit no-op).
k_ra8_err_invalid_stateSDHI deinit failed.
Precondition
None.
Postcondition
Internal state is the same as before the first ra8_sdcard_init.
SDHI module is gated off (MSTP).
Since
0.1.0

Definition at line 664 of file ra8_sdcard.c.

References k_ra8_err_invalid_state, k_ra8_ok, k_ra8_sdcard_type_unknown, ra8_sdhi_deinit(), and s_sdcard.

◆ ra8_sdcard_get_capacity()

ra8_err_t ra8_sdcard_get_capacity ( uint32_t * out_blocks)
nodiscard

Return card capacity in 512-byte blocks.

Parameters
[out]out_blocksReceives the block count; non-NULL.
Returns
ra8_err_t Error code.
Return values
k_ra8_okSuccess.
k_ra8_err_null_ptrout_blocks was NULL.
k_ra8_err_invalid_stateCard never initialized.
Precondition
out_blocks is non-NULL.
ra8_sdcard_init has returned k_ra8_ok.
Postcondition
On success *out_blocks > 0.
Driver state unchanged.
Since
0.1.0

Definition at line 644 of file ra8_sdcard.c.

References k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_sdcard, and s_tag.

Referenced by internal_sdhi_get_caps(), and sdhi_card_check_capacity().

◆ ra8_sdcard_get_type()

ra8_err_t ra8_sdcard_get_type ( ra8_sdcard_card_type_t * out_type)
nodiscard

Return the detected card type (SDSC / SDHC / SDXC).

Parameters
[out]out_typeReceives the card type; non-NULL.
Returns
ra8_err_t Error code.
Return values
k_ra8_okSuccess.
k_ra8_err_null_ptrout_type was NULL.
k_ra8_err_invalid_stateCard never initialized.
Precondition
out_type is non-NULL.
ra8_sdcard_init has returned k_ra8_ok.
Postcondition
Driver state unchanged.
Since
0.1.0

Definition at line 654 of file ra8_sdcard.c.

References k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_sdcard, and s_tag.

◆ ra8_sdcard_init()

ra8_err_t ra8_sdcard_init ( const ra8_sdcard_cfg_t * cfg)
nodiscard

Bring up the SDHI block and perform full SD card initialization.

Runs the standard SD Physical Layer init sequence:

  1. ra8_sdhi_init – MSTP gate + soft-reset + 400 kHz clock
  2. CMD0 GO_IDLE_STATE
  3. CMD8 SEND_IF_COND (pattern 0x1AA, 2.7-3.6 V)
  4. ACMD41 with HCS=1 looped until OCR busy bit clears
  5. CMD2 ALL_SEND_CID
  6. CMD3 SEND_RELATIVE_ADDR – captures the card-assigned RCA
  7. CMD9 SEND_CSD – decodes capacity + speed class
  8. CMD7 SELECT_CARD – transitions card to TRAN state
  9. optional ACMD6 4-bit bus-width negotiation when cfg->bus_width requests it (best-effort; see ra8_sdcard_cfg_t)

ra8_sdhi_set_clock to 25 MHz default-speed

On success the internal state holds card type, RCA, and capacity in 512-byte blocks, and the SDHI block is ready for read_blocks / write_blocks traffic.

Parameters
[in]cfgNon-NULL configuration with a valid SDHI instance.
Returns
ra8_err_t Error code.
Return values
k_ra8_okCard initialized, ready for I/O.
k_ra8_err_null_ptrcfg was NULL.
k_ra8_err_invalid_argcfg->instance out of range.
k_ra8_err_invalid_stateAlready initialized (call ra8_sdcard_deinit first).
k_ra8_err_hw_timeoutA command never produced RSPEND.
k_ra8_err_hw_init_failedCMD8 echo / ACMD41 pattern mismatch.
Precondition
cfg is non-NULL and points to a fully populated config struct.
No other consumer is currently using the chosen SDHI instance.
Postcondition
On success ra8_sdcard_get_capacity returns a non-zero block count.
On success the SDHI bus clock is at default speed (25 MHz).
Note
Blocking, polled implementation; not safe to call from an ISR.
Example:
ra8_sdcard_cfg_t cfg = { .instance = 0U, .bus_width = k_ra8_sdhi_bus_width_4bit };
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Definition ra8_err.h:546
ra8_err_t ra8_sdcard_init(const ra8_sdcard_cfg_t *cfg)
Bring up the SDHI block and perform full SD card initialization.
Definition ra8_sdcard.c:544
@ k_ra8_sdhi_bus_width_4bit
Four data lanes (SD default-speed wide).
Definition ra8_sdhi.h:69
User-supplied configuration for ra8_sdcard_init.
Definition ra8_sdcard.h:88
See also
ra8_sdcard_read_blocks
ra8_sdcard_get_capacity
Since
0.1.0

Definition at line 544 of file ra8_sdcard.c.

References ra8_sdcard_cfg_t::bus_width, ra8_sdcard_cfg_t::instance, internal_classify(), internal_sdcard_card_online(), internal_sdcard_negotiate_width(), k_ra8_err_invalid_state, k_ra8_ok, k_ra8_sdcard_default_clk_div, RA8_CHECK_NULL_PTR, ra8_log_info_val, RA8_RETURN_ON_ERROR, ra8_sdhi_set_clock(), s_sdcard, and s_tag.

Referenced by internal_sdcard_thread_entry(), sdhi_card_init_or_halt(), and sdhi_demo_init_card_or_halt().

◆ ra8_sdcard_read_blocks()

ra8_err_t ra8_sdcard_read_blocks ( uint32_t lba,
uint8_t * buf,
uint32_t count )
nodiscard

Read count 512-byte blocks starting at lba.

Thin pass-through to ra8_sdhi_read_block once the card has been initialized. The lba argument is the logical block address as understood by the card – which means block address for SDHC/SDXC and byte address for SDSC. ra8_sdcard translates the SDSC case internally (lba * 512) so callers always pass block indices.

Parameters
[in]lbaLogical block address (sector number).
[out]bufDestination buffer; must hold count * 512 bytes.
[in]countNumber of 512-byte blocks; must be > 0.
Returns
ra8_err_t Error code.
Return values
k_ra8_okSuccess.
k_ra8_err_null_ptrbuf was NULL.
k_ra8_err_invalid_argcount was 0.
k_ra8_err_invalid_stateCard never initialized.
k_ra8_err_out_of_rangelba + count exceeds card capacity.
Precondition
ra8_sdcard_init has returned k_ra8_ok.
buf is non-NULL.
Postcondition
Buffer holds card data on success.
Card remains in TRAN state.
Note
Blocking, polled implementation; not safe to call from an ISR.
Since
0.1.0

Definition at line 612 of file ra8_sdcard.c.

References internal_to_card_address(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_out_of_range, RA8_CHECK_NULL_PTR, ra8_sdhi_read_block(), s_sdcard, and s_tag.

Referenced by internal_sdcard_one_pass(), internal_sdhi_read(), and sdhi_card_block_roundtrip().

◆ ra8_sdcard_write_blocks()

ra8_err_t ra8_sdcard_write_blocks ( uint32_t lba,
const uint8_t * buf,
uint32_t count )
nodiscard

Write count 512-byte blocks starting at lba.

Thin pass-through to ra8_sdhi_write_block. Same SDSC byte-address translation as ra8_sdcard_read_blocks. The driver does not perform pre-erase (ACMD23) or busy-poll the card after writes; the caller is expected to layer those on top if required.

Parameters
[in]lbaLogical block address.
[in]bufSource buffer; must hold count * 512 bytes.
[in]countNumber of 512-byte blocks; must be > 0.
Returns
ra8_err_t Error code (same as ra8_sdcard_read_blocks).
Precondition
ra8_sdcard_init has returned k_ra8_ok.
buf is non-NULL.
Postcondition
On success the requested block range was pushed to the card.
Card remains in TRAN state.
Since
0.1.0

Definition at line 628 of file ra8_sdcard.c.

References internal_to_card_address(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_out_of_range, RA8_CHECK_NULL_PTR, ra8_sdhi_write_block(), s_sdcard, and s_tag.

Referenced by internal_sdhi_write(), and sdhi_card_block_roundtrip().

Variable Documentation

◆ s_sdcard

◆ s_tag

const char* s_tag = "SDCARD"
static

Module log tag.

Definition at line 44 of file ra8_sdcard.c.