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

USB host-mode bulk-transfer engine (polled, synchronous). More...

#include <stdint.h>
#include "ra8_attributes.h"
#include "ra8_check.h"
#include "ra8_err.h"
#include "ra8_usb.h"
#include "ra8_usb_internal.h"
#include "ra8_usb_regs.h"
Include dependency graph for ra8_usb_host_bulk.c:

Go to the source code of this file.

Enumerations

enum  ra8_usb_host_bulk_lim_t : uint32_t { k_ra8_usb_bulk_poll_limit = 10000000UL }
 Spin bound for bulk-pipe waits (covers media access latency). More...

Functions

static ra8_err_t internal_host_wait_pipe (volatile const r_usb_regs_t *reg, volatile const uint16_t *sts, uint8_t pipe_num)
 Spin until a pipe's W0C status bit asserts, with STALL detection.
ra8_err_t ra8_usb_host_set_target (ra8_usb_speed_t speed, uint8_t dev_addr)
 Implementation of ra8_usb_host_set_target().
static ra8_err_t internal_host_pipe_args_ok (uint8_t pipe_num, uint8_t dev_addr, uint8_t ep_num, uint16_t max_packet)
 Validate the argument set for ra8_usb_host_pipe_setup.
ra8_err_t ra8_usb_host_pipe_setup (ra8_usb_speed_t speed, uint8_t pipe_num, uint8_t dev_addr, uint8_t ep_num, bool device_to_host, uint16_t max_packet)
 Implementation of ra8_usb_host_pipe_setup().
ra8_err_t ra8_usb_host_bulk_out (ra8_usb_speed_t speed, uint8_t pipe_num, const uint8_t *data, uint16_t len)
 Implementation of ra8_usb_host_bulk_out().
static ra8_err_t internal_host_bulk_rx_packet (volatile r_usb_regs_t *reg, uint8_t pipe_num, uint8_t *dst, uint16_t room, uint16_t *out_dtln, uint16_t *out_copied)
 Receive one bulk packet from an armed IN pipe into dst.
static ra8_err_t internal_host_bulk_rx_loop (volatile r_usb_regs_t *reg, uint8_t pipe_num, uint8_t *buf, uint16_t max_len, uint16_t mps, uint16_t *out_rx)
 Consume bulk-IN packets until short packet, fill, or error.
ra8_err_t ra8_usb_host_bulk_in (ra8_usb_speed_t speed, uint8_t pipe_num, uint8_t *buf, uint16_t max_len, uint16_t *out_received)
 Implementation of ra8_usb_host_bulk_in().
uint16_t ra8_usb_host_line_state (ra8_usb_speed_t speed)
 Implementation of ra8_usb_host_line_state().

Variables

static const char * s_tag = "USB"

Detailed Description

USB host-mode bulk-transfer engine (polled, synchronous).

Tag
[Ring 3 / HAL] {World: NS}

Host-mode bulk-transfer engine plus the host pipe-setup / target-select helpers it builds on. Built on the same host signals the control engine validated on hardware – BRDY (a packet landed in the pipe buffer), BEMP (the pipe buffer emptied onto the wire), and PIPECTR.PID for STALL detection. Provides ra8_usb_host_set_target, ra8_usb_host_pipe_setup, ra8_usb_host_bulk_out / ra8_usb_host_bulk_in, and ra8_usb_host_line_state. Split out of ra8_usb.c so every translation unit stays under the 1000-line cap; the shared register helpers and host addressing enums it uses are declared in ra8_usb_internal.h. No FSP source ships in this tree.

Since
0.1.0

Definition in file ra8_usb_host_bulk.c.

Enumeration Type Documentation

◆ ra8_usb_host_bulk_lim_t

enum ra8_usb_host_bulk_lim_t : uint32_t

Spin bound for bulk-pipe waits (covers media access latency).

Enumerator
k_ra8_usb_bulk_poll_limit 

Spins per bulk stage wait.

Definition at line 48 of file ra8_usb_host_bulk.c.

Function Documentation

◆ internal_host_bulk_rx_loop()

ra8_err_t internal_host_bulk_rx_loop ( volatile r_usb_regs_t * reg,
uint8_t pipe_num,
uint8_t * buf,
uint16_t max_len,
uint16_t mps,
uint16_t * out_rx )
static

Consume bulk-IN packets until short packet, fill, or error.

Inner receive loop of ra8_usb_host_bulk_in, split out for the complexity gate. The pipe must already be armed (PID = BUF).

Parameters
[in]regSelected controller register block.
[in]pipe_numArmed IN pipe.
[out]bufDestination buffer.
[in]max_lenCapacity of buf in bytes.
[in]mpsPipe max packet size (short-packet threshold).
[out]out_rxReceives the byte count gathered.
Returns
First packet error, or k_ra8_ok at transfer end.
Return values
k_ra8_okTransfer ended by short packet or byte count.
Precondition
The pipe PID is BUF and BRDYENB carries the pipe bit.
buf holds at least max_len bytes.
Postcondition
out_rx holds the byte count even on error (partial count).
The pipe PID is unchanged (caller parks it).
Note
Helper split out for the clang-tidy size/complexity gate.
Since
0.1.0

Definition at line 368 of file ra8_usb_host_bulk.c.

References internal_host_bulk_rx_packet(), and k_ra8_ok.

Referenced by ra8_usb_host_bulk_in().

◆ internal_host_bulk_rx_packet()

ra8_err_t internal_host_bulk_rx_packet ( volatile r_usb_regs_t * reg,
uint8_t pipe_num,
uint8_t * dst,
uint16_t room,
uint16_t * out_dtln,
uint16_t * out_copied )
static

Receive one bulk packet from an armed IN pipe into dst.

Waits for the pipe BRDY, selects the pipe on the CFIFO port, reads DTLN bytes (clamped to room; any overflow remainder is dropped with BCLR, and a zero-length packet is released with BCLR), then clears the BRDY status for the next packet.

Parameters
[in]regSelected controller register block.
[in]pipe_numArmed IN pipe (PID = BUF).
[out]dstDestination for this packet's bytes.
[in]roomBytes available at dst.
[out]out_dtlnReceives the packet length the device sent.
[out]out_copiedReceives the bytes actually copied to dst.
Returns
Packet outcome.
Return values
k_ra8_okOne packet consumed.
k_ra8_err_hw_errorThe device STALLed the endpoint.
k_ra8_err_hw_timeoutNo packet before the spin bound.
Precondition
The pipe PID is BUF and BRDYENB carries the pipe bit.
dst holds at least room bytes.
Postcondition
The pipe buffer is released and BRDY is cleared.
out_dtln / out_copied describe the packet.
Note
Helper split out for the clang-tidy size/complexity gate.
Since
0.1.0

Definition at line 305 of file ra8_usb_host_bulk.c.

References r_usb_regs_t::BRDYSTS, r_usb_regs_t::CFIFOCTR, internal_host_wait_pipe(), k_ra8_fifoctr_bclr, k_ra8_fifoctr_dtln, k_ra8_ok, priv_fifo_read(), priv_select_cfifo(), and priv_wait_frdy().

Referenced by internal_host_bulk_rx_loop().

◆ internal_host_pipe_args_ok()

ra8_err_t internal_host_pipe_args_ok ( uint8_t pipe_num,
uint8_t dev_addr,
uint8_t ep_num,
uint16_t max_packet )
static

Validate the argument set for ra8_usb_host_pipe_setup.

Range-checks the pipe number, device address, endpoint number, and max-packet size against the controller limits so the setup body can stay small enough for the complexity gate.

Parameters
[in]pipe_numController pipe (1..k_ra8_usb_max_pipe_num).
[in]dev_addrTarget device address (0..k_ra8_usb_dev_addr_max).
[in]ep_numDevice endpoint number (1..15).
[in]max_packetEndpoint wMaxPacketSize (1..PIPEMAXP MXPS range).
Returns
Validation outcome.
Return values
k_ra8_okAll arguments are in range.
k_ra8_err_invalid_argAny argument is out of range.
Precondition
None (pure argument validation).
Caller passes the same values it will program.
Postcondition
No state is modified.
On k_ra8_ok the values are safe to write into PIPECFG/PIPEMAXP.
Note
Helper split out for the clang-tidy size/complexity gate.
Since
0.1.0

Definition at line 151 of file ra8_usb_host_bulk.c.

References k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pipecfg_epnum_mask, k_ra8_usb_dev_addr_max, k_ra8_usb_max_pipe_num, and k_ra8_usb_pipemaxp_mxps.

Referenced by ra8_usb_host_pipe_setup().

◆ internal_host_wait_pipe()

ra8_err_t internal_host_wait_pipe ( volatile const r_usb_regs_t * reg,
volatile const uint16_t * sts,
uint8_t pipe_num )
static

Spin until a pipe's W0C status bit asserts, with STALL detection.

Bounded busy-wait over BRDYSTS/BEMPSTS for one pipe. While waiting, watches the pipe's PIPECTR.PID field: a transition to either STALL encoding (PID[1] set) means the device rejected the transfer, which is reported distinctly from a timeout so MSC error handling can react.

Parameters
[in]regSelected controller register block.
[in]stsStatus register to watch (BRDYSTS or BEMPSTS).
[in]pipe_numPipe whose bit (1 << pipe_num) is awaited.
Returns
Wait outcome.
Return values
k_ra8_okThe status bit asserted.
k_ra8_err_hw_errorThe device STALLed the endpoint.
k_ra8_err_hw_timeoutNo event before the spin bound elapsed.
Precondition
The pipe is configured and its transfer has been armed.
The matching ENB bit is set so the status can latch.
Postcondition
No register is modified by this function.
On STALL the pipe PID still reads the STALL encoding for the caller.
Note
Bounded by k_ra8_usb_bulk_poll_limit (covers media access latency).
Since
0.1.0

Definition at line 78 of file ra8_usb_host_bulk.c.

References k_ra8_err_hw_error, k_ra8_err_hw_timeout, k_ra8_ok, k_ra8_usb_bulk_poll_limit, k_ra8_usb_pid_stall_bit, and r_usb_regs_t::PIPECTR.

Referenced by internal_host_bulk_rx_packet(), and ra8_usb_host_bulk_out().

◆ ra8_usb_host_bulk_in()

ra8_err_t ra8_usb_host_bulk_in ( ra8_usb_speed_t speed,
uint8_t pipe_num,
uint8_t * buf,
uint16_t max_len,
uint16_t * out_received )
nodiscard

Implementation of ra8_usb_host_bulk_in().

Receive a bulk transfer from the device into buf.

See the public header for the documented contract; arms the IN pipe (PID=BUF so the SIE issues IN tokens) and consumes packets via internal_host_bulk_rx_packet until a short packet ends the transfer or max_len bytes have been gathered, then parks the pipe NAK.

Parameters
[in]speedSee header.
[in]pipe_numSee header.
[out]bufSee header.
[in]max_lenSee header.
[out]out_receivedSee header.
Returns
Result code.
Return values
k_ra8_okTransfer ended by short packet or byte count.
Precondition
Module state is consistent.
The pipe was configured by ra8_usb_host_pipe_setup.
Postcondition
The pipe PID is NAK; out_received holds the byte count.
On error the partial count received so far is still reported.
Note
Not thread-safe.
Since
0.1.0

Definition at line 424 of file ra8_usb_host_bulk.c.

References r_usb_regs_t::BRDYENB, internal_host_bulk_rx_loop(), k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_pid_buf, k_ra8_pid_nak, k_ra8_usb_max_pipe_num, k_ra8_usb_pipemaxp_mxps, r_usb_regs_t::PIPEMAXP, r_usb_regs_t::PIPESEL, priv_pick(), priv_pipe_pid(), RA8_CHECK_NULL_PTR, and s_tag.

Referenced by cdc_echo_round(), hid_read_round(), hid_read_round(), internal_recv_bytes(), and ns_host_echo_round().

◆ ra8_usb_host_bulk_out()

ra8_err_t ra8_usb_host_bulk_out ( ra8_usb_speed_t speed,
uint8_t pipe_num,
const uint8_t * data,
uint16_t len )
nodiscard

Implementation of ra8_usb_host_bulk_out().

Transmit one bulk packet to the device and wait for the ACK.

See the public header for the documented contract; pushes one packet (up to the pipe MPS) through the pipe buffer via ra8_usb_queue_in (wait FRDY, FIFO write, BVAL, PID=BUF) and waits for the buffer-empty (BEMP) event that marks the packet transmitted and ACKed, then parks the pipe NAK.

Parameters
[in]speedSee header.
[in]pipe_numSee header.
[in]dataSee header.
[in]lenSee header.
Returns
Result code.
Return values
k_ra8_okPacket transmitted and acknowledged.
Precondition
Module state is consistent.
The pipe was configured by ra8_usb_host_pipe_setup.
Postcondition
The pipe PID is NAK and its BEMP status is cleared.
On k_ra8_ok the device has ACKed the packet.
Note
Not thread-safe.
Since
0.1.0

Definition at line 253 of file ra8_usb_host_bulk.c.

References r_usb_regs_t::BEMPENB, r_usb_regs_t::BEMPSTS, internal_host_wait_pipe(), k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_pid_nak, k_ra8_usb_max_pipe_num, priv_pick(), priv_pipe_pid(), RA8_CHECK_NULL_PTR, ra8_usb_queue_in(), and s_tag.

Referenced by cdc_echo_round(), internal_run_data_out(), internal_send_cbw(), and ns_host_echo_round().

◆ ra8_usb_host_line_state()

uint16_t ra8_usb_host_line_state ( ra8_usb_speed_t speed)

Implementation of ra8_usb_host_line_state().

Read the host port's D+/D- line state (SYSSTS0.LNST).

Pure MMIO read of SYSSTS0.LNST; no state is modified.

Parameters
[in]speedSee header.
Returns
LNST[1:0] (0 = SE0 / nothing attached, 1 = J-state).
Return values
0Invalid speed, controller not powered, or SE0.
Precondition
Module state is consistent.
The controller is clocked for a meaningful read.
Postcondition
No register is modified.
Caller-visible state matches the documented contract.
Note
Safe to call from any context.
Since
0.1.0

Definition at line 476 of file ra8_usb_host_bulk.c.

References k_ra8_usb_lnst_mask, priv_pick(), and r_usb_regs_t::SYSSTS0.

Referenced by cdc_enum_hunt(), dfu_enum_hunt(), hid_enum_hunt(), hid_enum_hunt(), internal_enum_hunt(), internal_enum_hunt(), and ns_host_enum_hunt().

◆ ra8_usb_host_pipe_setup()

ra8_err_t ra8_usb_host_pipe_setup ( ra8_usb_speed_t speed,
uint8_t pipe_num,
uint8_t dev_addr,
uint8_t ep_num,
bool device_to_host,
uint16_t max_packet )
nodiscard

Implementation of ra8_usb_host_pipe_setup().

Configure a controller pipe against an attached device's bulk endpoint.

See the public header for the documented contract; configures a bulk pipe against an attached device's endpoint. In host mode PIPECFG.DIR keeps its transmit/receive sense: receiving (device-to-host IN) is DIR=0 and transmitting (host-to-device OUT) is DIR=1, so the device-mode encoder is reused with the mapped direction. PIPEnCTR shares the DCPCTR SQCLR bit layout.

Parameters
[in]speedSee header.
[in]pipe_numSee header.
[in]dev_addrSee header.
[in]ep_numSee header.
[in]device_to_hostSee header.
[in]max_packetSee header.
Returns
Result code.
Return values
k_ra8_okPipe configured, DATA0 forced, parked NAK.
Precondition
Module state is consistent.
SET_CONFIGURATION has reset the device endpoint to DATA0.
Postcondition
The pipe targets dev_addr endpoint ep_num, PID = NAK.
The pipe's BRDY/NRDY/BEMP status bits are cleared.
Note
Not thread-safe.
Since
0.1.0

Definition at line 200 of file ra8_usb_host_bulk.c.

References r_usb_regs_t::BEMPSTS, r_usb_regs_t::BRDYSTS, internal_host_pipe_args_ok(), k_ra8_dcpctr_bit_sqclr, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_devsel_shift, k_ra8_usb_ep_dir_in, k_ra8_usb_ep_dir_out, k_ra8_usb_ep_type_bulk, k_ra8_usb_pipemaxp_mxps, r_usb_regs_t::NRDYSTS, r_usb_regs_t::PIPEBUF, r_usb_regs_t::PIPECFG, r_usb_regs_t::PIPECTR, r_usb_regs_t::PIPEMAXP, r_usb_regs_t::PIPEPERI, r_usb_regs_t::PIPESEL, priv_pick(), priv_pipe_quiesce(), priv_pipebuf_word(), priv_pipecfg_word(), and priv_rmw16().

Referenced by cdc_open_pipes(), hid_open_pipes(), hid_open_pipes(), internal_enum_configure(), and ns_host_open_pipes().

◆ ra8_usb_host_set_target()

ra8_err_t ra8_usb_host_set_target ( ra8_usb_speed_t speed,
uint8_t dev_addr )
nodiscard

Implementation of ra8_usb_host_set_target().

Retarget the host's default control pipe at a device address.

See the public header for the documented contract; programs the DEVADDn slot for dev_addr from the live RHST and retargets the DCP by loading DCPMAXP.DEVSEL while preserving MXPS.

Parameters
[in]speedSee header.
[in]dev_addrSee header.
Returns
Result code.
Return values
k_ra8_okTarget address applied.
Precondition
Module state is consistent.
The DCP is idle (no SUREQ pending).
Postcondition
DCPMAXP.DEVSEL = dev_addr; DEVADDn carries the link speed.
Subsequent control transfers address dev_addr.
Note
Not thread-safe.
Since
0.1.0

Definition at line 112 of file ra8_usb_host_bulk.c.

References r_usb_regs_t::DCPMAXP, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_dcpmaxp_mxps, k_ra8_usb_dev_addr_max, k_ra8_usb_devsel_shift, priv_host_program_devadd(), and priv_pick().

Referenced by cdc_enum_hunt(), cdc_enum_set_address(), dfu_enum_hunt(), dfu_enum_set_address(), hid_enum_hunt(), hid_enum_hunt(), hid_enum_set_address(), hid_enum_set_address(), internal_enum_assign_addr(), internal_enum_hunt(), internal_enum_hunt(), internal_set_address(), ns_host_enum_hunt(), and ns_host_set_address().

Variable Documentation

◆ s_tag

const char* s_tag = "USB"
static

Definition at line 34 of file ra8_usb_host_bulk.c.