USB self-loop config B: FS host DFU-downloads firmware to an HS DFU device, uploads + verifies.
More...
|
| enum | dfu_config_t : uint32_t {
k_dfu_thread_stack = 4096U
,
k_dfu_host_stack = 8192U
,
k_dfu_usbx_pool_bytes = 32768U
,
k_dfu_idle_ticks = 50U
,
k_dfu_boot_wait_ticks = 500U
,
k_dfu_retry_ticks = 3000U
,
k_dfu_baud = 115200U
,
k_dfu_print_cap = 160U
,
k_dfu_dev_priority = 8U
,
k_dfu_host_priority = 24U
} |
| | Compile-time settings: threads, pool, console, cadence. More...
|
| enum | dfu_hex_t : uint8_t {
k_dfu_hex_chars_u16 = 4U
,
k_dfu_hex_chars_u32 = 8U
,
k_dfu_dec_chars_u32 = 10U
,
k_dfu_nibble_bits = 4U
,
k_dfu_hex_digit_split = 10U
} |
| | Hex/decimal text-formatter sizing constants. More...
|
| enum | dfu_mask_t : uint32_t {
k_dfu_nibble_mask = 0xFU
,
k_dfu_dec_radix = 10U
} |
| | Bit-mask constants used by the text formatters. More...
|
| enum | dfu_geom_t : uint32_t {
k_dfu_xfer_size = 64U
,
k_dfu_blocks = 8U
,
k_dfu_image_bytes = 512U
,
k_dfu_no_mismatch = 0xFFFFFFFFU
,
k_dfu_pat_blk_mul = 131U
,
k_dfu_pat_idx_mul = 7U
,
k_dfu_pat_bias = 0xA5U
,
k_dfu_byte_mask = 0xFFU
,
k_dfu_dev_addr = 1U
,
k_dfu_intf = 0U
,
k_dfu_config_val = 1U
} |
| | Firmware-image geometry + pattern constants. More...
|
| enum | dfu_phase_t : uint32_t {
k_dfu_phase_boot = 0U
,
k_dfu_phase_init = 1U
,
k_dfu_phase_enum = 2U
,
k_dfu_phase_download = 3U
,
k_dfu_phase_upload = 4U
,
k_dfu_phase_pass = 5U
} |
| | J-Link probe values marking host-ladder progress. More...
|
| enum | usb_langid_byte_t : uint8_t {
k_usb_langid_en_us_lo = 0x09U
,
k_usb_langid_en_us_hi = 0x04U
} |
| enum | dfu_req_t : uint16_t {
k_dfu_bm_std_dev_in = 0x80U
,
k_dfu_bm_std_dev_out = 0x00U
,
k_dfu_bm_class_if_out = 0x21U
,
k_dfu_bm_class_if_in = 0xA1U
,
k_dfu_breq_get_desc = 0x06U
,
k_dfu_breq_set_addr = 0x05U
,
k_dfu_breq_set_config = 0x09U
,
k_dfu_breq_dnload = 0x01U
,
k_dfu_breq_upload = 0x02U
,
k_dfu_breq_getstatus = 0x03U
,
k_dfu_breq_abort = 0x06U
,
k_dfu_desc_device = 0x01U
,
k_dfu_dev_desc_len = 18U
,
k_dfu_off_dev_pid = 10U
,
k_dfu_byte_bits = 8U
,
k_dfu_getstatus_len = 6U
,
k_dfu_off_status_state = 4U
,
k_dfu_state_dnload_idle = 5U
,
k_dfu_state_idle = 2U
} |
| | Chapter-9 + DFU class request / descriptor constants. More...
|
| enum | dfu_enum_tune_t : uint32_t {
k_dfu_vbus_settle_ms = 200U
,
k_dfu_attach_to_ms = 2000U
,
k_dfu_debounce_ms = 500U
,
k_dfu_reset_hold_ms = 50U
,
k_dfu_recovery_ms = 20U
,
k_dfu_addr_settle_ms = 5U
,
k_dfu_status_poll_ms = 2U
,
k_dfu_status_tries = 50U
,
k_dfu_enum_tries = 8U
,
k_dfu_attach_spin = 50000000U
} |
| | Timing / retry tunables for the polled enumeration + status polling. More...
|
|
| void | _tx_timer_interrupt (void) |
| | ThreadX 1 ms tick worker.
|
| void | SysTick_Handler (void) |
| | Service the SysTick exception selected by the linked application.
|
| static void | dfu_pattern_fill (uint32_t block, uint8_t *out, uint32_t len) |
| | Fill a firmware block with this block's deterministic bytes.
|
| static VOID | dfu_device_worker (ULONG arg) |
| | Device-side worker: bring the DFU device up, then park.
|
| static uint8_t | dfu_nibble_to_hex (uint32_t nibble) |
| | Format one nibble (0..15) into an uppercase hex character.
|
| static uint32_t | dfu_str_len (const char *text) |
| | Bounded ASCII string length (cap k_dfu_print_cap).
|
| static ra8_err_t | dfu_sci_write (const uint8_t *data, uint32_t len) |
| | Push a literal block over the BSP UART console (SCI8) polled.
|
| static ra8_err_t | dfu_print (const char *text) |
| | Print a NUL-terminated ASCII string over the console.
|
| static ra8_err_t | dfu_print_hex (uint32_t value, uint8_t digits) |
| | Print a value as fixed-width uppercase hex.
|
| static ra8_err_t | dfu_print_dec (uint32_t value) |
| | Print a uint32_t as ASCII decimal.
|
| static ra8_err_t | dfu_print_fail (const char *what, ra8_err_t err) |
| | Print "FAIL <what> err=0xNNNNNNNN" on its own line.
|
| static ra8_err_t | dfu_host_pass (void) |
| | Run the full host pass: enumerate, download, upload-verify.
|
| static VOID | dfu_host_worker (ULONG arg) |
| | Host-side worker: retry the full pass until it succeeds, then park.
|
| VOID | tx_application_define (VOID *first_unused_memory) |
| | ThreadX application-define hook.
|
| static void | dfu_panic_halt (void) |
| | Halt forever in WFI – panic stop on init failure.
|
| static void | dfu_route_usb_or_halt (void) |
| | Route both ports' pins: HS as device, FS as host (config B).
|
| static void | dfu_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.
|
USB self-loop config B: FS host DFU-downloads firmware to an HS DFU device, uploads + verifies.
- Tag
- [Ring 6 / APP] {World: S}
Rehearses a firmware-update-over-USB path entirely on-chip, with the host and device roles SWAPPED versus config A (dfu_selftest_hs_host). The two USB ports are cabled to EACH OTHER and one image runs both stacks:
- USBHS (J7) = DEVICE: a ThreadX + USBX DFU class in DFU mode (bInterfaceProtocol 0x02, so it enumerates straight into dfuIDLE – no runtime/detach round-trip). Its write callback programs each downloaded block straight into the inactive MRAM slot (libs/ra8_dfu); its read callback serves the slot body back on UPLOAD. DFU runs entirely over EP0 control transfers (no data endpoints).
- USBFS (J11) = HOST: a self-contained polled host on the first-party ra8_usb_host_* primitives. It enumerates the device, DFU_DNLOADs a deterministic multi-block image (with DFU_GETSTATUS polling), DFU_ABORTs back to dfuIDLE, then DFU_UPLOADs it back and byte-checks it – proving the MRAM program/read-back path round-trips intact.
The download exercises the host control-OUT data stage of ra8_usb_host_control_xfer (DFU_DNLOAD carries the firmware block in the SETUP data stage host -> device).
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 so J7's role is Device and U18 does not back-feed VBUS; D+/D- are dedicated PHY balls. FS host: P4_07 VBUS sense, P5_00 VBUSEN peripheral-routed so 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-15
- Copyright
- Copyright (c) 2026 Brighton Sikarskie SPDX-License-Identifier: MIT
- Since
- 0.1.0
Definition in file main.c.
| VOID dfu_device_worker |
( |
ULONG | arg | ) |
|
|
static |
Device-side worker: bring the DFU device up, then park.
- Parameters
-
| [in] | arg | ThreadX entry argument (unused). |
- Returns
- Never returns.
- Precondition
- tx_application_define created this thread.
-
USB-HS pins + PHY PLL are up (main did both).
- Postcondition
- The HS device is attached in DFU mode; the DFU class services EP0.
-
On any bring-up failure the thread exits (s_dbg_dev_step frozen).
- Note
- The DFU class runs its own thread; this worker only brings it up.
- Since
- 0.1.0
Definition at line 414 of file main.c.
References k_dfu_idle_ticks, k_ra8_dfu_slot_b, k_ra8_ok, k_ra8_usb_speed_hs, ra8_dfu_device_set_target(), ra8_dfu_device_start(), ra8_dfu_device_worker_step(), s_dbg_dev_step, s_dbg_host_err, s_device_framework, s_language_id_framework, s_string_framework, s_usbx_pool, and tx_thread_sleep.
Run the full host pass: enumerate, download, upload-verify.
- Returns
- First failing step's error, or k_ra8_ok.
- Return values
-
- Precondition
- Device-side DFU class is registered (other thread).
-
The self-loop cable connects J7 to J11.
- Postcondition
- On success s_dbg_pass_count advanced and LED2 is on.
-
On failure the host controller is deinitialized for a clean retry.
- Note
- Blocking; runs on the low-priority host thread.
- Since
- 0.1.0
Definition at line 683 of file main.c.
References ra8_dfu_host_result_t::blocks_ok, dfu_pattern_fill(), dfu_print(), dfu_print_dec(), dfu_print_fail(), dfu_print_hex(), k_dfu_blocks, k_dfu_hex_chars_u16, k_dfu_image_bytes, k_dfu_phase_download, k_dfu_phase_init, k_dfu_phase_pass, k_dfu_xfer_size, k_ra8_board_led2, k_ra8_ok, k_ra8_usb_speed_fs, ra8_dfu_host_result_t::mismatch, ra8_dfu_host_result_t::pid, ra8_board_led_on(), ra8_dfu_host_run(), s_dbg_blocks_ok, s_dbg_mismatch, s_dbg_pass_count, s_dbg_phase, s_dbg_pid, and s_dfu_image.
| void dfu_route_usb_or_halt |
( |
void | | ) |
|
|
static |
Route both ports' pins: HS as device, FS as host (config B).
- Returns
- void.
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 dfu_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 842 of file main.c.
References dfu_panic_halt(), k_dfu_pin_fs_dm, k_dfu_pin_fs_dp, k_dfu_pin_fs_vbus, k_dfu_pin_fs_vbusen, k_dfu_pin_hs_role, k_dfu_pin_hs_vbus, k_ra8_level_low, k_ra8_ok, k_ra8_psel_usb_fs, k_ra8_psel_usb_hs, ra8_gpio_output_init(), and ra8_pfs_route_peripheral().
| 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 83 of file main.c.
References _tx_timer_interrupt(), ra8_time_on_tick(), s_tx_kernel_up, and ux_dcd_ra8_usb_irq_reenable().
| VOID tx_application_define |
( |
VOID * | first_unused_memory | ) |
|
ThreadX application-define hook.
Spawns both workers.
- Parameters
-
| [in] | first_unused_memory | Sentinel (unused; static stacks). |
- Returns
- void.
- Precondition
- Called from tx_kernel_enter after scheduler init.
-
Static stacks are reserved at file scope.
- Postcondition
- Two auto-start workers are queued; s_tx_kernel_up is true.
-
The scheduler runs the device DFU bring-up + the host DFU ladder.
- Note
- Called once at boot; not thread-safe.
- Since
- 0.1.0
Definition at line 776 of file main.c.
References dfu_device_worker(), dfu_host_worker(), k_dfu_dev_priority, k_dfu_host_priority, k_dfu_host_stack, k_dfu_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, TX_AUTO_START, TX_NO_TIME_SLICE, and tx_thread_create.