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

examples/ek_ra8d2/hw_validated/hil/usb_selftest_fs_host/src/usb_selftest_fs_host_fatdisk.c More...

#include <stdint.h>
#include <string.h>
#include "usb_selftest_fs_host_steps.h"
#include "ra8_board_ek_ra8d2.h"
#include "ra8_err.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_selftest_fs_host_fatdisk.c:

Go to the source code of this file.

Functions

static void selftest_put16 (UCHAR *dst, uint16_t value)
 Write a 16-bit value little-endian into a byte buffer.
static void selftest_put32 (UCHAR *dst, uint32_t value)
 Write a 32-bit value little-endian into a byte buffer.
static void selftest_fat_fill_boot (UCHAR *out)
 Synthesize the FAT16 boot sector (MS FAT spec 1.03 sec 3.1).
static void selftest_fat_fill_fat (uint32_t fat_sector, UCHAR *out)
 Synthesize one FAT16 sector of the cluster chain.
static void selftest_fat_fill_root (uint32_t root_sector, UCHAR *out)
 Synthesize one root-directory sector.
static void selftest_fat_fill_sector (uint32_t lba, UCHAR *out)
 Synthesize one 512-byte sector of the read-only volume.
UINT selftest_msc_read (VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
 Storage media-read callback: synthesize sectors over MRAM.
UINT selftest_msc_write (VOID *storage, ULONG lun, UCHAR *data_pointer, ULONG number_blocks, ULONG lba, ULONG *media_status)
 Storage media-write callback: always rejects (write-protected).
UINT selftest_msc_status (VOID *storage, ULONG lun, ULONG media_id, ULONG *media_status)
 Storage media-status callback.
static UINT selftest_usbx_stack_up (void)
 Brings USBX system + FS device stack up.
static UINT selftest_msc_class_register (void)
 Registers the Mass-Storage class with the read-only MRAM LUN.
VOID selftest_device_worker (ULONG arg)
 Device-side worker: bring the HS device stack up, then park.

Variables

static UCHAR s_usbx_pool [k_selftest_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 [] = "SELFTEST MRAM RO"
static UCHAR s_msc_product_rev [] = "0001"
static const UCHAR s_fat_oem_name [8] = {'R', 'A', '8', 'D', '2', 'F', 'W', ' '}
 Boot-sector OEM name (8 bytes, space padded).
static const UCHAR s_fat_volume_label [11] = {'R', 'A', '8', 'D', '2', ' ', 'M', 'R', 'A', 'M', ' '}
 Volume label, 11 bytes space padded (also the root entry).
static const UCHAR s_fat_fs_type [8] = {'F', 'A', 'T', '1', '6', ' ', ' ', ' '}
 Filesystem-type tag, 8 bytes space padded.
static const UCHAR s_fat_file_name [11] = {'M', 'R', 'A', 'M', ' ', ' ', ' ', ' ', 'B', 'I', 'N'}
 8.3 directory name of the exposed file: "MRAM.BIN".
static volatile uint32_t s_dbg_read_calls
 Device-side media_read invocations.
static volatile uint32_t s_dbg_dev_state
 Device-side ux_slave_device_state sample (3 = CONFIGURED).
static volatile uint32_t s_dbg_ux_speed
 Device-side USBX negotiated speed (0 = HS, 1 = FS in UX terms).
static volatile uint32_t s_dbg_thr_runs
 Storage class thread ThreadX run-count (0 = never scheduled).
static volatile uint32_t s_dbg_thr_state
 Storage class thread ThreadX state (see tx_api TX_* states).
static volatile uint32_t s_dbg_state3_seen
 Times the device sampler observed UX_DEVICE_CONFIGURED.
static volatile uint32_t s_dbg_framework
 Current device framework pointer (HS vs FS array address).
static volatile uint32_t s_dbg_fw_len
 Current device framework length (32 = FS cfg, 42 = HS cfg).
static volatile uint32_t s_dbg_fw_fs_addr
 Address of the FS framework array (compare vs s_dbg_framework).
static volatile uint32_t s_dbg_fw_hs_addr
 Address of the HS framework array (compare vs s_dbg_framework).
static UCHAR s_device_framework_hs []
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_validated/hil/usb_selftest_fs_host/src/usb_selftest_fs_host_fatdisk.c

Device role: synthesized read-only FAT16 MRAM disk + USBX bring-up.

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

The DEVICE half of the USB self-loop config B example, split out of main.c. The board's USBHS controller exposes the 1 MiB MRAM window at 0x02000000 as a read-only synthesized FAT16 volume with one file MRAM.BIN. This unit owns:

  • the synthesized FAT16 layout (boot sector, FAT chain, root directory, data region copied straight out of MRAM);
  • the USBX Mass-Storage media callbacks (read / write / status);
  • the USBX system + device-stack + class bring-up;
  • the ThreadX device worker that attaches the HS device and parks.

The compile-time geometry and the cross-unit prototypes live in usb_selftest_fs_host_steps.h. The static data and helpers here stay private to this translation unit; only selftest_msc_read, selftest_msc_write, selftest_msc_status, and selftest_device_worker are referenced from main.c.

Author
Brighton Sikarskie
Date
2026-06-13
Since
0.1.0

Definition in file usb_selftest_fs_host_fatdisk.c.

Function Documentation

◆ selftest_device_worker()

VOID selftest_device_worker ( ULONG arg)

Device-side worker: bring the HS device stack up, then park.

Device-side worker: bring the FS device MSC stack up, then park.

USBX system + device stack + MSC class + DCD bridge on the USBHS controller, then DPRPU attach. The FS host downstream forces a full-speed link, so the stack serves the FS-fallback framework. USBX runs the SCSI/BBB state machine on its own class threads after this.

Parameters
[in]argThreadX entry argument (unused).
Precondition
tx_application_define created this thread.
USB-HS pins + UTMI PLL are up (main did both).
Postcondition
The HS device is attached and serviceable.
On any bring-up failure the thread exits (probes show where).
Note
Runs once; loops forever on success.
Since
0.1.0

Definition at line 761 of file usb_selftest_fs_host_fatdisk.c.

◆ selftest_fat_fill_boot()

void selftest_fat_fill_boot ( UCHAR * out)
static

Synthesize the FAT16 boot sector (MS FAT spec 1.03 sec 3.1).

BPB for the padded 4146-sector volume plus the 0x55AA signature; geometry constants in selftest_fat_geom_t.

Parameters
[out]outZeroed 512-byte sector buffer.
Precondition
out is zeroed.
Geometry constants describe a valid FAT16 volume.
Postcondition
out holds the BPB + 0x55AA signature.
No other state changes.
Note
Pure function.
Since
0.1.0

Definition at line 382 of file usb_selftest_fs_host_fatdisk.c.

References k_boot_drive_num, k_boot_ext_sig, k_boot_jmp0, k_boot_jmp1, k_boot_jmp2, k_boot_media, k_boot_num_heads, k_boot_sec_per_trk, k_boot_sig_hi, k_boot_sig_hi_off, k_boot_sig_lo, k_boot_sig_lo_off, k_boot_volume_id, k_bpb_off_bootsig, k_bpb_off_bps, k_bpb_off_drvnum, k_bpb_off_fatsz16, k_bpb_off_fstype, k_bpb_off_heads, k_bpb_off_jmp, k_bpb_off_label, k_bpb_off_media, k_bpb_off_nfats, k_bpb_off_oem, k_bpb_off_rootent, k_bpb_off_rsvd, k_bpb_off_spc, k_bpb_off_spt, k_bpb_off_totsec16, k_bpb_off_volid, k_fat_fat_sectors, k_fat_num_fats, k_fat_reserved_sectors, k_fat_root_entries, k_fat_total_sectors, k_selftest_block_size, memcpy(), s_fat_fs_type, s_fat_oem_name, s_fat_volume_label, selftest_put16(), and selftest_put32().

Referenced by selftest_fat_fill_sector().

◆ selftest_fat_fill_fat()

void selftest_fat_fill_fat ( uint32_t fat_sector,
UCHAR * out )
static

Synthesize one FAT16 sector of the cluster chain.

MRAM.BIN occupies clusters 2..2049 as one sequential chain (entry c -> c + 1, last entry -> end-of-chain). Entries 0/1 carry the media descriptor per the FAT spec; everything past the chain reads as free (0x0000).

Parameters
[in]fat_sectorIndex of the FAT sector (0-based).
[out]outZeroed 512-byte sector buffer.
Precondition
out is zeroed.
fat_sector is below k_fat_fat_sectors.
Postcondition
out holds 256 little-endian FAT16 entries.
No other state changes.
Note
Pure function.
Since
0.1.0

Definition at line 426 of file usb_selftest_fs_host_fatdisk.c.

References k_fat_entries_per_sec, k_fat_entry0, k_fat_eoc, k_fat_last_mram_clus, and selftest_put16().

Referenced by selftest_fat_fill_sector().

◆ selftest_fat_fill_root()

void selftest_fat_fill_root ( uint32_t root_sector,
UCHAR * out )
static

Synthesize one root-directory sector.

Sector 0 of the root carries two entries: the volume label and the read-only MRAM.BIN file (start cluster 2, size 1 MiB). Every other root sector is empty.

Parameters
[in]root_sectorIndex of the root sector (0-based).
[out]outZeroed 512-byte sector buffer.
Precondition
out is zeroed.
root_sector is below k_fat_root_sectors.
Postcondition
out holds the directory entries for that sector.
No other state changes.
Note
Pure function.
Since
0.1.0

Definition at line 465 of file usb_selftest_fs_host_fatdisk.c.

References k_dir_attr_read_only, k_dir_attr_volume, k_dir_entry_bytes, k_dir_name_bytes, k_dir_off_attr, k_dir_off_cluster_lo, k_dir_off_size, k_fat_first_cluster, k_mram_bytes, memcpy(), s_fat_file_name, s_fat_volume_label, selftest_put16(), and selftest_put32().

Referenced by selftest_fat_fill_sector().

◆ selftest_fat_fill_sector()

void selftest_fat_fill_sector ( uint32_t lba,
UCHAR * out )
static

Synthesize one 512-byte sector of the read-only volume.

Dispatches on the LBA: boot sector, FAT, root directory, or data region. Data sectors inside the MRAM.BIN chain are copied straight out of the 1 MiB MRAM window; padding clusters past the chain read as zeros.

Parameters
[in]lbaLogical block address inside the volume.
[out]out512-byte destination buffer.
Precondition
lba is below k_fat_total_sectors (caller-checked).
out has 512 writable bytes.
Postcondition
out holds the synthesized sector content.
No other state changes.
Note
Reads chip MRAM directly; no caching.
Since
0.1.0

Definition at line 500 of file usb_selftest_fs_host_fatdisk.c.

References k_fat_data_lba, k_fat_fat_lba, k_fat_first_cluster, k_fat_last_mram_clus, k_fat_root_lba, k_mram_base_addr, k_selftest_block_size, memcpy(), memset(), selftest_fat_fill_boot(), selftest_fat_fill_fat(), and selftest_fat_fill_root().

Referenced by selftest_msc_read().

◆ selftest_msc_class_register()

UINT selftest_msc_class_register ( void )
static

Registers the Mass-Storage class with the read-only MRAM LUN.

Single LUN, write-protected, FAT16 geometry from selftest_fat_geom_t, media callbacks above.

Returns
UINT UX_SUCCESS on success.
Return values
UX_SUCCESSClass registered.
Precondition
selftest_usbx_stack_up has succeeded.
Media read/write/status callbacks are defined.
Postcondition
MSC class bound to configuration 1, interface 0.
LUN0 advertises the read-only synthesized FAT16 volume.
Note
Not re-entrant.
Since
0.1.0

Definition at line 708 of file usb_selftest_fs_host_fatdisk.c.

References k_fat_total_sectors, k_selftest_block_size, memset(), s_msc_product_id, s_msc_product_rev, s_msc_vendor_id, selftest_msc_read(), selftest_msc_status(), and selftest_msc_write().

Referenced by selftest_device_worker().

◆ selftest_msc_read()

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

Storage media-read callback: synthesize sectors over MRAM.

Bound checks the request against the volume, then fills each block via selftest_fat_fill_sector. LED1 toggles per call so the self-loop traffic is visible on the board.

Parameters
[in,out]storageUSBX storage class instance (unused).
[in]lunLogical unit number (must be 0).
[out]data_pointerUSBX-owned destination buffer.
[in]number_blocksNumber of 512-byte blocks to produce.
[in]lbaStarting LBA.
[out]media_statusFilled with sense status word.
Returns
UX_SUCCESS if the request fits the volume; otherwise UX_ERROR with media_status set to ILLEGAL REQUEST.
Return values
UX_SUCCESSRead completed.
UX_ERROROut-of-range LBA / count.
Precondition
data_pointer and media_status are non-NULL (USBX guarantee).
lun is 0 (single-LUN device).
Postcondition
Either number_blocks * 512 bytes were synthesized or media_status is non-zero.
s_dbg_read_calls advanced.
Note
Called from the USBX storage class thread.
Since
0.1.0

Definition at line 557 of file usb_selftest_fs_host_fatdisk.c.

References k_fat_total_sectors, k_ra8_board_led1, k_scsi_asc_lba_out_of_range, k_scsi_ascq_none, k_scsi_sense_illegal_request, k_selftest_block_size, ra8_board_led_toggle(), s_dbg_read_calls, and selftest_fat_fill_sector().

◆ selftest_msc_status()

UINT selftest_msc_status ( VOID * storage,
ULONG lun,
ULONG media_id,
ULONG * media_status )

Storage media-status callback.

Always reports media-present.

The synthesized volume cannot go away; status is constant 0.

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 class instance is live.
Postcondition
*media_status is 0.
No other state changes.
Note
Synthesized volume; never reports media-not-present.
Since
0.1.0

Definition at line 645 of file usb_selftest_fs_host_fatdisk.c.

◆ selftest_msc_write()

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

Storage media-write callback: always rejects (write-protected).

The host side of this very app probes exactly this rejection (WRITE(10) must fail with DATA PROTECT and the transport must keep working afterwards).

Parameters
[in,out]storageUSBX storage class instance (unused).
[in]lunLogical unit number (unused).
[in]data_pointerUSBX-owned source buffer (unused).
[in]number_blocksNumber of blocks the host tried (unused).
[in]lbaStarting LBA (unused).
[out]media_statusFilled with DATA PROTECT sense.
Returns
Always UX_ERROR.
Return values
UX_ERRORThe medium is write-protected.
Precondition
media_status is non-NULL (USBX guarantee).
The LUN also reports write-protected via MODE SENSE.
Postcondition
*media_status carries the DATA PROTECT sense triple.
The MRAM window is untouched.
Note
Hosts honouring the MODE SENSE WP bit never call this.
Since
0.1.0

Definition at line 606 of file usb_selftest_fs_host_fatdisk.c.

References k_scsi_asc_write_protected, k_scsi_ascq_none, and k_scsi_sense_data_protect.

◆ selftest_put16()

void selftest_put16 ( UCHAR * dst,
uint16_t value )
static

Write a 16-bit value little-endian into a byte buffer.

Low byte first, high byte second, per the FAT on-disk layout.

Parameters
[out]dstDestination (2 bytes).
[in]valueValue to store.
Precondition
dst has 2 writable bytes.
None beyond the buffer contract.
Postcondition
dst[0] holds the low byte, dst[1] the high byte.
No other state changes.
Note
Pure function.
Since
0.1.0

Definition at line 338 of file usb_selftest_fs_host_fatdisk.c.

References k_byte_mask, and k_byte_shift.

Referenced by selftest_fat_fill_boot(), selftest_fat_fill_fat(), selftest_fat_fill_root(), and selftest_put32().

◆ selftest_put32()

void selftest_put32 ( UCHAR * dst,
uint32_t value )
static

Write a 32-bit value little-endian into a byte buffer.

Two selftest_put16 halves, low half-word first.

Parameters
[out]dstDestination (4 bytes).
[in]valueValue to store.
Precondition
dst has 4 writable bytes.
None beyond the buffer contract.
Postcondition
dst holds the four little-endian bytes of value.
No other state changes.
Note
Pure function.
Since
0.1.0

Definition at line 360 of file usb_selftest_fs_host_fatdisk.c.

References k_word_mask, k_word_shift, and selftest_put16().

Referenced by selftest_fat_fill_boot(), and selftest_fat_fill_root().

◆ selftest_usbx_stack_up()

UINT selftest_usbx_stack_up ( void )
static

Brings USBX system + FS device stack up.

One-shot USBX pool + device-stack initialization for the 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 675 of file usb_selftest_fs_host_fatdisk.c.

References k_selftest_usbx_pool_bytes, s_device_framework_fs, s_device_framework_hs, s_language_id_framework, s_string_framework, and s_usbx_pool.

Referenced by selftest_device_worker().

Variable Documentation

◆ s_dbg_dev_state

volatile uint32_t s_dbg_dev_state
static

Device-side ux_slave_device_state sample (3 = CONFIGURED).

Definition at line 85 of file usb_selftest_fs_host_fatdisk.c.

Referenced by demo_worker(), and selftest_device_worker().

◆ s_dbg_framework

volatile uint32_t s_dbg_framework
static

Current device framework pointer (HS vs FS array address).

Definition at line 95 of file usb_selftest_fs_host_fatdisk.c.

Referenced by demo_worker(), and selftest_device_worker().

◆ s_dbg_fw_fs_addr

volatile uint32_t s_dbg_fw_fs_addr
static

Address of the FS framework array (compare vs s_dbg_framework).

Definition at line 99 of file usb_selftest_fs_host_fatdisk.c.

Referenced by selftest_device_worker().

◆ s_dbg_fw_hs_addr

volatile uint32_t s_dbg_fw_hs_addr
static

Address of the HS framework array (compare vs s_dbg_framework).

Definition at line 101 of file usb_selftest_fs_host_fatdisk.c.

Referenced by selftest_device_worker().

◆ s_dbg_fw_len

volatile uint32_t s_dbg_fw_len
static

Current device framework length (32 = FS cfg, 42 = HS cfg).

Definition at line 97 of file usb_selftest_fs_host_fatdisk.c.

Referenced by demo_worker(), and selftest_device_worker().

◆ s_dbg_read_calls

volatile uint32_t s_dbg_read_calls
static

Device-side media_read invocations.

Definition at line 83 of file usb_selftest_fs_host_fatdisk.c.

◆ s_dbg_state3_seen

volatile uint32_t s_dbg_state3_seen
static

Times the device sampler observed UX_DEVICE_CONFIGURED.

Definition at line 93 of file usb_selftest_fs_host_fatdisk.c.

Referenced by demo_worker(), and selftest_device_worker().

◆ s_dbg_thr_runs

volatile uint32_t s_dbg_thr_runs
static

Storage class thread ThreadX run-count (0 = never scheduled).

Definition at line 89 of file usb_selftest_fs_host_fatdisk.c.

Referenced by demo_worker(), and selftest_device_worker().

◆ s_dbg_thr_state

volatile uint32_t s_dbg_thr_state
static

Storage class thread ThreadX state (see tx_api TX_* states).

Definition at line 91 of file usb_selftest_fs_host_fatdisk.c.

Referenced by demo_worker(), and selftest_device_worker().

◆ s_dbg_ux_speed

volatile uint32_t s_dbg_ux_speed
static

Device-side USBX negotiated speed (0 = HS, 1 = FS in UX terms).

Definition at line 87 of file usb_selftest_fs_host_fatdisk.c.

Referenced by demo_worker(), and selftest_device_worker().

◆ s_device_framework_fs

UCHAR s_device_framework_fs[]
static

Definition at line 185 of file usb_selftest_fs_host_fatdisk.c.

◆ s_device_framework_hs

UCHAR s_device_framework_hs[]
static

◆ s_fat_file_name

const UCHAR s_fat_file_name[11] = {'M', 'R', 'A', 'M', ' ', ' ', ' ', ' ', 'B', 'I', 'N'}
static

8.3 directory name of the exposed file: "MRAM.BIN".

Definition at line 76 of file usb_selftest_fs_host_fatdisk.c.

◆ s_fat_fs_type

const UCHAR s_fat_fs_type[8] = {'F', 'A', 'T', '1', '6', ' ', ' ', ' '}
static

Filesystem-type tag, 8 bytes space padded.

Definition at line 73 of file usb_selftest_fs_host_fatdisk.c.

◆ s_fat_oem_name

const UCHAR s_fat_oem_name[8] = {'R', 'A', '8', 'D', '2', 'F', 'W', ' '}
static

Boot-sector OEM name (8 bytes, space padded).

Definition at line 67 of file usb_selftest_fs_host_fatdisk.c.

◆ s_fat_volume_label

const UCHAR s_fat_volume_label[11] = {'R', 'A', '8', 'D', '2', ' ', 'M', 'R', 'A', 'M', ' '}
static

Volume label, 11 bytes space padded (also the root entry).

Definition at line 70 of file usb_selftest_fs_host_fatdisk.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 316 of file usb_selftest_fs_host_fatdisk.c.

◆ s_msc_product_id

UCHAR s_msc_product_id[] = "SELFTEST MRAM RO"
static

Definition at line 63 of file usb_selftest_fs_host_fatdisk.c.

◆ s_msc_product_rev

UCHAR s_msc_product_rev[] = "0001"
static

Definition at line 64 of file usb_selftest_fs_host_fatdisk.c.

◆ s_msc_vendor_id

UCHAR s_msc_vendor_id[] = "RA8D2 "
static

Definition at line 62 of file usb_selftest_fs_host_fatdisk.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 250 of file usb_selftest_fs_host_fatdisk.c.

◆ s_usbx_pool

UCHAR s_usbx_pool[k_selftest_usbx_pool_bytes]
static

USBX memory pool (USBX uses tx_byte_pool internally).

Since
0.1.0

Definition at line 59 of file usb_selftest_fs_host_fatdisk.c.