|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
FAT16 synthesis, OSPI pattern, MSC media callbacks + console helpers. More...
#include <stdint.h>#include <string.h>#include "ra8_board_ek_ra8d2.h"#include "ra8_err.h"#include "ra8_xspi.h"#include "usb_selftest_ospi_steps.h"#include "tx_api.h"#include "ux_api.h"#include "ux_device_class_storage.h"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. | |
| void | selftest_pattern_fill (uint32_t win_sector, UCHAR *out) |
| Compute the deterministic pattern for one window data 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 uint8_t | selftest_nibble_to_hex (uint32_t nibble) |
| Format one nibble (0..15) into an uppercase hex character. | |
| static uint32_t | selftest_str_len (const char *text) |
| Bounded ASCII string length (cap k_selftest_print_cap). | |
| static ra8_err_t | selftest_sci_write (const uint8_t *data, uint32_t len) |
| Push a literal block over SCI8 polled. | |
| ra8_err_t | selftest_print (const char *text) |
| Print a NUL-terminated ASCII string over the console. | |
| ra8_err_t | selftest_print_dec (uint32_t value) |
| Print a uint32_t as ASCII decimal. | |
| ra8_err_t | selftest_print_hex (uint32_t value, uint8_t digits) |
| Print a value as fixed-width uppercase hex. | |
| ra8_err_t | selftest_print_fail (const char *what, ra8_err_t err) |
| Print "FAIL <what> err=0xNNNNNNNN" on its own line. | |
Variables | |
| static volatile uint32_t | s_dbg_read_calls |
| Device-side media_read invocations. | |
| 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', ' ', 'O', 'S', 'P', 'I', ' '} |
| 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] = {'O', 'S', 'P', 'I', ' ', ' ', ' ', ' ', 'B', 'I', 'N'} |
| 8.3 directory name of the exposed file: "OSPI.BIN". | |
FAT16 synthesis, OSPI pattern, MSC media callbacks + console helpers.
Device-facing half of the OSPI USB self-loop app, split out of main.c so every translation unit stays under the file-size cap. Holds the synthesized read-only FAT16 volume (boot sector / FAT chain / root directory / data sectors pulled off the OSPI flash), the deterministic per-sector pattern the boot programmer and the host verifier both compute, the USBX Mass-Storage media read/write/status callbacks, and the polled SCI8 -> J-Link OB CDC console formatters. main.c registers the media callbacks; usb_selftest_ospi_host.c reuses the pattern + console formatters. The shared constants and the cross-TU prototypes live in usb_selftest_ospi_steps.h.
Definition in file usb_selftest_ospi_format.c.
|
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.
| [out] | out | Zeroed 512-byte sector buffer. |
out is zeroed. out holds the BPB + 0x55AA signature. Definition at line 128 of file usb_selftest_ospi_format.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().
|
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).
| [in] | fat_sector | Index of the FAT sector (0-based). |
| [out] | out | Zeroed 512-byte sector buffer. |
out is zeroed. fat_sector is below k_fat_fat_sectors. out holds 256 little-endian FAT16 entries. Definition at line 172 of file usb_selftest_ospi_format.c.
References k_fat_entries_per_sec, k_fat_entry0, k_fat_eoc, k_fat_last_data_clus, and selftest_put16().
Referenced by selftest_fat_fill_sector().
|
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.
| [in] | root_sector | Index of the root sector (0-based). |
| [out] | out | Zeroed 512-byte sector buffer. |
out is zeroed. root_sector is below k_fat_root_sectors. out holds the directory entries for that sector. Definition at line 211 of file usb_selftest_ospi_format.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_ospi_bytes, memcpy(), s_fat_file_name, s_fat_volume_label, selftest_put16(), and selftest_put32().
Referenced by selftest_fat_fill_sector().
|
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 are pulled straight off the OSPI flash with ra8_xspi_flash_read (the bytes the boot programmer wrote); padding clusters past the chain read as zeros. A flash read error leaves the zero-fill in place so the host sees a mismatch rather than stale data.
| [in] | lba | Logical block address inside the volume. |
| [out] | out | 512-byte destination buffer. |
lba is below k_fat_total_sectors (caller-checked). out has 512 writable bytes. out holds the synthesized sector content. Definition at line 257 of file usb_selftest_ospi_format.c.
References k_fat_data_lba, k_fat_fat_lba, k_fat_first_cluster, k_fat_last_data_clus, k_fat_root_lba, k_ospi_instance, k_ospi_test_offset, k_selftest_block_size, memset(), ra8_xspi_flash_read(), selftest_fat_fill_boot(), selftest_fat_fill_fat(), and selftest_fat_fill_root().
Referenced by 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 the FAT16 synthesizer. LED1 toggles per call so the self-loop traffic is visible on the board.
| [in,out] | storage | USBX storage class instance (unused). |
| [in] | lun | Logical unit number (must be 0). |
| [out] | data_pointer | USBX-owned destination buffer. |
| [in] | number_blocks | Number of 512-byte blocks to produce. |
| [in] | lba | Starting LBA. |
| [out] | media_status | Filled with sense status word. |
| UX_SUCCESS | Read completed. |
| UX_ERROR | Out-of-range LBA / count. |
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.
| [in,out] | storage | USBX storage class instance (unused). |
| [in] | lun | Logical unit number (must be 0). |
| [out] | data_pointer | USBX-owned destination buffer. |
| [in] | number_blocks | Number of 512-byte blocks to produce. |
| [in] | lba | Starting LBA. |
| [out] | media_status | Filled with sense status word. |
| UX_SUCCESS | Read completed. |
| UX_ERROR | Out-of-range LBA / count. |
Definition at line 288 of file usb_selftest_ospi_format.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, selftest_fat_fill_sector(), and selftest_fat_fill_sector().
Referenced by selftest_msc_class_register(), selftest_msc_class_register(), and selftest_msc_class_register().
Storage media-status callback.
Always reports media-present.
The synthesized volume cannot go away; status is constant 0.
| [in,out] | storage | USBX storage class instance (unused). |
| [in] | lun | Logical unit number (unused). |
| [in] | media_id | Media id (unused). |
| [out] | media_status | Filled with 0 (no fault). |
| UX_SUCCESS | Media is present and ready. |
Definition at line 330 of file usb_selftest_ospi_format.c.
Referenced by selftest_msc_class_register(), selftest_msc_class_register(), and selftest_msc_class_register().
| 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).
| [in,out] | storage | USBX storage class instance (unused). |
| [in] | lun | Logical unit number (unused). |
| [in] | data_pointer | USBX-owned source buffer (unused). |
| [in] | number_blocks | Number of blocks the host tried (unused). |
| [in] | lba | Starting LBA (unused). |
| [out] | media_status | Filled with DATA PROTECT sense. |
| UX_ERROR | The medium is write-protected. |
Definition at line 312 of file usb_selftest_ospi_format.c.
References k_scsi_asc_write_protected, k_scsi_ascq_none, and k_scsi_sense_data_protect.
Referenced by selftest_msc_class_register(), selftest_msc_class_register(), and selftest_msc_class_register().
|
static |
Format one nibble (0..15) into an uppercase hex character.
Standard '0'-'9' then 'A'-'F' mapping.
| [in] | nibble | 4-bit value. |
| '0' | For a zero nibble. |
Definition at line 361 of file usb_selftest_ospi_format.c.
References k_selftest_hex_digit_split.
Referenced by selftest_print_hex().
| void selftest_pattern_fill | ( | uint32_t | win_sector, |
| UCHAR * | out ) |
Compute the deterministic pattern for one window data sector.
Fills out with (win_sector * smul + i * imul + bias) per byte (see selftest_pattern_t). This is the single source of truth: the boot programmer writes it into OSPI and the host verifier recomputes it – so the host never reads the flash and there is no single-controller contention.
| [in] | win_sector | 0-based sector index within the OSPI window. |
| [out] | out | 512-byte destination buffer. |
out has 512 writable bytes. out holds the sector's pattern bytes. Definition at line 227 of file usb_selftest_ospi_format.c.
References k_ospi_pat_bias, k_ospi_pat_imul, k_ospi_pat_mask, k_ospi_pat_smul, and k_selftest_block_size.
Referenced by selftest_ospi_write_pattern(), and selftest_verify_ospi_raw().
|
nodiscard |
Print a NUL-terminated ASCII string over the console.
Length-bounded by the bounded string-length scan.
| [in] | text | String to print (CR/LF included by the caller). |
| k_ra8_ok | All bytes queued. |
text is non-NULL. text is NUL-terminated within k_selftest_print_cap bytes. Definition at line 423 of file usb_selftest_ospi_format.c.
Referenced by selftest_print_fail().
|
nodiscard |
Print a uint32_t as ASCII decimal.
Print an unsigned 32-bit value in decimal.
Digit-reversal into a bounded scratch buffer.
| [in] | value | Value to print. |
| k_ra8_ok | All bytes queued. |
Definition at line 428 of file usb_selftest_ospi_format.c.
Print "FAIL <what> err=0xNNNNNNNN" on its own line.
Print a "FAIL <what> err=0x..." diagnostic line.
One-line diagnostic; print errors inside are not recoverable anyway, so the first failing chunk's code is returned.
| [in] | what | Short description of the failed step. |
| [in] | err | Error code returned by the step. |
| k_ra8_ok | The diagnostic line is queued. |
what is NUL-terminated within the print cap. Definition at line 466 of file usb_selftest_ospi_format.c.
|
nodiscard |
Print a value as fixed-width uppercase hex.
Print the low digits hex nibbles of value (upper-case).
Width is clamped to 8 hex digits.
| [in] | value | Value to print. |
| [in] | digits | Hex digit count (4 for u16, 8 for u32). |
| k_ra8_ok | All bytes queued. |
digits is at most k_selftest_hex_chars_u32. Definition at line 452 of file usb_selftest_ospi_format.c.
Referenced by selftest_print_fail().
|
static |
Write a 16-bit value little-endian into a byte buffer.
Low byte first, high byte second, per the FAT on-disk layout.
| [out] | dst | Destination (2 bytes). |
| [in] | value | Value to store. |
dst has 2 writable bytes. Definition at line 84 of file usb_selftest_ospi_format.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().
|
static |
Write a 32-bit value little-endian into a byte buffer.
Two selftest_put16 halves, low half-word first.
| [out] | dst | Destination (4 bytes). |
| [in] | value | Value to store. |
dst has 4 writable bytes. dst holds the four little-endian bytes of value. Definition at line 106 of file usb_selftest_ospi_format.c.
References k_word_mask, k_word_shift, and selftest_put16().
Referenced by selftest_fat_fill_boot(), and selftest_fat_fill_root().
|
staticnodiscard |
Push a literal block over SCI8 polled.
Thin wrapper fixing the console channel.
| [in] | data | Buffer to send. |
| [in] | len | Byte count. |
| k_ra8_ok | All bytes queued. |
data is non-NULL; SCI8 init already ran. len excludes any NUL terminator. Definition at line 418 of file usb_selftest_ospi_format.c.
References ra8_board_uart_console_write().
Referenced by selftest_print(), selftest_print_dec(), and selftest_print_hex().
|
static |
Bounded ASCII string length (cap k_selftest_print_cap).
Linear scan with a hard upper bound.
| [in] | text | NUL-terminated string. |
| 0 | For an empty string. |
text is non-NULL. text points to readable storage of at least the returned length. Definition at line 387 of file usb_selftest_ospi_format.c.
References k_selftest_print_cap.
Referenced by selftest_print().
|
static |
Device-side media_read invocations.
Definition at line 46 of file usb_selftest_ospi_format.c.
|
static |
8.3 directory name of the exposed file: "OSPI.BIN".
Definition at line 62 of file usb_selftest_ospi_format.c.
|
static |
Filesystem-type tag, 8 bytes space padded.
Definition at line 59 of file usb_selftest_ospi_format.c.
|
static |
Boot-sector OEM name (8 bytes, space padded).
Definition at line 53 of file usb_selftest_ospi_format.c.
|
static |
Volume label, 11 bytes space padded (also the root entry).
Definition at line 56 of file usb_selftest_ospi_format.c.