66static const char*
s_tag =
"USB";
90typedef enum : uint32_t {
154void priv_rmw16(
volatile uint16_t* reg, uint16_t set_mask, uint16_t clr_mask)
156 const uint16_t old = *reg;
157 uint16_t new_val = (uint16_t)(old & (uint16_t)~clr_mask);
158 new_val = (uint16_t)(new_val | set_mask);
260#if defined(RA8_OFF_TARGET) && defined(UNIT_TEST)
262 if (ra8_fake_mmio_wait_eval(®->
CFIFOCTR, i, frdy)) {
311 const uint8_t idx = (uint8_t)(pipe_num - 1U);
357 const uint16_t blocks_per_pipe = (uint16_t)(mps_blocks * 2U);
358 const uint16_t bufsize_field = (uint16_t)(blocks_per_pipe - 1U);
359 const uint16_t bufnmb_field =
360 (uint16_t)(8U + (uint16_t)((uint16_t)(pipe_num - 1U) * blocks_per_pipe));
449 const uint16_t pipe_bit = (uint16_t)(1U << pipe_num);
465typedef enum : uint8_t {
489typedef uint32_t __attribute__((may_alias))
510 const uint16_t tail = (uint16_t)(len & 0x3U);
514 const uint16_t sel_save = reg->CFIFOSEL;
516 uint16_t offset = (uint16_t)(len & (uint16_t)~(uint16_t)0x3U);
527 volatile uint16_t*
const cfifoh = (
volatile uint16_t*)((uintptr_t)®->CFIFO + 2U);
528 volatile uint8_t*
const cfifohh = (
volatile uint8_t*)((uintptr_t)®->CFIFO + 3U);
529 if ((tail & 0x2U) != 0U) {
531 const uint16_t lo = (uint16_t)data[offset + 0U];
532 const uint16_t hi = (uint16_t)data[offset + 1U];
534 offset = (uint16_t)(offset + 2U);
536 if ((tail & 0x1U) != 0U) {
538 *cfifohh = data[offset];
540 reg->CFIFOSEL = sel_save;
563 const uint16_t quads = (uint16_t)(len >> 2U);
564 for (uint16_t i = 0U; i < quads; ++i) {
565 const uint32_t b0 = (uint32_t)data[(4U * i) + 0U];
566 const uint32_t b1 = (uint32_t)data[(4U * i) + 1U];
567 const uint32_t b2 = (uint32_t)data[(4U * i) + 2U];
568 const uint32_t b3 = (uint32_t)data[(4U * i) + 3U];
602 const uint16_t even = (uint16_t)(len >> 1U);
603 for (uint16_t i = 0U; i < even; ++i) {
604 const uint16_t lo = (uint16_t)data[(2U * i) + 0U];
605 const uint16_t hi = (uint16_t)data[(2U * i) + 1U];
608 if ((len & 1U) != 0U) {
613 const uint16_t sel_save = reg->
CFIFOSEL;
614 const uint16_t sel_8 =
616 volatile uint8_t*
const cfifo8 = (
volatile uint8_t*)(uintptr_t)®->
CFIFO;
618 *cfifo8 = data[len - 1U];
643 const uint16_t quads = (uint16_t)(len >> 2U);
644 for (uint16_t i = 0U; i < quads; ++i) {
645 const uint32_t word = *cfifo32;
671 const uint16_t tail = (uint16_t)(len & 0x3U);
684 const uint16_t off_base = (uint16_t)(len & (uint16_t)~(uint16_t)0x3U);
685 const uint8_t bytes[4] = {
691 for (uint16_t i = 0U; i < tail; ++i) {
692 data[off_base + i] = bytes[i];
721 const uint16_t even = (uint16_t)(len >> 1U);
722 for (uint16_t i = 0U; i < even; ++i) {
723 const uint16_t word = reg->
CFIFO;
727 if ((len & 1U) != 0U) {
730 const uint16_t sel_save = reg->
CFIFOSEL;
731 const uint16_t sel_8 =
733 volatile const uint8_t*
const cfifo8 = (
volatile uint8_t*)(uintptr_t)®->
CFIFO;
735 data[len - 1U] = *cfifo8;
static const char * s_tag
Logging / check tag.
Annotation-attribute framework macros for ra8-firmware.
#define RA8_INTERNAL
Marker that a function is intended to be static (file-local).
Validation and Error-Checking Macros for ra8-firmware.
#define RA8_RETURN_ON_ERROR(err, tag, message)
Early return on error, propagating the code upward.
Error Code Definitions for ra8-firmware.
@ k_ra8_err_hw_timeout
Hardware timed out waiting for a flag or handshake.
@ k_ra8_ok
Success – operation completed with all postconditions satisfied.
ra8_err_codes_t ra8_err_t
Canonical error-return type used by every ra8-firmware API.
Bounded wait-flag primitives for RA8D2 HAL drivers.
Ref-counted Module Stop Control wrapper for the RA8D2.
ra8_mstp_t
Packed (reg << 8) | bit module-stop identifier.
@ k_ra8_mstp_usbfs
MSTPB11 USBFS0.
@ k_ra8_mstp_usbhs
MSTPB12 USBHS.
static void internal_fifo_read_hs_tail(volatile r_usb_regs_t *reg, uint8_t *data, uint16_t len)
HS-only: read trailing 1..3 bytes from CFIFOH / CFIFOHH aliases.
static void internal_fifo_write_hs_tail(volatile r_usb_regs_t *reg, const uint8_t *data, uint16_t len)
HS-only: write the residual 0-3 bytes after 32-bit chunks.
void priv_fifo_write(volatile r_usb_regs_t *reg, const uint8_t *data, uint16_t len)
Push a byte buffer into the CFIFO data port.
static void internal_fifo_read_hs_head(volatile r_usb_regs_t *reg, uint8_t *data, uint16_t len)
HS-only: 32-bit CFIFO read loop for the head bytes.
ra8_usb_internal_lim32_t
32-bit driver-wide bounds (don't fit in uint16_t).
@ k_ra8_usb_fifosel_settle_limit
RA8 USB fifosel settle limit.
@ k_ra8_usb_frdy_poll_limit
Spin-loops before timeout.
@ k_ra8_usb_dblb_frdy_poll_limit
RA8 USB dblb frdy poll limit.
void priv_dcp_pid(volatile r_usb_regs_t *reg, ra8_usb_pid_t pid)
Set DCPCTR PID field to a specific value while preserving the rest of the register.
void priv_rmw16(volatile uint16_t *reg, uint16_t set_mask, uint16_t clr_mask)
Apply a generic read-modify-write to a 16-bit register.
void priv_select_cfifo(volatile r_usb_regs_t *reg, uint16_t pipe_num, bool is_in_dir)
Set CFIFOSEL.MBW + CURPIPE + ISEL for the given pipe / direction.
ra8_err_t priv_wait_frdy(volatile r_usb_regs_t *reg)
Spin until CFIFOCTR.FRDY asserts or a deadline elapses.
ra8_mstp_t priv_mstp(ra8_usb_speed_t speed)
Resolve the per-speed MSTP id.
volatile r_usb_regs_t * priv_pick(ra8_usb_speed_t speed)
Resolve the per-speed register pointer.
uint32_t ra8_usb_cfifo32_t
32-bit view of the CFIFO data port, permitted to alias the 16-bit CFIFO register lane.
bool priv_is_hs(volatile const r_usb_regs_t *reg)
Detect whether reg points at the USBHS (IP1) register block.
ra8_err_t priv_dcp_push_chunk(volatile r_usb_regs_t *reg, const uint8_t *p, uint16_t n)
Push a single DCP IN chunk: wait for FRDY, write FIFO, pulse BVAL.
uint16_t priv_pipebuf_word(uint8_t pipe_num, uint16_t max_packet)
Compute the PIPEBUF word for a bulk pipe (2*MPS region).
void priv_pipe_pid(volatile r_usb_regs_t *reg, uint8_t pipe_num, ra8_usb_pid_t pid)
Set PIPECTR[idx] PID field.
void priv_pipe_quiesce(volatile r_usb_regs_t *reg, uint8_t pipe_num)
Quiesce the pipe so PIPECFG/PIPEMAXP/PIPEPERI become writable.
void priv_fifo_read(volatile r_usb_regs_t *reg, uint8_t *data, uint16_t len)
Drain the CFIFO data port into a buffer.
ra8_usb_fifo_shift_t
Byte-shift constants for packing CFIFO writes.
@ k_ra8_usb_shift_b1
Shift for byte 1.
@ k_ra8_usb_shift_b2
Shift for byte 2.
@ k_ra8_usb_shift_b3
Shift for byte 3.
uint16_t priv_pipecfg_word(uint8_t ep_addr, ra8_usb_ep_dir_t dir, ra8_usb_ep_type_t type, bool dblb_in)
Pack PIPECFG fields for a configured non-control pipe.
static void internal_fifo_write_hs_head(volatile r_usb_regs_t *reg, const uint8_t *data, uint16_t len)
HS-only: 32-bit CFIFO write loop for the head bytes.
Native USB controller driver public API (device + host modes).
ra8_usb_ep_type_t
Transfer type for a non-control endpoint.
@ k_ra8_usb_ep_type_bulk
Bulk transfer.
@ k_ra8_usb_ep_type_intr
Interrupt transfer.
ra8_usb_ep_dir_t
Endpoint direction.
@ k_ra8_usb_ep_dir_in
Device -> host.
@ k_ra8_usb_ep_dir_out
Host -> device.
ra8_usb_speed_t
Selects which controller instance the call targets.
@ k_ra8_usb_speed_hs
High-Speed controller (USBHS @ 0x40351000).
@ k_ra8_usb_speed_fs
Full-Speed controller (USBFS @ 0x40250000).
Cross-TU surface for the ra8_usb driver split.
@ k_ra8_usb_byte_mask
Low byte of a 16-bit FIFO word.
@ k_ra8_usb_byte_bits
Bits per byte (shift constant).
USB Full-Speed + High-Speed controller layout for the Renesas RA8D2.
ra8_usb_pid_t
Response PID values written into the low two bits of DCPCTR / PIPECTR.
@ k_ra8_pid_nak
NAK response.
@ k_ra8_pid_mask
PID[1:0] field mask.
@ k_ra8_fifoctr_frdy
FIFO ready.
@ k_ra8_fifoctr_bval
Buffer valid.
@ k_ra8_pipebuf_block_bytes
Each buffer block is 64 bytes.
@ k_ra8_pipebuf_bufsize_shift
RA8 pipebuf bufsize shift.
@ k_ra8_pipebuf_bufnmb_mask
RA8 pipebuf bufnmb mask.
@ k_ra8_fifosel_mbw_msk
MBW field mask.
@ k_ra8_fifosel_mbw_32
32-bit FIFO access width.
@ k_ra8_fifosel_mbw_8
8-bit FIFO access width.
@ k_ra8_fifosel_isel
CFIFO direction (DCP only).
@ k_ra8_fifosel_mbw_16
16-bit FIFO access width.
@ k_ra8_fifosel_curpipe
Current pipe select [3:0].
static volatile r_usb_regs_t * ra8_usb_hs(void)
Get pointer to the USB HS controller register block.
@ k_ra8_pipecfg_epnum_mask
Endpoint number [3:0].
@ k_ra8_pipecfg_dir_in
1 = IN, 0 = OUT (peri).
@ k_ra8_pipecfg_type_intr
Type = interrupt.
@ k_ra8_pipecfg_dblb
Double-buffer mode.
@ k_ra8_pipecfg_shtnak
Auto NAK on short pkt.
@ k_ra8_pipecfg_type_bulk
Type = bulk.
@ k_ra8_pipecfg_type_iso
Type = isochronous.
static volatile r_usb_regs_t * ra8_usb_fs(void)
Compile-time offset and size insurance for r_usb_regs_t.
USB FS / HS register window (device-mode subset).
volatile uint16_t NRDYENB
+0x038 NRDY Interrupt Enable.
volatile uint16_t DCPCTR
+0x060 DCP Control.
volatile uint16_t CFIFOCTR
+0x022 Control FIFO control.
volatile uint16_t CFIFOSEL
+0x020 Control FIFO select.
volatile uint16_t PIPECTR[k_ra8_usb_pipectr_count]
+0x070 PIPE1..9 ctrl.
volatile uint16_t CFIFO
+0x014 Control FIFO data port.
volatile uint16_t BRDYENB
+0x036 BRDY Interrupt Enable.
volatile uint16_t BEMPENB
+0x03A BEMP Interrupt Enable.