CHGame 0.3.0
Libraries for the CHGame handheld
Loading...
Searching...
No Matches
sd Namespace Reference

The SD card's SPI-mode block driver (CHSd). More...

Typedefs

typedef void(* BlockFn) (const uint8_t *block, void *ctx)
 What stream() calls with each block, in order.
 

Functions

bool init ()
 Wakes the card and identifies it (SD v1, SDSC v2, SDHC/SDXC).
 
bool read (uint32_t lba, uint8_t *dst)
 Reads one 512-byte block (CMD17), polled at 12 MHz.
 
bool stream (uint32_t lba, uint32_t n, uint8_t *buf0, uint8_t *buf1, BlockFn fn, void *ctx)
 Reads n consecutive blocks with one multi-block read (CMD18), handing each to fn while the next one arrives.
 

Detailed Description

The SD card's SPI-mode block driver (CHSd).

Typedef Documentation

◆ BlockFn

typedef void(* sd::BlockFn) (const uint8_t *block, void *ctx)

What stream() calls with each block, in order.

It runs while the next block arrives by DMA, so it must keep off SPI1 and off the other of stream()'s two buffers, and must not read the card.

Parameters
blockthe block's 512 bytes (in buf0 or buf1), valid until the callback returns.
ctxthe ctx given to stream().

Function Documentation

◆ init()

bool sd::init ( )

Wakes the card and identifies it (SD v1, SDSC v2, SDHC/SDXC).

Runs at 187.5 kHz with the card's CS (PB11) low, then sets 12 MHz for read(). Takes up to about a second with a card that is slow to come ready; with no card it fails in about 15 ms (MISO is pulled up, so an empty slot reads 0xFF). Call it again after any failed read, or after the card may have been swapped.

Returns
true if a card answered and is ready; false: no card, or not one this can read.

◆ read()

bool sd::read ( uint32_t  lba,
uint8_t *  dst 
)

Reads one 512-byte block (CMD17), polled at 12 MHz.

About 0.5 ms of bytes plus the card's own access time (0.1-1 ms, up to ~0.8 s for a block's first read after power-up); ~1.5 ms in all is typical. The block's CRC is not checked.

Parameters
lbathe block number on the card (0 = the card's first block, whatever the card type).
dstwhere the 512 bytes go.
Returns
true if the block arrived; false: the card did not deliver (call init() before the next read).

◆ stream()

bool sd::stream ( uint32_t  lba,
uint32_t  n,
uint8_t *  buf0,
uint8_t *  buf1,
BlockFn  fn,
void *  ctx 
)

Reads n consecutive blocks with one multi-block read (CMD18), handing each to fn while the next one arrives.

For a sketch that reads a file over and over (CHStlView reads a whole model every frame). The blocks come at 24 MHz by DMA into buf0 and buf1 in turn while fn(block, ctx) works on the one before; fn gets each block once, in order. Costs about 0.6 ms of card latency per call plus 0.17 ms per block, against ~1.5 ms per block for read(). No CRC is checked (a block garbled on the wire reaches fn as it came). DMA1 channels 2 and 3 are borrowed and left off: CHGfx sets channel 3 up afresh for every flush. The games never call it, so it is not in their images.

Parameters
lbathe first block's number on the card.
nhow many blocks to read; 0 does nothing and returns true.
buf0a 512-byte buffer for the even blocks (0, 2, 4 ...).
buf1a 512-byte buffer for the odd blocks; not the same as buf0.
fncalled once per block, in order (see BlockFn).
ctxpassed to fn unchanged; may be nullptr.
Returns
true if every block was delivered; false: the card stopped delivering (call init() before the next read). Some of the blocks may have reached fn before the failure.