|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
USB device-mode lifecycle, status, and endpoint configuration. More...
#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_log.h"#include "ra8_mstp.h"#include "ra8_usb.h"#include "ra8_usb_internal.h"#include "ra8_usb_regs.h"Go to the source code of this file.
Functions | |
| static ra8_usb_dev_state_t | internal_decode_dvsq (uint16_t intsts0) |
| Translate INTSTS0.DVSQ[2:0] into the public state enum. | |
| ra8_err_t | ra8_usb_device_init (ra8_usb_speed_t speed) |
| Implementation of ra8_usb_device_init(). | |
| ra8_err_t | ra8_usb_device_deinit (ra8_usb_speed_t speed) |
| Implementation of ra8_usb_device_deinit(). | |
| ra8_err_t | ra8_usb_device_attach (ra8_usb_speed_t speed, bool attached) |
| Implementation of ra8_usb_device_attach(). | |
| ra8_err_t | ra8_usb_get_status (ra8_usb_speed_t speed, uint16_t *out_mask) |
| Implementation of ra8_usb_get_status(). | |
| ra8_err_t | ra8_usb_clear_status (ra8_usb_speed_t speed, uint16_t mask) |
| Implementation of ra8_usb_clear_status(). | |
| ra8_err_t | ra8_usb_get_device_state (ra8_usb_speed_t speed, ra8_usb_dev_state_t *out_state) |
| Implementation of ra8_usb_get_device_state(). | |
| ra8_err_t | ra8_usb_set_address (ra8_usb_speed_t speed, uint8_t address) |
| Implementation of ra8_usb_set_address(). | |
| static void | internal_dcp_reset_defaults (volatile r_usb_regs_t *reg) |
| Reset DCP defaults + clear DCP FIFO on bus-reset rearm. | |
| ra8_err_t | ra8_usb_device_busreset_rearm (ra8_usb_speed_t speed) |
| Implementation of ra8_usb_device_busreset_rearm (see header). | |
| static ra8_err_t | internal_check_ep_args (uint8_t pipe_num, uint8_t ep_addr, ra8_usb_ep_dir_t dir, ra8_usb_ep_type_t type, uint16_t max_packet) |
| Validate the argument set for ra8_usb_configure_endpoint. | |
| static void | internal_pipe_finalize (volatile r_usb_regs_t *reg, uint8_t pipe_num, ra8_usb_ep_dir_t dir) |
| Finalize the pipe after PIPECFG/PIPEMAXP/PIPEPERI have landed. | |
| static void | internal_pipe_arm_irq (volatile r_usb_regs_t *reg, uint8_t pipe_num, ra8_usb_ep_dir_t dir) |
| Re-arm the per-pipe interrupt the dispatcher routes off of. | |
| ra8_err_t | ra8_usb_configure_endpoint (ra8_usb_speed_t speed, uint8_t pipe_num, uint8_t ep_addr, ra8_usb_ep_dir_t dir, ra8_usb_ep_type_t type, uint16_t max_packet) |
| Implementation of ra8_usb_configure_endpoint(). | |
| ra8_err_t | ra8_usb_stall_endpoint (ra8_usb_speed_t speed, uint8_t pipe_num) |
| Implementation of ra8_usb_stall_endpoint(). | |
Variables | |
| static const char * | s_tag = "USB" |
| volatile uint16_t | g_syscfg_after_phy_bringup = 0U |
| SYSCFG snapshot captured at the end of ra8_usb_device_init. | |
| volatile uint16_t | g_lpsts_after_phy_bringup = 0U |
| LPSTS snapshot at the end of ra8_usb_device_init. | |
| volatile uint16_t | g_syscfg_after_attach = 0U |
| SYSCFG snapshot captured at the end of ra8_usb_device_attach(true). | |
| volatile uint16_t | g_lpsts_after_attach = 0U |
| LPSTS snapshot at the end of ra8_usb_device_attach(true). | |
| volatile uint16_t | g_syssts0_after_attach = 0U |
| SYSSTS0 snapshot captured at the end of ra8_usb_device_attach(true). | |
| volatile uint16_t | g_syscfg_before_dprpu = 0U |
| SYSCFG snapshot captured immediately BEFORE the DPRPU write. | |
USB device-mode lifecycle, status, and endpoint configuration.
Device-mode half of the native USB driver: module init / deinit / attach, status + device-state queries, USB-address programming, the bus-reset DCP re-arm, and the non-control endpoint (pipe) configuration and stall entry points (HUM Ch 36 USBFS / Ch 37 USBHS). Split out of ra8_usb.c so every translation unit stays under the 1000-line cap; the shared register helpers it calls live in ra8_usb.c and the PHY / common bring-up it dispatches to lives in ra8_usb_phy.c – both are declared in ra8_usb_internal.h. Modelled on FSP r_usb_pdriver.c / r_usb_preg_abs.c; no FSP source ships in this tree.
Definition in file ra8_usb_device.c.
|
static |
Validate the argument set for ra8_usb_configure_endpoint.
See implementation.
| [in] | pipe_num | See implementation. |
| [in] | ep_addr | See implementation. |
| [in] | dir | See implementation. |
| [in] | type | See implementation. |
| [in] | max_packet | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 552 of file ra8_usb_device.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_ep_dir_in, k_ra8_usb_ep_dir_out, k_ra8_usb_ep_type_iso, k_ra8_usb_max_ep_addr, k_ra8_usb_max_pipe_num, and k_ra8_usb_pipe_max_packet.
Referenced by ra8_usb_configure_endpoint().
|
static |
Reset DCP defaults + clear DCP FIFO on bus-reset rearm.
Helper extracted from ra8_usb_device_busreset_rearm to keep the top-level function under the clang-tidy line budget. Re-asserts DCPCFG=0 and DCPMAXP=64, then pulses CFIFOCTR.BCLR (HUM Ch 36.2.8 / 37.2.10 p 1979 / 2073) to wipe any bytes a previous incomplete control transfer left in the DCP FIFO. Without the BCLR pulse the next ra8_usb_dcp_in_data sees FRDY=0, times out, and the DCD path STALLs EP0 (Linux dmesg "device descriptor read/N, error -110" on every retry).
| [in] | reg | Selected USB instance register block. |
Definition at line 453 of file ra8_usb_device.c.
References r_usb_regs_t::CFIFOCTR, r_usb_regs_t::DCPCFG, r_usb_regs_t::DCPMAXP, k_ra8_fifoctr_bclr, k_ra8_usb_dcp_max_packet, and priv_select_cfifo().
Referenced by ra8_usb_device_busreset_rearm().
|
static |
Translate INTSTS0.DVSQ[2:0] into the public state enum.
See implementation.
| [in] | intsts0 | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 152 of file ra8_usb_device.c.
References k_ra8_dvsq_address, k_ra8_dvsq_configured, k_ra8_dvsq_default, k_ra8_dvsq_suspend, k_ra8_intsts0_mask_dvsq, k_ra8_usb_dev_state_address, k_ra8_usb_dev_state_configured, k_ra8_usb_dev_state_default, k_ra8_usb_dev_state_powered, and k_ra8_usb_dev_state_suspended.
Referenced by ra8_usb_get_device_state().
|
static |
Re-arm the per-pipe interrupt the dispatcher routes off of.
Sets BRDYENB for OUT pipes and BEMPENB for IN pipes (mirrors STAR rx_usb_hw.c::rx_usb_hw_configure_pipe step 8). Without this, BRDYSTS for the freshly configured OUT pipe never propagates to INTSTS0.BRDY – the polled-dispatch BRDYSTS scan stays clean forever, queue_out keeps returning no_data, the pipe sits at PID=NAK forever, and the host (macOS AppleUSBCDCACM) gives up retrying bulk-OUT tokens.
| [in,out] | reg | Controller register window. |
| [in] | pipe_num | Pipe index 1..9. |
| [in] | dir | Endpoint direction. |
Definition at line 628 of file ra8_usb_device.c.
References r_usb_regs_t::BEMPENB, r_usb_regs_t::BRDYENB, and k_ra8_usb_ep_dir_out.
Referenced by ra8_usb_configure_endpoint().
|
static |
Finalize the pipe after PIPECFG/PIPEMAXP/PIPEPERI have landed.
Pulses SQCLR + ACLRM, clears BRDYSTS/BEMPSTS for this pipe, then sets PID. OUT goes to BUF so the first host OUT token is ACKed; IN stays at NAK until the caller has data to push (HUM Ch 36.2.27; mirrors STAR rx_usb_hw.c::internal_usb_finalize_pipe).
| [in,out] | reg | Controller register window. |
| [in] | pipe_num | Pipe index 1..9. |
| [in] | dir | Endpoint direction. |
Definition at line 595 of file ra8_usb_device.c.
References r_usb_regs_t::BEMPSTS, r_usb_regs_t::BRDYSTS, k_ra8_pid_buf, k_ra8_pid_nak, k_ra8_pipectr_aclrm, k_ra8_pipectr_sqclr, k_ra8_usb_ep_dir_out, r_usb_regs_t::PIPECTR, priv_pipe_pid(), and priv_rmw16().
Referenced by ra8_usb_configure_endpoint().
|
nodiscard |
Implementation of ra8_usb_clear_status().
Clear bits in INTSTS0.
See the public header for the documented contract; this definition implements it.
| [in] | speed | See implementation. |
| [in] | mask | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 367 of file ra8_usb_device.c.
References r_usb_regs_t::INTSTS0, k_ra8_err_invalid_arg, k_ra8_ok, and priv_pick().
Referenced by demo_poll_once(), and internal_ack_spurious().
|
nodiscard |
Implementation of ra8_usb_configure_endpoint().
Configure a non-control PIPE for IN or OUT bulk / interrupt / iso transfers.
See the public header for the documented contract; this definition implements it. Sequence (FIT r_usb_creg_abs.c::usb_cstd_pipe_init mirror): quiesce -> PIPESEL window write of PIPECFG/PIPEMAXP/PIPEPERI -> deselect window -> finalize PIPECTR -> arm per-pipe IRQ.
| [in] | speed | Which controller (FS/HS). |
| [in] | pipe_num | Pipe index 1..9. |
| [in] | ep_addr | USB endpoint address (low nibble = EP number). |
| [in] | dir | IN/OUT direction. |
| [in] | type | Bulk / Interrupt / Iso. |
| [in] | max_packet | wMaxPacketSize from the descriptor. |
| k_ra8_ok | Pipe configured and PID set per direction. |
| k_ra8_err_invalid_arg | speed/pipe/ep/type/max_packet out of range. |
Definition at line 661 of file ra8_usb_device.c.
References internal_check_ep_args(), internal_pipe_arm_irq(), internal_pipe_finalize(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_ep_type_bulk, r_usb_regs_t::PIPEBUF, r_usb_regs_t::PIPECFG, r_usb_regs_t::PIPEMAXP, r_usb_regs_t::PIPEPERI, r_usb_regs_t::PIPESEL, priv_pick(), priv_pipe_quiesce(), priv_pipebuf_word(), and priv_pipecfg_word().
Referenced by internal_configure_pipes(), internal_configure_pipes(), internal_configure_pipes(), internal_configure_pipes(), internal_configure_pipes(), internal_configure_pipes(), internal_configure_pipes(), internal_configure_pipes(), internal_configure_pipes(), internal_configure_pipes(), internal_endpoint_create(), and internal_endpoint_create().
|
nodiscard |
Implementation of ra8_usb_device_attach().
Raise / drop the D+ pull-up to advertise the device to the host.
See the public header for the documented contract; this definition implements it.
| [in] | speed | See implementation. |
| [in] | attached | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 267 of file ra8_usb_device.c.
References g_lpsts_after_attach, g_syscfg_after_attach, g_syscfg_before_dprpu, g_syssts0_after_attach, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_syscfg_bit_cnen, k_ra8_syscfg_bit_dprpu, k_ra8_usb_speed_hs, priv_pick(), priv_rmw16(), ra8_usbhs_lpsts(), r_usb_regs_t::SYSCFG, and r_usb_regs_t::SYSSTS0.
Referenced by cdc_device_worker(), demo_usb_bringup(), demo_worker(), demo_worker_start_dcd(), dfu_device_worker(), hid_device_worker(), hid_device_worker(), microsd_device_worker(), mlun_device_worker(), ns_usb_worker(), ospirw_device_worker(), ra8_nsc_usb_attach(), ra8_usb_cdc_attach(), ra8_usb_cdc_deinit(), ra8_usb_pal_attach(), ra8_usb_pal_deinit(), ra8_usb_paud_close(), ra8_usb_phid_close(), ra8_usb_pmsc_close(), ra8_usb_pprn_close(), ra8_usb_pvnd_close(), sdmsc_device_worker(), selftest_device_worker(), selftest_device_worker(), and wlun_device_worker().
|
nodiscard |
Implementation of ra8_usb_device_busreset_rearm (see header).
Re-arm the default control pipe (DCP) after a host-issued bus reset.
Re-default DCPCFG/DCPMAXP, clear all PIPECTR[*], drop BRDYSTS/NRDYSTS/BEMPSTS, clear the DCP FIFO via CFIFOCTR.BCLR, and re-arm INTENB0 with the post-init mask. Mirrors FSP r_usb_psignal.c::usb_pstd_bus_reset.
| [in] | speed | Which controller (FS or HS). |
| k_ra8_ok | Success. |
| k_ra8_err_invalid_arg | speed out of range. |
Definition at line 478 of file ra8_usb_device.c.
References r_usb_regs_t::BEMPSTS, r_usb_regs_t::BRDYSTS, r_usb_regs_t::INTENB0, internal_dcp_reset_defaults(), k_ra8_err_invalid_arg, k_ra8_int0_bit_bemp, k_ra8_int0_bit_brdy, k_ra8_int0_bit_ctrt, k_ra8_int0_bit_dvst, k_ra8_int0_bit_nrdy, k_ra8_int0_bit_vbse, k_ra8_ok, k_ra8_usb_pipectr_count, r_usb_regs_t::NRDYSTS, r_usb_regs_t::PIPECTR, and priv_pick().
Referenced by demo_handle_dvst(), and priv_dvst_default_state().
|
nodiscard |
Implementation of ra8_usb_device_deinit().
Tear down a USB controller and drop its MSTP reference.
See the public header for the documented contract; this definition implements it.
| [in] | speed | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 234 of file ra8_usb_device.c.
References r_usb_regs_t::BEMPENB, r_usb_regs_t::BRDYENB, r_usb_regs_t::INTENB0, r_usb_regs_t::INTENB1, k_ra8_err_invalid_arg, r_usb_regs_t::NRDYENB, priv_mstp(), priv_pick(), ra8_mstp_disable(), and r_usb_regs_t::SYSCFG.
Referenced by ra8_usb_cdc_deinit(), ra8_usb_cdc_init(), ra8_usb_composite_close(), ra8_usb_pal_deinit(), ra8_usb_paud_close(), ra8_usb_phid_close(), ra8_usb_pmsc_close(), ra8_usb_pprn_close(), ra8_usb_pvnd_close(), and ux_dcd_ra8_usb_uninitialize().
|
nodiscard |
Implementation of ra8_usb_device_init().
Bring up a USB controller in device mode.
Dispatches FS vs HS bring-up, then programmes shared FIFO, DCP, and INTENB0 fields.
| [in] | speed | See implementation. |
| k_ra8_ok | Operation succeeded. |
| k_ra8_err_invalid_arg | Invalid speed. |
| k_ra8_err_hw_timeout | HS PHY PLL lock timeout. |
Definition at line 186 of file ra8_usb_device.c.
References g_lpsts_after_phy_bringup, g_syscfg_after_phy_bringup, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_speed_hs, priv_mstp(), priv_pick(), priv_usb_init_common(), priv_usbfs_module_bringup(), priv_usbhs_phy_bringup(), ra8_log_info_val, ra8_mstp_enable(), RA8_RETURN_ON_ERROR, ra8_usbhs_lpsts(), s_tag, and r_usb_regs_t::SYSCFG.
Referenced by ra8_board_usbhs_device_init(), ra8_nsc_usb_init(), ra8_usb_cdc_init(), ra8_usb_composite_init(), ra8_usb_pal_init(), ra8_usb_paud_init(), ra8_usb_phid_init(), ra8_usb_pmsc_init(), ra8_usb_pprn_init(), ra8_usb_pvnd_init(), and ux_dcd_ra8_usb_initialize().
|
nodiscard |
Implementation of ra8_usb_get_device_state().
Read the decoded device state from INTSTS0.DVSQ[2:0].
See the public header for the documented contract; this definition implements it.
| [in] | speed | See implementation. |
| [in] | out_state | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 392 of file ra8_usb_device.c.
References internal_decode_dvsq(), r_usb_regs_t::INTSTS0, k_ra8_err_invalid_arg, k_ra8_ok, priv_pick(), RA8_CHECK_NULL_PTR, and s_tag.
Referenced by demo_handle_dvst().
|
nodiscard |
Implementation of ra8_usb_get_status().
Read raw INTSTS0 snapshot.
See the public header for the documented contract; this definition implements it.
| [in] | speed | See implementation. |
| [in] | out_mask | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 341 of file ra8_usb_device.c.
References r_usb_regs_t::INTSTS0, k_ra8_err_invalid_arg, k_ra8_ok, priv_pick(), RA8_CHECK_NULL_PTR, and s_tag.
Referenced by demo_poll_once().
|
nodiscard |
Implementation of ra8_usb_set_address().
Program the device USB address into USBADDR.
See the public header for the documented contract; this definition implements it.
| [in] | speed | See implementation. |
| [in] | address | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 418 of file ra8_usb_device.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_max_address, k_ra8_usbaddr_addr_mask, priv_pick(), and r_usb_regs_t::USBADDR.
Referenced by demo_dispatch_setup(), internal_do_set_address(), internal_do_set_address(), internal_do_set_address(), internal_do_set_address(), internal_do_set_address(), and internal_handle_standard().
|
nodiscard |
Implementation of ra8_usb_stall_endpoint().
Stall a configured endpoint.
See the public header for the documented contract; this definition implements it.
| [in] | speed | See implementation. |
| [in] | pipe_num | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 716 of file ra8_usb_device.c.
References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pid_stall, k_ra8_usb_max_pipe_num, priv_dcp_pid(), priv_pick(), and priv_pipe_pid().
Referenced by internal_endpoint_stall().
| volatile uint16_t g_lpsts_after_attach = 0U |
LPSTS snapshot at the end of ra8_usb_device_attach(true).
Bisect probe; expected SUSPENDM=1 (0x4000). HUM Ch 37.2.43 LPSTS p 2111.
Definition at line 91 of file ra8_usb_device.c.
Referenced by ra8_usb_device_attach().
| volatile uint16_t g_lpsts_after_phy_bringup = 0U |
LPSTS snapshot at the end of ra8_usb_device_init.
Companion to g_syscfg_after_phy_bringup. Expected value: SUSPENDM=1 (bit 14), so 0x4000. HUM Ch 37.2.43 LPSTS p 2111.
Definition at line 67 of file ra8_usb_device.c.
Referenced by ra8_usb_device_init().
| volatile uint16_t g_syscfg_after_attach = 0U |
SYSCFG snapshot captured at the end of ra8_usb_device_attach(true).
Bisect probe; expected value with attach=true: 0x0091 (USBE | DPRPU | HSE). HUM Ch 37.2.1 SYSCFG p 2060.
Definition at line 79 of file ra8_usb_device.c.
Referenced by ra8_usb_device_attach().
| volatile uint16_t g_syscfg_after_phy_bringup = 0U |
SYSCFG snapshot captured at the end of ra8_usb_device_init.
Bisect probe for the "USBE clears between phy bring-up and echo loop" regression. Captured AFTER priv_usbhs_phy_bringup AND priv_usb_init_common have both run. Expected value: 0x0081 (USBE | HSE). HUM Ch 37.2.1 SYSCFG p 2060.
Definition at line 55 of file ra8_usb_device.c.
Referenced by ra8_usb_device_init().
| volatile uint16_t g_syscfg_before_dprpu = 0U |
SYSCFG snapshot captured immediately BEFORE the DPRPU write.
Bisect probe; expected: 0x0181 (USBE | CNEN | HSE) on the HS instance after the CNEN-then-DPRPU split that aligns with HUM Ch 37.3.3 Figure 37.2 p 2121 ("Resistor control: set SYSCFG.DPRPU and SYSCFG.DRPD" comes AFTER "Enable USB operation: set SYSCFG.USBE = 1" and AFTER the CNEN single-end-receiver enable).
Definition at line 130 of file ra8_usb_device.c.
Referenced by ra8_usb_device_attach().
| volatile uint16_t g_syssts0_after_attach = 0U |
SYSSTS0 snapshot captured at the end of ra8_usb_device_attach(true).
Bisect probe; this is the LOAD-BEARING readback for the HS device-mode attach gate. Per HUM Ch 37.2.3 SYSSTS0 p 2063 and Table 37.4 p 2064:
Expected post-attach value with HS cable plugged: 0x0001 (LNST=01, J-state) – the host then issues a USB bus reset within ~100 ms, after which DVST fires and FRMNUM begins incrementing.
Per HUM Ch 37.2.1 SYSCFG description on p 2062 (CNEN bit), LNST reads as SE0 unless SYSCFG.CNEN=1 in device-mode – the single-end receivers must be powered before the line state is observable.
Definition at line 115 of file ra8_usb_device.c.
Referenced by ra8_usb_device_attach().
|
static |
Definition at line 35 of file ra8_usb_device.c.