|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
USB self-loop: HS host writes bytes to a CDC-ACM device, reads the echo. 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_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 "usb_selftest_cdc_steps.h"#include "tx_api.h"#include "ux_api.h"#include "ux_dcd_ra8_usb.h"#include "ux_device_class_cdc_acm.h"#include "ux_device_stack.h"Go to the source code of this file.
Enumerations | |
| enum | cdc_dev_step_t : uint32_t { k_cdc_dev_step_stack = 1U , k_cdc_dev_step_class = 2U , k_cdc_dev_step_dcd = 3U , k_cdc_dev_step_attach = 4U , k_cdc_dev_step_echo = 5U } |
| J-Link probe values marking device-worker bring-up progress. More... | |
| enum | usb_langid_byte_t : uint8_t { k_usb_langid_en_us_lo = 0x09U , k_usb_langid_en_us_hi = 0x04U } |
Functions | |
| void | _tx_timer_interrupt (void) |
| void | SysTick_Handler (void) |
| Service the SysTick exception selected by the linked application. | |
| static VOID | cdc_activate (VOID *cdc_instance) |
| CDC-ACM activate callback. | |
| static VOID | cdc_deactivate (VOID *cdc_instance) |
| CDC-ACM deactivate callback. | |
| static UINT | cdc_usbx_stack_up (void) |
| Bring USBX system + device stack up with the CDC-ACM framework. | |
| static UINT | cdc_class_register (void) |
| Register the CDC-ACM class against configuration 1, interface 0. | |
| static void | cdc_echo_iter (UCHAR *buf, ULONG cap) |
| One device echo iteration: read a bulk-OUT chunk, write it back. | |
| static VOID | cdc_device_worker (ULONG arg) |
| Device-side worker: bring the CDC-ACM device up, then echo forever. | |
| VOID | tx_application_define (VOID *first_unused_memory) |
| ThreadX application-define hook. | |
| static void | cdc_panic_halt (void) |
| Halt forever in WFI – panic stop on init failure. | |
| static void | cdc_route_usb_or_halt (void) |
| Route both ports' pins: FS as device, HS as host. | |
| static void | cdc_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_cdc_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_cdc_pin_fs_vbusen = (ra8_port_pin_t)k_ra8_board_usbfs_pin_vbusen |
| USBFS VBUSEN (P5_00) – GPIO LOW for the device role. | |
| static const ra8_port_pin_t | k_cdc_pin_fs_dp = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dp |
| USBFS D+ (P8_14). | |
| static const ra8_port_pin_t | k_cdc_pin_fs_dm = (ra8_port_pin_t)k_ra8_board_usbfs_pin_dm |
| USBFS D- (P8_15). | |
| static const ra8_port_pin_t | k_cdc_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_cdc_pin_hs_pwr = (ra8_port_pin_t)k_ra8_board_usbhs_pin_pwr |
| J7 host-power switch (PD07): HIGH = U18 supplies VBUS (UM 6.2). | |
| static TX_THREAD | s_device_thread |
| ThreadX TCB for the USBX device-side worker thread. | |
| static UCHAR | s_device_stack [k_cdc_thread_stack] |
| Stack backing storage for s_device_thread. | |
| static TX_THREAD | s_host_thread |
| ThreadX TCB for the host-side worker thread. | |
| static UCHAR | s_host_stack [k_cdc_host_stack] |
| Stack backing storage for s_host_thread. | |
| static UCHAR | s_usbx_pool [k_cdc_usbx_pool_bytes] |
| USBX memory pool (USBX uses tx_byte_pool internally). | |
| static UX_SLAVE_CLASS_CDC_ACM * | s_cdc_acm = UX_NULL |
| Active CDC-ACM class instance, captured by the activate callback. | |
| static TX_SEMAPHORE | s_cdc_active_sem |
| Posted by the activate callback so the echo worker blocks on it instead of polling s_cdc_acm with tx_thread_sleep (which has been observed never returning on this silicon under load). | |
| static volatile uint32_t | s_dbg_dev_echo_calls |
| Device-side echo iterations (one read+write each). | |
| static volatile uint32_t | s_dbg_dev_last_len |
| Bytes the device echoed on the most recent round. | |
| static volatile uint32_t | s_dbg_dev_step |
| Device worker progress: 1 stack, 2 class, 3 dcd, 4 attach, 5 echo. | |
| static volatile uint32_t | s_dbg_dev_err |
| Device worker first failing return code (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. | |
USB self-loop: HS host writes bytes to a CDC-ACM device, reads the echo.
The CDC-ACM echo self-loop – it exercises a bidirectional bulk round-trip through a real device class (host bulk-OUT -> device receives -> device echoes -> host bulk-IN). The two USB ports are cabled to EACH OTHER and one firmware image runs both USB stacks:
Each round ships a sub-MPS (60-byte) payload so the echo returns as a single short packet (no MPS-exact ZLP ambiguity on the host bulk-IN). No serial terminal is involved; raw bulk transfers only.
The link runs at 12 Mbps (FS device ceiling; HS host serves an FS downstream device).
Verdicts stream over SCI8 (J-Link OB CDC console, 115200) and are mirrored in J-Link-readable probes (s_dbg_*).
FS device: P4_07 VBUS sense, P5_00 VBUSEN GPIO LOW (device role), P8_14 D+, P8_15 D- (PSEL usb_fs). HS host: SW4-8 to Host via the U15 expander, PD07 HIGH (U18 supplies J7 VBUS), P4_08 USBHS_VBUS (PSEL usb_hs). Console: PD_02/PD_03 SCI8 (PSEL sci_async).
Definition in file main.c.
| enum cdc_dev_step_t : uint32_t |
| enum usb_langid_byte_t : uint8_t |
|
extern |
|
static |
CDC-ACM activate callback.
Captures the live class instance.
Pins ux_slave_device_state at CONFIGURED (works around a residual DVSQ-poll race on this silicon that can demote it back to ATTACHED after SET_CONFIGURATION and break the cdc_acm_read gate), then posts the semaphore the echo worker blocks on. The DCD ISR auto-echo is deliberately NOT enabled – the worker read/write path is the sole data mover, so the two cannot race on the bulk-OUT pipe.
| [in] | cdc_instance | Pointer to UX_SLAVE_CLASS_CDC_ACM. |
Definition at line 445 of file main.c.
References s_cdc_acm, and s_cdc_active_sem.
Referenced by cdc_class_register().
|
static |
Register the CDC-ACM class against configuration 1, interface 0.
Binds cdc_activate / cdc_deactivate so the worker learns when the host has configured the device. The comm + data interfaces are described by the device framework (IAD composite).
| UX_SUCCESS | Class registered. |
Definition at line 529 of file main.c.
References cdc_activate(), and cdc_deactivate().
Referenced by cdc_device_worker().
|
static |
CDC-ACM deactivate callback.
Drops the live class pointer.
| [in] | cdc_instance | Unused. |
Definition at line 468 of file main.c.
References s_cdc_acm.
Referenced by cdc_class_register().
|
static |
Device-side worker: bring the CDC-ACM device up, then echo forever.
USBX system + device stack + CDC-ACM class + DCD bridge on the USBFS controller, then DPRPU attach. Blocks on s_cdc_active_sem until the host configures the device, then loops cdc_echo_iter.
| [in] | arg | ThreadX entry argument (unused). |
Definition at line 604 of file main.c.
References cdc_class_register(), cdc_echo_iter(), cdc_usbx_stack_up(), k_cdc_dev_step_attach, k_cdc_dev_step_class, k_cdc_dev_step_dcd, k_cdc_dev_step_echo, k_cdc_dev_step_stack, k_cdc_echo_buf, k_ra8_ok, k_ra8_usb_speed_fs, ra8_usb_device_attach(), s_cdc_acm, s_cdc_active_sem, s_dbg_dev_err, s_dbg_dev_step, TX_WAIT_FOREVER, and ux_dcd_ra8_usb_initialize().
Referenced by tx_application_define().
|
static |
One device echo iteration: read a bulk-OUT chunk, write it back.
Pins CONFIGURED (DVSQ-poll race guard), then _ux_device_class_cdc_acm_read (blocks for the host's bulk-OUT, returns on the short packet) -> _ux_device_class_cdc_acm_write (stages the same bytes on bulk-IN). This rides the normal device bulk-OUT receive path the WRITE(10) driver fix repaired, NOT the DCD ISR auto-echo.
| [in,out] | buf | Scratch buffer for one chunk. |
| [in] | cap | Capacity of buf in bytes. |
buf holds cap bytes. Definition at line 565 of file main.c.
References k_ra8_board_led1, ra8_board_led_toggle(), s_cdc_acm, s_dbg_dev_echo_calls, s_dbg_dev_last_len, and tx_thread_sleep.
Referenced by cdc_device_worker().
|
static |
Halt forever in WFI – panic stop on init failure.
Last-resort stop; only a debugger or reset recovers.
Definition at line 710 of file main.c.
Referenced by cdc_route_usb_or_halt(), cdc_setup_or_halt(), and main().
|
static |
Route both ports' pins: FS as device, HS as host.
FS device: P4_07 VBUS sense, P5_00 VBUSEN GPIO LOW (else peripheral routing forces host VBUSEN and blocks device enum), P8_14/P8_15 data. HS host: SW4-8 to Host via the U15 expander, PD07 HIGH (U18 supplies J7), P4_08 VBUS sense.
Definition at line 733 of file main.c.
References cdc_panic_halt(), k_cdc_pin_fs_dm, k_cdc_pin_fs_dp, k_cdc_pin_fs_vbus, k_cdc_pin_fs_vbusen, k_cdc_pin_hs_pwr, k_cdc_pin_hs_vbus, k_ra8_level_high, k_ra8_level_low, k_ra8_ok, k_ra8_psel_usb_fs, k_ra8_psel_usb_hs, ra8_board_io_expander_set_usbhs_host_mode(), ra8_gpio_output_init(), and ra8_pfs_route_peripheral().
Referenced by cdc_setup_or_halt().
|
static |
Bring CGC + both USB clocks + SysTick + SCI8 + LEDs + pins up.
USBFS needs the 48 MHz PLL2 reference; USBHS needs its UTMI PLL. SCI8 is the J-Link OB CDC console at 115200.
Definition at line 772 of file main.c.
References cdc_panic_halt(), cdc_route_usb_or_halt(), k_cdc_baud, k_ra8_board_led1, k_ra8_board_led2, k_ra8_clock_id_cpuclk0, k_ra8_ok, 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(), and ra8_time_init().
Referenced by main().
|
static |
Bring USBX system + device stack up with the CDC-ACM framework.
One-shot USBX pool + device-stack init (FS-only framework).
| UX_SUCCESS | Stack ready. |
Definition at line 494 of file main.c.
References k_cdc_usbx_pool_bytes, s_device_framework_fs, s_language_id_framework, s_string_framework, and s_usbx_pool.
Referenced by cdc_device_worker().
| 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 workers only deal with stack bring-up.
Definition at line 816 of file main.c.
References cdc_panic_halt(), cdc_setup_or_halt(), and ra8_isr_globals_enable().
| 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.
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.
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.
Service the SysTick exception selected by the linked application.
Definition at line 93 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.
Creates the activation semaphore, then the device worker at priority 8 and the host worker at 24 (below the USBX class threads). Sets s_tx_kernel_up so SysTick may feed ThreadX from here on.
| [in] | first_unused_memory | Sentinel (unused; static stacks). |
Definition at line 661 of file main.c.
References cdc_device_worker(), cdc_host_worker(), k_cdc_dev_priority, k_cdc_host_priority, k_cdc_host_stack, k_cdc_thread_stack, s_cdc_active_sem, 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.
|
static |
|
static |
|
static |
USBFS VBUS sense pin (P4_07, PSEL = 0x13).
Definition at line 108 of file main.c.
Referenced by cdc_route_usb_or_halt().
|
static |
USBFS VBUSEN (P5_00) – GPIO LOW for the device role.
Definition at line 111 of file main.c.
Referenced by cdc_route_usb_or_halt().
|
static |
J7 host-power switch (PD07): HIGH = U18 supplies VBUS (UM 6.2).
Definition at line 123 of file main.c.
Referenced by cdc_route_usb_or_halt().
|
static |
USBHS_VBUS sense pin (P4_08, PSEL = 0x14).
Definition at line 120 of file main.c.
Referenced by cdc_route_usb_or_halt().
|
static |
Active CDC-ACM class instance, captured by the activate callback.
Definition at line 195 of file main.c.
Referenced by cdc_activate(), cdc_deactivate(), cdc_device_worker(), cdc_echo_iter(), demo_cdc_activate(), demo_cdc_activate(), demo_cdc_deactivate(), demo_cdc_deactivate(), demo_echo_iter(), demo_worker(), and demo_worker_echo_loop().
|
static |
Posted by the activate callback so the echo worker blocks on it instead of polling s_cdc_acm with tx_thread_sleep (which has been observed never returning on this silicon under load).
Definition at line 205 of file main.c.
Referenced by cdc_activate(), cdc_device_worker(), demo_cdc_activate(), demo_cdc_activate(), demo_worker(), and tx_application_define().
|
static |
Device-side echo iterations (one read+write each).
Definition at line 216 of file main.c.
Referenced by cdc_echo_iter().
|
static |
|
static |
Bytes the device echoed on the most recent round.
Definition at line 218 of file main.c.
Referenced by cdc_echo_iter().
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
|
static |
Set in tx_application_define; gates ThreadX tick delivery.
main() starts SysTick before tx_kernel_enter and the setup window is long (U15 expander I2C blocks for ms), so the tick fires pre-kernel; feeding _tx_timer_interrupt into ThreadX's zeroed timer state bus-faults. Gate it until the kernel runs.
|
static |