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

USB self-loop config B: FS host reads the HS device's MSC MRAM disk. More...

#include <stdint.h>
#include <string.h>
#include "ra8_board_ek_ra8d2.h"
#include "ra8_boot_entry.h"
#include "ra8_cgc.h"
#include "ra8_err.h"
#include "ra8_fs.h"
#include "ra8_gpio_constants.h"
#include "ra8_isr.h"
#include "ra8_port_constants.h"
#include "ra8_port_utils.h"
#include "ra8_time.h"
#include "ra8_usb.h"
#include "ra8_usb_hmsc.h"
#include "usb_selftest_fs_host_steps.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 main.c:

Go to the source code of this file.

Functions

void _tx_timer_interrupt (void)
void SysTick_Handler (void)
 Service the SysTick exception selected by the linked application.
VOID tx_application_define (VOID *first_unused_memory)
 ThreadX application-define hook.
static void selftest_panic_halt (void)
 Halt forever in WFI – panic stop on init failure.
static void selftest_route_usb_or_halt (void)
 Route both ports' pins: HS as device, FS as host (config B).
static void selftest_setup_or_halt (void)
 Bring CGC + both USB clocks + SysTick + SCI8 + LEDs + pins up.
void main (void)
 Application entry: bring the board up, then hand off to ThreadX.

Variables

static volatile bool s_tx_kernel_up = false
 Set in tx_application_define; gates ThreadX tick delivery.
static const ra8_port_pin_t k_selftest_pin_fs_vbus = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbus
 USBFS VBUS sense pin (P4_07, PSEL = 0x13).
static const ra8_port_pin_t k_selftest_pin_fs_vbusen = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbusen
 USBFS VBUSEN (P5_00) – peripheral-routed; the FS host controller sources J11 VBUS through it (config B host role).
static const ra8_port_pin_t k_selftest_pin_fs_dp = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dp
 USBFS D+ (P8_14).
static const ra8_port_pin_t k_selftest_pin_fs_dm = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dm
 USBFS D- (P8_15).
static const ra8_port_pin_t k_selftest_pin_hs_vbus = (ra8_port_pin_t)k_ra8_board_usbhs_pin_vbus
 USBHS_VBUS sense pin (P4_08, PSEL = 0x14).
static const ra8_port_pin_t k_selftest_pin_hs_role = (ra8_port_pin_t)k_ra8_board_usbhs_pin_pwr
 J7 role strap (PD07): LOW = Device, so U18 does not back-feed VBUS into the FS host's cable (config B device role, UM 6.2).
static TX_THREAD s_device_thread
 ThreadX TCB for the USBX device-side worker thread.
static UCHAR s_device_stack [k_selftest_thread_stack]
 Stack backing storage for s_device_thread.
static TX_THREAD s_host_thread
 ThreadX TCB for the polled host-side worker thread.
static UCHAR s_host_stack [k_selftest_host_stack]
 Stack backing storage for s_host_thread (ra8_fs walks live here).

Detailed Description

USB self-loop config B: FS host reads the HS device's MSC MRAM disk.

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

The role-flipped twin of usb_selftest_hs_host. The board's two USB ports are cabled to EACH OTHER and one firmware image runs BOTH sides of the link, with the host and device roles SWAPPED versus config A:

  • USBHS (J7) = DEVICE: the ThreadX + USBX Mass-Storage class from usb_msc_mram_hs, exposing the 1 MiB MRAM window at 0x02000000 as a read-only synthesized FAT16 volume with one file MRAM.BIN. IRQ-driven through the port/usbx/ux_dcd_ra8_usb bridge on the USBHS controller; it ships both the HS and the FS-fallback frameworks so it can serve a full-speed host.
  • USBFS (J11) = HOST: the polled first-party host stack from usb_host_file_ops (ra8_usb_hmsc + ra8_fs), running in a low-priority ThreadX thread. It enumerates the HS device over the cable, mounts the FAT16 volume, streams the data region back with raw multi-block READ(10), and memcmp's every burst against the SAME MRAM bytes read directly – a fully on-chip end-to-end proof that the USB transport returns the truth. A WRITE(10) into the read-only LUN must come back rejected.

The link runs at 12 Mbps: the FS host is the ceiling, so the HS device falls back to full speed (its FS framework, 64-byte bulk MPS) – the USBHS-device-at-full-speed path, which neither the Mac ladders (HS) nor config A (FS device) exercised.

Verdicts stream over SCI8 (J-Link OB CDC console, 115200) and are mirrored in J-Link-readable probes (s_dbg_*).

Pinout

HS device: P4_08 USBHS_VBUS sense (PSEL usb_hs), PD07 driven LOW (J7 role = Device, so U18 does not back-feed VBUS); D+/D- are dedicated PHY balls. FS host: P4_07 VBUS sense, P5_00 VBUSEN peripheral-routed (the USBFS controller sources J11 VBUS), P8_14 D+, P8_15 D- (PSEL usb_fs). Console: PD_02/PD_03 SCI8 (PSEL sci_async).

Author
Brighton Sikarskie
Date
2026-06-13
Since
0.1.0

Definition in file main.c.

Function Documentation

◆ _tx_timer_interrupt()

void _tx_timer_interrupt ( void )
extern

◆ main()

void main ( void )

Application entry: bring the board up, then hand off to ThreadX.

The application entry point Reset_Handler hands control to.

Both USB controllers' clocks and pins come up before the kernel so the two workers only deal with stack bring-up.

Precondition
Reset_Handler has copied .data and zeroed .bss.
SystemInit has set VTOR, FPU, and priority grouping.
Postcondition
On clean entry the CPU stays in tx_kernel_enter forever.
On any HAL init failure the function halts in WFI.
Note
Single entry point; not re-entrant.
Since
0.1.0

Definition at line 340 of file main.c.

References ra8_isr_globals_enable(), selftest_panic_halt(), and selftest_setup_or_halt().

◆ selftest_panic_halt()

void selftest_panic_halt ( void )
static

Halt forever in WFI – panic stop on init failure.

Last-resort stop; only a debugger or reset recovers.

Precondition
Called only after a fatal error in boot.
Interrupts may be in any state.
Postcondition
CPU is parked.
No further code runs.
Note
Not reachable post-boot.
Since
0.1.0

Definition at line 228 of file main.c.

◆ selftest_route_usb_or_halt()

void selftest_route_usb_or_halt ( void )
static

Route both ports' pins: HS as device, FS as host (config B).

HS device: P4_08 VBUS sense (PSEL usb_hs), PD07 driven LOW so J7's role is Device and U18 does not back-feed VBUS into the FS host's cable; D+/D- are dedicated PHY balls (no PFS routing). FS host: P4_07 VBUS sense, P5_00 VBUSEN peripheral-routed so the USBFS controller sources J11 VBUS, P8_14/P8_15 data – all PSEL usb_fs.

Precondition
IOPORT is reachable.
Called once from selftest_setup_or_halt.
Postcondition
HS pins carry the device role, FS pins the host role.
PD07 is LOW (J7 device, not self-powered).
Note
Panic-halts on any routing failure.
Since
0.1.0

Definition at line 252 of file main.c.

References k_ra8_level_low, k_ra8_ok, k_ra8_psel_usb_fs, k_ra8_psel_usb_hs, k_selftest_pin_fs_dm, k_selftest_pin_fs_dp, k_selftest_pin_fs_vbus, k_selftest_pin_fs_vbusen, k_selftest_pin_hs_role, k_selftest_pin_hs_vbus, ra8_gpio_output_init(), ra8_pfs_route_peripheral(), and selftest_panic_halt().

◆ selftest_setup_or_halt()

void selftest_setup_or_halt ( void )
static

Bring CGC + both USB clocks + SysTick + SCI8 + LEDs + pins up.

USBFS needs the 48 MHz PLL2 reference before MSTPB11 is released; USBHS needs its 60 MHz UTMI PLL. SCI8 is the J-Link OB CDC console at 115200.

Precondition
Reset_Handler has finished C runtime init.
SystemInit has run.
Postcondition
Console prints work; both USB ports' pins and clocks are live.
LED1/LED2 are initialized.
Note
Panic-halts on any failure; called exactly once from main.
Since
0.1.0

Definition at line 296 of file main.c.

References k_ra8_board_led1, k_ra8_board_led2, k_ra8_clock_id_cpuclk0, k_ra8_ok, k_selftest_baud, ra8_board_led_init(), ra8_board_uart_console_init(), ra8_cgc_get_clock_hz(), ra8_cgc_init(), ra8_cgc_usbfs_clock_enable(), ra8_cgc_usbhs_pll_enable(), ra8_time_init(), selftest_panic_halt(), and selftest_route_usb_or_halt().

◆ SysTick_Handler()

void SysTick_Handler ( void )

Service the SysTick exception selected by the linked application.

Service one SysTick event for the core timebase.

Service one SysTick event for the core timebase.

Resolves to the weak core timebase handler unless a strong RTOS or application handler overrides it. The vector table references the selected implementation without owning its subsystem policy.

Precondition
Entered for a SysTick exception with a valid exception frame.
The selected handler's timebase or scheduler state is initialised.
Postcondition
The selected implementation has processed one SysTick event.
The vector table itself remains unchanged.
Note
Runs in handler mode; thread-safety follows the selected implementation.
Since
0.1.0

The weak firmware implementation advances the millisecond counter, then services linked ThreadX and USB hooks when their weak symbols and readiness state permit. The host-test implementation advances only the counter. An application may replace either weak definition with a strong handler.

Precondition
The handler is entered for one SysTick event or a host-test equivalent.
On target, ra8_time_init() configured the SysTick period.
Postcondition
s_tick_ms has advanced by exactly one.
Optional subsystem hooks run only when linked and ready.
Note
IRQ-safe; the weak symbol may be overridden by an application handler.
Since
0.1.0

Service the SysTick exception selected by the linked application.

The weak firmware implementation advances the millisecond counter, then services linked ThreadX and USB hooks when their weak symbols and readiness state permit. The host-test implementation advances only the counter. An application may replace either weak definition with a strong handler.

Precondition
The handler is entered for one SysTick event or a host-test equivalent.
On target, ra8_time_init() configured the SysTick period.
Postcondition
s_tick_ms has advanced by exactly one.
Optional subsystem hooks run only when linked and ready.
Note
IRQ-safe; the weak symbol may be overridden by an application handler.
Since
0.1.0

Service the SysTick exception selected by the linked application.

Precondition
Called from exception context (IPSR == 15).
_tx_initialize_low_level has programmed SysTick.
Postcondition
One ThreadX tick elapsed; PendSV may be pending.

Definition at line 96 of file main.c.

References _tx_timer_interrupt(), ra8_time_on_tick(), s_tx_kernel_up, and ux_dcd_ra8_usb_irq_reenable().

◆ tx_application_define()

VOID tx_application_define ( VOID * first_unused_memory)

ThreadX application-define hook.

Spawns both workers.

Device worker at priority 8 (above USBX class threads' default), host worker at 16 so the polled host loop can never starve the IRQ-driven device side.

Parameters
[in]first_unused_memorySentinel (unused; static stacks).
Precondition
Called from tx_kernel_enter after scheduler init.
Postcondition
Two auto-start worker threads are queued.
Note
Called once at boot; not thread-safe.
Since
0.1.0

Definition at line 181 of file main.c.

References k_selftest_dev_priority, k_selftest_host_priority, k_selftest_host_stack, k_selftest_thread_stack, s_device_stack, s_device_thread, s_device_thread_name, s_host_stack, s_host_thread, s_host_thread_name, s_tx_kernel_up, selftest_device_worker(), selftest_host_worker(), TX_AUTO_START, TX_NO_TIME_SLICE, and tx_thread_create.

Variable Documentation

◆ k_selftest_pin_fs_dm

const ra8_port_pin_t k_selftest_pin_fs_dm = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dm
static

USBFS D- (P8_15).

Definition at line 121 of file main.c.

◆ k_selftest_pin_fs_dp

const ra8_port_pin_t k_selftest_pin_fs_dp = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dp
static

USBFS D+ (P8_14).

Definition at line 118 of file main.c.

◆ k_selftest_pin_fs_vbus

const ra8_port_pin_t k_selftest_pin_fs_vbus = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbus
static

USBFS VBUS sense pin (P4_07, PSEL = 0x13).

Definition at line 111 of file main.c.

◆ k_selftest_pin_fs_vbusen

const ra8_port_pin_t k_selftest_pin_fs_vbusen = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbusen
static

USBFS VBUSEN (P5_00) – peripheral-routed; the FS host controller sources J11 VBUS through it (config B host role).

Definition at line 115 of file main.c.

◆ k_selftest_pin_hs_role

const ra8_port_pin_t k_selftest_pin_hs_role = (ra8_port_pin_t)k_ra8_board_usbhs_pin_pwr
static

J7 role strap (PD07): LOW = Device, so U18 does not back-feed VBUS into the FS host's cable (config B device role, UM 6.2).

Definition at line 128 of file main.c.

Referenced by selftest_route_usb_or_halt().

◆ k_selftest_pin_hs_vbus

const ra8_port_pin_t k_selftest_pin_hs_vbus = (ra8_port_pin_t)k_ra8_board_usbhs_pin_vbus
static

USBHS_VBUS sense pin (P4_08, PSEL = 0x14).

Definition at line 124 of file main.c.

◆ s_device_stack

UCHAR s_device_stack[k_selftest_thread_stack]
static

Stack backing storage for s_device_thread.

Since
0.1.0

Definition at line 149 of file main.c.

◆ s_device_thread

TX_THREAD s_device_thread
static

ThreadX TCB for the USBX device-side worker thread.

Note
Single-writer (worker only).
Since
0.1.0

Definition at line 142 of file main.c.

◆ s_host_stack

UCHAR s_host_stack[k_selftest_host_stack]
static

Stack backing storage for s_host_thread (ra8_fs walks live here).

Since
0.1.0

Definition at line 164 of file main.c.

◆ s_host_thread

TX_THREAD s_host_thread
static

ThreadX TCB for the polled host-side worker thread.

Note
Single-writer (worker only).
Since
0.1.0

Definition at line 157 of file main.c.

◆ s_tx_kernel_up

volatile bool s_tx_kernel_up = false
static

Set in tx_application_define; gates ThreadX tick delivery.

main() starts SysTick (ra8_time_init) BEFORE tx_kernel_enter, and this app's setup window is long (the U15 expander I2C transaction blocks for milliseconds), so the tick WILL fire pre-kernel. Feeding _tx_timer_interrupt into ThreadX's still-zeroed timer state walks a bogus expiration list and bus-faults (observed: IMPRECISERR HardFault from SysTick).

Since
0.1.0

Definition at line 93 of file main.c.