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

examples/ek_ra8d2/hw_pending/manual/usb_msc_sdcard/src/usb_msc_sdcard_steps.c More...

#include "usb_msc_sdcard_steps.h"
#include <stdint.h>
#include <string.h>
#include "ra8_board_ek_ra8d2.h"
#include "ra8_err.h"
#include "ra8_sdmmc_spi.h"
#include "ra8_usb.h"
#include "tx_api.h"
#include "ux_api.h"
#include "ux_dcd_ra8_usb.h"
#include "ux_device_class_storage.h"
#include "ux_device_stack.h"
Include dependency graph for usb_msc_sdcard_steps.c:

Go to the source code of this file.

Functions

static UINT sdmsc_msc_read (VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
 Storage media-read callback: stream blocks off the live SD card.
static UINT sdmsc_msc_write (VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
 Storage media-write callback: commit host data to the live SD card.
static UINT sdmsc_msc_status (VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)
 Storage media-status callback.
static UINT sdmsc_usbx_stack_up (void)
 Bring USBX system + device stack up with the MSC framework.
static UINT sdmsc_class_register (void)
 Register the Mass-Storage class with one writable live-SD LUN.
static ra8_err_t sdmsc_print_ready (void)
 Print the READY banner: "usb_msc_sdcard: USB MSC SDCARD READY ...".
VOID sdmsc_device_worker (ULONG arg)
 Device worker: bring the live-SD read/write MSC device up, then park.

Variables

static UCHAR s_usbx_pool [k_sdmsc_usbx_pool_bytes]
 USBX memory pool (USBX uses tx_byte_pool internally).
static UCHAR s_msc_vendor_id [] = "RA8D2 "
static UCHAR s_msc_product_id [] = "SDCARD LIVE RW "
static UCHAR s_msc_product_rev [] = "0001"
static volatile uint32_t s_dbg_dev_step
 Device worker progress: 1 stack, 2 class, 3 dcd, 4 attach, 5 parked.
static volatile uint32_t s_dbg_dev_err
 Device worker first failing return code (0 = none).
static volatile uint32_t s_dbg_read_calls
 media_read invocations (each is one CMD17/CMD18 streak).
static volatile uint32_t s_dbg_write_calls
 media_write invocations (each is one CMD24/CMD25 streak).
static volatile uint32_t s_dbg_read_blocks
 Total 512-B blocks served to the host by media_read.
static volatile uint32_t s_dbg_write_blocks
 Total 512-B blocks committed to the card by media_write.
static volatile uint32_t s_dbg_media_err
 First failing SD driver error on the media path (0 = none).
static UCHAR s_device_framework_fs []
static UCHAR s_string_framework []
 USBX string descriptor table (vendor / product / serial).
static UCHAR s_language_id_framework [] = {k_usb_langid_en_us_lo, k_usb_langid_en_us_hi}
 USBX language-id table – US English.

Detailed Description

examples/ek_ra8d2/hw_pending/manual/usb_msc_sdcard/src/usb_msc_sdcard_steps.c

USBX device worker + read/write MSC media callbacks for the live SD card

Tag
[Ring 6 / APP] {World: S}

Split out of main.c to keep every translation unit under the line-count cap. Holds the device-side bring-up (USBX system + device stack + a single WRITABLE Mass-Storage LUN + DCD attach) and the media callbacks that stream the live full-capacity Pmod2 SD card:

  • sdmsc_msc_read forwards each SCSI READ(10) run to ra8_sdmmc_spi_read_blocks – one CMD18 (READ_MULTIPLE_BLOCK) streak per run, CMD17 for single blocks.
  • sdmsc_msc_write forwards each WRITE(10) data chunk to ra8_sdmmc_spi_write_blocks – one CMD25 (WRITE_MULTIPLE_BLOCK) streak per chunk. The class hands runs of up to UX_SLAVE_CLASS_STORAGE_BUFFER_SIZE bytes (4096 = 8 blocks), so a host file copy passes through as back-to-back CMD25 streaks.

WRITE(10) routing: _ux_device_class_storage_write consults the LUN's ux_slave_class_storage_media_read_only_flag BEFORE touching the media callback – the read-only examples (usb_msc_mram, usb_selftest_microsd) set it UX_TRUE so the class itself answers DATA PROTECT and their media-write hooks never run. This app sets it UX_FALSE: MODE SENSE reports the medium writable (no WP bit) and the class streams the bulk-OUT data phase into sdmsc_msc_write. On UX_ERROR the class stalls the OUT endpoint, fails the CSW, and serves the sense triple this file stored in media_status through the host's next REQUEST SENSE.

The LUN geometry is latched from s_usb_msc_sdcard_blocks (the real card capacity read from the CSD in main.c); no snapshot volume is synthesized anywhere.

Author
Brighton Sikarskie
Date
2026-07-08
Since
0.1.0

Definition in file usb_msc_sdcard_steps.c.

Function Documentation

◆ sdmsc_class_register()

UINT sdmsc_class_register ( void )
static

Register the Mass-Storage class with one writable live-SD LUN.

Sets number_lun = 1 and fills LUN0 with the REAL card geometry: last_lba = s_usb_msc_sdcard_blocks - 1 (CSD-derived capacity, no snapshot), 512-byte blocks, removable, and – the write enable – media_read_only_flag = UX_FALSE so MODE SENSE omits the WP bit and the class routes WRITE(10) into sdmsc_msc_write.

Returns
UINT UX_SUCCESS on success.
Return values
UX_SUCCESSClass registered.
Precondition
sdmsc_usbx_stack_up has succeeded.
s_usb_msc_sdcard_blocks is non-zero (worker gated on it).
Postcondition
MSC class bound to configuration 1, interface 0, with 1 LUN.
GET_MAX_LUN will report 0.
Note
Not re-entrant.
Since
0.1.0

Definition at line 451 of file usb_msc_sdcard_steps.c.

References k_sdmsc_block_size, memset(), s_msc_product_id, s_msc_product_rev, s_msc_vendor_id, s_usb_msc_sdcard_blocks, sdmsc_msc_read(), sdmsc_msc_status(), and sdmsc_msc_write().

Referenced by sdmsc_device_worker().

◆ sdmsc_device_worker()

VOID sdmsc_device_worker ( ULONG arg)

Device worker: bring the live-SD read/write MSC device up, then park.

USBX system + device stack + MSC class (1 writable LUN sized from s_usb_msc_sdcard_blocks) + DCD bridge on the USBFS controller, then DPRPU attach and the READY banner. USBX runs the SCSI/BBB state machine on its own class threads after this; the media callbacks stream the live card via ra8_sdmmc_spi_read_blocks / ra8_sdmmc_spi_write_blocks.

Parameters
[in]argThreadX entry argument (unused).
Precondition
tx_application_define created this thread.
USB-FS pins + 48 MHz clock + the SD card are up (main did all three).
Postcondition
The FS device is attached and serviceable on its single LUN.
On any bring-up failure the thread prints the step and exits.
Note
Runs once; loops forever on success.
Since
0.1.0

Definition at line 516 of file usb_msc_sdcard_steps.c.

References k_ra8_err_invalid_state, k_ra8_ok, k_ra8_usb_speed_fs, k_sdmsc_dev_step_attach, k_sdmsc_dev_step_class, k_sdmsc_dev_step_dcd, k_sdmsc_dev_step_parked, k_sdmsc_dev_step_stack, k_sdmsc_idle_ticks, ra8_usb_device_attach(), s_dbg_dev_err, s_dbg_dev_step, s_usb_msc_sdcard_blocks, sdmsc_class_register(), sdmsc_print_fail(), sdmsc_print_ready(), sdmsc_usbx_stack_up(), tx_thread_sleep, and ux_dcd_ra8_usb_initialize().

Referenced by tx_application_define().

◆ sdmsc_msc_read()

UINT sdmsc_msc_read ( VOID * storage,
ULONG lun,
UCHAR * data_pointer,
ULONG number_blocks,
ULONG lba,
ULONG * media_status )
static

Storage media-read callback: stream blocks off the live SD card.

Bounds-checks the request against the card capacity, then hands the whole run to ra8_sdmmc_spi_read_blocks – a single CMD18 (READ_MULTIPLE_BLOCK) streak with per-block CRC16 verification, CMD17 for a one-block run. A driver failure reports MEDIUM ERROR / UNRECOVERED READ ERROR so the host retries or surfaces a read error instead of silently corrupting the mount. LED1 toggles per call so traffic is visible.

Parameters
[in,out]storageUSBX storage class instance (unused).
[in]lunLogical unit number (unused; single LUN).
[out]data_pointerUSBX-owned destination buffer.
[in]number_blocksNumber of 512-byte blocks to produce.
[in]lbaStarting LBA.
[out]media_statusFilled with the sense status word.
Returns
UX_SUCCESS when the card served the run; else UX_ERROR.
Return values
UX_SUCCESSBlocks read from the card.
UX_ERROROut-of-range LBA / count, or the card read failed.
Precondition
data_pointer / media_status are non-NULL (USBX guarantee).
ra8_sdmmc_spi_init succeeded at boot (worker gates on capacity).
Postcondition
Either the blocks were read or media_status carries the sense triple.
s_dbg_read_calls / s_dbg_read_blocks advanced.
Note
Called from the USBX storage class thread – the only SD-bus user after boot, so card access needs no extra locking.
Since
0.1.0

Definition at line 268 of file usb_msc_sdcard_steps.c.

References k_ra8_board_led1, k_ra8_ok, k_scsi_asc_lba_out_of_range, k_scsi_asc_unrecovered_read, k_scsi_ascq_none, k_scsi_sense_illegal_request, k_scsi_sense_medium_error, ra8_board_led_toggle(), ra8_sdmmc_spi_read_blocks(), s_dbg_media_err, s_dbg_read_blocks, s_dbg_read_calls, and s_usb_msc_sdcard_blocks.

Referenced by sdmsc_class_register().

◆ sdmsc_msc_status()

UINT sdmsc_msc_status ( VOID * storage,
ULONG lun,
ULONG media_id,
ULONG * media_status )
static

Storage media-status callback.

Reports the boot-probed card.

The card was brought up once at boot and the worker refuses to attach without it, so a live class instance always has its medium.

Parameters
[in,out]storageUSBX storage class instance (unused).
[in]lunLogical unit number (unused).
[in]media_idMedia id (unused).
[out]media_statusFilled with 0 (no fault).
Returns
Always UX_SUCCESS.
Return values
UX_SUCCESSMedia is present and ready.
Precondition
media_status is non-NULL (USBX guarantee).
The worker attached only after the card probe succeeded.
Postcondition
*media_status is 0.
No other state changes.
Note
Card hot-swap is not supported; power-cycle to change cards.
Since
0.1.0

Definition at line 386 of file usb_msc_sdcard_steps.c.

Referenced by sdmsc_class_register().

◆ sdmsc_msc_write()

UINT sdmsc_msc_write ( VOID * storage,
ULONG lun,
UCHAR * data_pointer,
ULONG number_blocks,
ULONG lba,
ULONG * media_status )
static

Storage media-write callback: commit host data to the live SD card.

The LUN is writable, so _ux_device_class_storage_write streams each WRITE(10) bulk-OUT chunk here after its own read-only-flag and transfer-length checks. Bounds-checks the run against the card capacity, then hands it to ra8_sdmmc_spi_write_blocks – one CMD25 (WRITE_MULTIPLE_BLOCK) streak per chunk (CMD24 for a one-block run), with the card's data-response token and busy handshake verified per block. On success the class advances its LBA cursor and continues the command; the CSW passes only after every chunk landed. A driver failure reports MEDIUM ERROR / PERIPHERAL DEVICE WRITE FAULT and fails the command so the host knows the sectors did NOT reach the medium. LED2 toggles per call.

Parameters
[in,out]storageUSBX storage class instance (unused).
[in]lunLogical unit number (unused; single LUN).
[in]data_pointerUSBX-owned source buffer (received OUT data).
[in]number_blocksNumber of 512-byte blocks in this chunk.
[in]lbaStarting LBA of this chunk.
[out]media_statusFilled with the sense status word.
Returns
UX_SUCCESS when the card accepted the run; else UX_ERROR.
Return values
UX_SUCCESSBlocks written to the card.
UX_ERROROut-of-range LBA / count, or the card write failed.
Precondition
data_pointer / media_status are non-NULL (USBX guarantee).
The OUT data phase delivered number_blocks * 512 bytes.
Postcondition
Either the card holds the sectors or media_status carries the triple.
s_dbg_write_calls / s_dbg_write_blocks advanced.
Note
Called from the USBX storage class thread – the only SD-bus user after boot, so card access needs no extra locking.
Since
0.1.0

Definition at line 333 of file usb_msc_sdcard_steps.c.

References k_ra8_board_led2, k_ra8_ok, k_scsi_asc_lba_out_of_range, k_scsi_asc_write_fault, k_scsi_ascq_none, k_scsi_sense_illegal_request, k_scsi_sense_medium_error, ra8_board_led_toggle(), ra8_sdmmc_spi_write_blocks(), s_dbg_media_err, s_dbg_write_blocks, s_dbg_write_calls, and s_usb_msc_sdcard_blocks.

Referenced by sdmsc_class_register().

◆ sdmsc_print_ready()

ra8_err_t sdmsc_print_ready ( void )
staticnodiscard

Print the READY banner: "usb_msc_sdcard: USB MSC SDCARD READY ...".

Streams the capacity so the bench log records what the host is about to mount.

Returns
ra8_err_t propagated from the SCI helpers.
Return values
k_ra8_okThe banner is queued.
Precondition
The DCD attach succeeded (DPRPU pulled up).
SCI8 init already ran.
Postcondition
One ASCII banner line is in the SCI8 TX FIFO.
No other state changes.
Note
Blocking polled TX.
Since
0.1.0

Definition at line 503 of file usb_msc_sdcard_steps.c.

References k_ra8_ok, s_usb_msc_sdcard_blocks, sdmsc_print(), and sdmsc_print_dec().

Referenced by sdmsc_device_worker().

◆ sdmsc_usbx_stack_up()

UINT sdmsc_usbx_stack_up ( void )
static

Bring USBX system + device stack up with the MSC framework.

One-shot USBX pool + device-stack init (FS-only framework).

Returns
UINT UX_SUCCESS on success.
Return values
UX_SUCCESSStack ready.
Precondition
File-scope pool reserved.
Thread context.
Postcondition
Device stack accepts class registrations.
On failure USBX state is undefined.
Note
Single-call; not idempotent.
Since
0.1.0

Definition at line 415 of file usb_msc_sdcard_steps.c.

References k_sdmsc_usbx_pool_bytes, s_device_framework_fs, s_language_id_framework, s_string_framework, and s_usbx_pool.

Referenced by sdmsc_device_worker().

Variable Documentation

◆ s_dbg_dev_err

volatile uint32_t s_dbg_dev_err
static

Device worker first failing return code (0 = none).

Definition at line 85 of file usb_msc_sdcard_steps.c.

◆ s_dbg_dev_step

volatile uint32_t s_dbg_dev_step
static

Device worker progress: 1 stack, 2 class, 3 dcd, 4 attach, 5 parked.

Definition at line 83 of file usb_msc_sdcard_steps.c.

◆ s_dbg_media_err

volatile uint32_t s_dbg_media_err
static

First failing SD driver error on the media path (0 = none).

Definition at line 95 of file usb_msc_sdcard_steps.c.

Referenced by sdmsc_msc_read(), and sdmsc_msc_write().

◆ s_dbg_read_blocks

volatile uint32_t s_dbg_read_blocks
static

Total 512-B blocks served to the host by media_read.

Definition at line 91 of file usb_msc_sdcard_steps.c.

Referenced by sdmsc_msc_read().

◆ s_dbg_read_calls

volatile uint32_t s_dbg_read_calls
static

media_read invocations (each is one CMD17/CMD18 streak).

Definition at line 87 of file usb_msc_sdcard_steps.c.

◆ s_dbg_write_blocks

volatile uint32_t s_dbg_write_blocks
static

Total 512-B blocks committed to the card by media_write.

Definition at line 93 of file usb_msc_sdcard_steps.c.

◆ s_dbg_write_calls

volatile uint32_t s_dbg_write_calls
static

media_write invocations (each is one CMD24/CMD25 streak).

Definition at line 89 of file usb_msc_sdcard_steps.c.

◆ s_device_framework_fs

UCHAR s_device_framework_fs[]
static

Definition at line 103 of file usb_msc_sdcard_steps.c.

◆ s_language_id_framework

UCHAR s_language_id_framework[] = {k_usb_langid_en_us_lo, k_usb_langid_en_us_hi}
static

USBX language-id table – US English.

Since
0.1.0

Definition at line 232 of file usb_msc_sdcard_steps.c.

◆ s_msc_product_id

UCHAR s_msc_product_id[] = "SDCARD LIVE RW "
static

Definition at line 75 of file usb_msc_sdcard_steps.c.

◆ s_msc_product_rev

UCHAR s_msc_product_rev[] = "0001"
static

Definition at line 76 of file usb_msc_sdcard_steps.c.

◆ s_msc_vendor_id

UCHAR s_msc_vendor_id[] = "RA8D2 "
static

Definition at line 74 of file usb_msc_sdcard_steps.c.

◆ s_string_framework

UCHAR s_string_framework[]
static

USBX string descriptor table (vendor / product / serial).

Each entry: 2 bytes lang-id, 1 byte string index, 1 byte length, then ASCII bytes.

Since
0.1.0

Definition at line 168 of file usb_msc_sdcard_steps.c.

◆ s_usbx_pool

UCHAR s_usbx_pool[k_sdmsc_usbx_pool_bytes]
static

USBX memory pool (USBX uses tx_byte_pool internally).

Since
0.1.0

Definition at line 71 of file usb_msc_sdcard_steps.c.