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

Native USB device-side Audio (UAC) class layer. More...

#include <stdint.h>
#include "ra8_err.h"
#include "ra8_usb.h"
Include dependency graph for ra8_usb_paud.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ra8_usb_paud_format_t
 Current iso stream format negotiated with the host. More...

Typedefs

typedef ra8_err_t(* ra8_usb_paud_setup_fn_t) (void *ctx, const ra8_usb_setup_t *setup)
 Caller-supplied audio class-setup handler signature.

Enumerations

enum  ra8_usb_paud_pipe_t : uint8_t {
  k_ra8_paud_pipe_iso_in = 1U ,
  k_ra8_paud_pipe_iso_out = 2U
}
 PIPE numbers used by the device-Audio function for the local isochronous endpoints. More...
enum  ra8_usb_paud_ep_t : uint8_t {
  k_ra8_paud_ep_iso_in_addr = 1U ,
  k_ra8_paud_ep_iso_out_addr = 2U
}
 USB endpoint addresses used by the device-Audio function. More...
enum  ra8_usb_paud_packet_t : uint16_t {
  k_ra8_paud_iso_max_packet_fs_default = 192U ,
  k_ra8_paud_iso_max_packet_fs = 1023U ,
  k_ra8_paud_iso_max_packet_hs = 1024U
}
 Packet sizing for the iso endpoints. More...
enum  ra8_usb_paud_class_t : uint8_t {
  k_ra8_paud_class_audio = 0x01U ,
  k_ra8_paud_subclass_control = 0x01U ,
  k_ra8_paud_subclass_streaming = 0x02U ,
  k_ra8_paud_protocol_none = 0x00U
}
 Class / subclass / protocol triplet that identifies the local Audio function in the configuration descriptor. More...
enum  ra8_usb_paud_request_t : uint8_t {
  k_ra8_paud_req_set_cur = 0x01U ,
  k_ra8_paud_req_get_cur = 0x81U ,
  k_ra8_paud_req_set_min = 0x02U ,
  k_ra8_paud_req_get_min = 0x82U ,
  k_ra8_paud_req_set_max = 0x03U ,
  k_ra8_paud_req_get_max = 0x83U ,
  k_ra8_paud_req_set_res = 0x04U ,
  k_ra8_paud_req_get_res = 0x84U ,
  k_ra8_paud_req_get_stat = 0xFFU
}
 Audio class-specific request codes the host issues to the device. More...
enum  ra8_usb_paud_control_sel_t : uint8_t {
  k_ra8_paud_ctl_mute = 0x01U ,
  k_ra8_paud_ctl_volume = 0x02U ,
  k_ra8_paud_ctl_sample_rate = 0x01U
}
 Feature-unit / endpoint control selectors carried in the high byte of wValue. More...

Functions

ra8_err_t ra8_usb_paud_init (ra8_usb_speed_t speed)
 Bring up the device-Audio function on a chosen USB controller.
ra8_err_t ra8_usb_paud_close (void)
 Tear down the device-Audio function and release the controller.
ra8_err_t ra8_usb_paud_set_descriptors (const uint8_t *desc, uint16_t desc_len)
 Install the caller-supplied audio descriptor blob.
ra8_err_t ra8_usb_paud_send_frame (const uint8_t *frame, uint16_t len)
 Push a captured audio frame on the iso-IN endpoint.
ra8_err_t ra8_usb_paud_recv_frame (uint8_t *buf, uint16_t max_len, uint16_t *got_len)
 Drain a playback audio frame from the iso-OUT endpoint.
ra8_err_t ra8_usb_paud_set_format (ra8_usb_paud_format_t format)
 Apply a SET_CUR(sampling-frequency) shadow update.
ra8_err_t ra8_usb_paud_get_format (ra8_usb_paud_format_t *out_format)
 Read the current iso stream format.
ra8_err_t ra8_usb_paud_set_volume (int16_t volume_q8_8)
 Apply a SET_CUR(volume) shadow update on the feature unit.
ra8_err_t ra8_usb_paud_get_volume (int16_t *out_volume)
 Read the current feature-unit volume.
ra8_err_t ra8_usb_paud_attach_setup_handler (ra8_usb_paud_setup_fn_t setup_fn, void *ctx)
 Register the application's audio class-setup handler.
ra8_err_t ra8_usb_paud_handle_setup (const ra8_usb_setup_t *setup)
 Process a class-specific SETUP packet on EP0.

Detailed Description

Native USB device-side Audio (UAC) class layer.

Glues the device-mode ra8_usb controller driver to a USB Audio Class 1.0 function so the EK-RA8D2 enumerates as a microphone (iso IN) or speaker (iso OUT) gadget. The implementation is from-scratch; FSP r_usb_paud_driver.c is reference material only – nothing is pulled in verbatim. Mirrors the surface that FSP's peripheral-Audio class exposes:

  • Caller-supplied audio descriptor blob (interface association, AC interface header, AC input / output / feature units, AS interface alt-settings, AS general + format-type CS interface descriptors, plus iso EP descriptors).
  • One iso-IN pipe (PIPE1) for capture (microphone).
  • One iso-OUT pipe (PIPE2) for playback (speaker).
  • SET_CUR / GET_CUR shadow for current sample-rate (sampling-frequency control on the iso endpoint) and feature-unit volume / mute.
  • Caller-supplied class-setup callback so the application picks the rate / volume policy (e.g. clamp to USB-IF audio rates 8 / 16 / 44.1 / 48 / 96 kHz, or follow the host without question).

Reference: USB Device Class Definition for Audio Devices revision 1.0 (USB-IF, 1998-03-18) – specifically:

  • sec 4.3.2.5 "Class-Specific AS Interface Descriptor"
  • sec 5.2.1 "Request Layout" (SET_CUR / GET_CUR / GET_MIN / ...)
  • sec A.9 "Audio Class-Specific Request Codes"

Definition in file ra8_usb_paud.h.

Typedef Documentation

◆ ra8_usb_paud_setup_fn_t

typedef ra8_err_t(* ra8_usb_paud_setup_fn_t) (void *ctx, const ra8_usb_setup_t *setup)

Caller-supplied audio class-setup handler signature.

The class layer pre-decodes the SETUP envelope (validates it really is an audio class request to the local AC / AS interface or to one of the iso EPs) and hands the SETUP packet to the application. The callback can update *format (e.g. when SET_CUR on the sampling-frequency control fires) or queue a data-stage payload for GET_CUR responses.

Parameters
[in]ctxCaller-supplied context registered alongside the handler.
[in]setupThe 8-byte SETUP envelope (class request).
Returns
ra8_err_t error code; k_ra8_ok lets the class layer ACK the status stage, anything else stalls EP0.
Note
Invoked from the dispatch site (typically ISR context) when an audio class SETUP lands.

Definition at line 178 of file ra8_usb_paud.h.

Enumeration Type Documentation

◆ ra8_usb_paud_class_t

enum ra8_usb_paud_class_t : uint8_t

Class / subclass / protocol triplet that identifies the local Audio function in the configuration descriptor.

USB Audio 1.0 sec A.1 "Audio Interface Class Code" and A.2 "Audio Interface Subclass Codes".

Enumerator
k_ra8_paud_class_audio 

Audio interface class.

k_ra8_paud_subclass_control 

AudioControl Subclass.

k_ra8_paud_subclass_streaming 

AudioStreaming Subclass.

k_ra8_paud_protocol_none 

No protocol (UAC1).

Definition at line 99 of file ra8_usb_paud.h.

◆ ra8_usb_paud_control_sel_t

Feature-unit / endpoint control selectors carried in the high byte of wValue.

Per USB Audio 1.0 sec 5.2.2.4.3 "Feature Unit Control Selectors" and sec 5.2.3.2.3.1 "Sampling Frequency Control".

Enumerator
k_ra8_paud_ctl_mute 

Mute Control.

k_ra8_paud_ctl_volume 

Volume Control.

k_ra8_paud_ctl_sample_rate 

Sampling Frequency Control.

Definition at line 135 of file ra8_usb_paud.h.

◆ ra8_usb_paud_ep_t

enum ra8_usb_paud_ep_t : uint8_t

USB endpoint addresses used by the device-Audio function.

Enumerator
k_ra8_paud_ep_iso_in_addr 

EP1 IN address.

k_ra8_paud_ep_iso_out_addr 

EP2 OUT address.

Definition at line 71 of file ra8_usb_paud.h.

◆ ra8_usb_paud_packet_t

enum ra8_usb_paud_packet_t : uint16_t

Packet sizing for the iso endpoints.

Per USB 2.0 sec 5.6.3 "Isochronous Transfer Bus Access Constraints", FS iso pipes top out at 1023 bytes / frame and HS at 1024 bytes / microframe. A typical 48 kHz / 16-bit / stereo capture stream is 192 bytes per FS frame (48 samples * 2 ch * 2 bytes).

Enumerator
k_ra8_paud_iso_max_packet_fs_default 

48 kHz stereo 16-bit.

k_ra8_paud_iso_max_packet_fs 

FS iso ceiling.

k_ra8_paud_iso_max_packet_hs 

HS iso ceiling.

Definition at line 85 of file ra8_usb_paud.h.

◆ ra8_usb_paud_pipe_t

enum ra8_usb_paud_pipe_t : uint8_t

PIPE numbers used by the device-Audio function for the local isochronous endpoints.

FSP / RA8D2 PIPE assignment rules constrain isochronous pipes to PIPE1 / PIPE2. PIPE1 carries iso IN (microphone), PIPE2 carries iso OUT (speaker). USB Audio 1.0 sec 3.7.1 "Standard AS Isochronous Audio Data Endpoint Descriptor".

Enumerator
k_ra8_paud_pipe_iso_in 

PIPE1 -> EP1 IN (capture).

k_ra8_paud_pipe_iso_out 

PIPE2 -> EP2 OUT (playback).

Definition at line 62 of file ra8_usb_paud.h.

◆ ra8_usb_paud_request_t

enum ra8_usb_paud_request_t : uint8_t

Audio class-specific request codes the host issues to the device.

Per USB Audio 1.0 sec A.9 "Audio Class-Specific Request Codes". The class layer pre-decodes SET_CUR / GET_CUR / GET_MIN / GET_MAX / GET_RES and forwards them to the application callback.

Enumerator
k_ra8_paud_req_set_cur 

SET_CUR.

k_ra8_paud_req_get_cur 

GET_CUR.

k_ra8_paud_req_set_min 

SET_MIN.

k_ra8_paud_req_get_min 

GET_MIN.

k_ra8_paud_req_set_max 

SET_MAX.

k_ra8_paud_req_get_max 

GET_MAX.

k_ra8_paud_req_set_res 

SET_RES.

k_ra8_paud_req_get_res 

GET_RES.

k_ra8_paud_req_get_stat 

GET_STAT.

Definition at line 115 of file ra8_usb_paud.h.

Function Documentation

◆ ra8_usb_paud_attach_setup_handler()

ra8_err_t ra8_usb_paud_attach_setup_handler ( ra8_usb_paud_setup_fn_t setup_fn,
void * ctx )
nodiscard

Register the application's audio class-setup handler.

Pass NULL for setup_fn to detach. The class layer drains the SETUP envelope from the controller and forwards it if its bmRequestType indicates a class-recipient-interface or class-recipient-endpoint request and its bRequest is one of the audio class request codes (USB Audio 1.0 sec A.9).

Parameters
[in]setup_fnApplication's handler. NULL detaches.
[in]ctxContext pointer threaded back into setup_fn.
Returns
ra8_err_t error code.
Return values
k_ra8_okHandler installed.
k_ra8_err_invalid_stateDriver not initialized.
Precondition
ra8_usb_paud_init succeeded.
Postcondition
On the next class SETUP, setup_fn(ctx, &setup) fires.
Note
Not thread-safe.
Since
0.1.0

Definition at line 397 of file ra8_usb_paud.c.

References k_ra8_err_invalid_state, k_ra8_ok, and s_state.

◆ ra8_usb_paud_close()

ra8_err_t ra8_usb_paud_close ( void )
nodiscard

Tear down the device-Audio function and release the controller.

Returns
ra8_err_t error code.
Return values
k_ra8_okReleased.
k_ra8_err_invalid_stateDriver was never initialized.
Precondition
Single-threaded shutdown context.
Postcondition
ra8_usb_device_deinit ran; D+ pull-up dropped; subsequent device-Audio API calls return k_ra8_err_invalid_state.
Note
Not thread-safe.
Since
0.1.0

Definition at line 265 of file ra8_usb_paud.c.

References k_ra8_err_invalid_state, ra8_usb_device_attach(), ra8_usb_device_deinit(), and s_state.

◆ ra8_usb_paud_get_format()

ra8_err_t ra8_usb_paud_get_format ( ra8_usb_paud_format_t * out_format)
nodiscard

Read the current iso stream format.

Parameters
[out]out_formatReceives the current format.
Returns
ra8_err_t error code.
Return values
k_ra8_okValue copied.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrout_format was NULL.
Precondition
out_format non-NULL.
Postcondition
No internal state mutated.
Note
Not thread-safe.
Since
0.1.0

Definition at line 363 of file ra8_usb_paud.c.

References k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.

◆ ra8_usb_paud_get_volume()

ra8_err_t ra8_usb_paud_get_volume ( int16_t * out_volume)
nodiscard

Read the current feature-unit volume.

Parameters
[out]out_volumeReceives the current volume in Q8.8 dB.
Returns
ra8_err_t error code.
Return values
k_ra8_okValue copied.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrout_volume was NULL.
Precondition
out_volume non-NULL.
Postcondition
No internal state mutated.
Note
Not thread-safe.
Since
0.1.0

Definition at line 382 of file ra8_usb_paud.c.

References k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.

◆ ra8_usb_paud_handle_setup()

ra8_err_t ra8_usb_paud_handle_setup ( const ra8_usb_setup_t * setup)
nodiscard

Process a class-specific SETUP packet on EP0.

Switches on b_request and forwards the SETUP to the registered application handler if any. Standard (non-class) SETUPs are rejected with k_ra8_err_not_supported so the caller can fall back to its own standard-request handler.

Parameters
[in]setupThe SETUP packet returned by ra8_usb_read_setup_if_valid.
Returns
ra8_err_t error code.
Return values
k_ra8_okSETUP handled (status stage queued internally).
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrsetup was NULL.
k_ra8_err_not_supportedbRequest is not an audio class request this layer cares about.
Precondition
ra8_usb_paud_init succeeded.
Postcondition
Internal shadows may have been updated by the callback.
Note
Call from the CTRT ISR path of ra8_usb.
Since
0.1.0

Definition at line 412 of file ra8_usb_paud.c.

References ra8_usb_setup_t::b_request, ra8_usb_setup_t::bm_request_type, internal_is_class_envelope(), internal_is_known_class_request(), k_ra8_err_invalid_state, k_ra8_err_not_supported, k_ra8_ok, RA8_CHECK_NULL_PTR, ra8_usb_control_response(), s_state, and s_tag.

◆ ra8_usb_paud_init()

ra8_err_t ra8_usb_paud_init ( ra8_usb_speed_t speed)
nodiscard

Bring up the device-Audio function on a chosen USB controller.

Initialises the underlying ra8_usb driver in DEVICE mode for speed, configures PIPE1 (iso IN) and PIPE2 (iso OUT), seeds the format shadow to 48 kHz / stereo / 16-bit, and leaves the D+ pull-up dropped. The caller raises it via ra8_usb_device_attach once descriptors are set.

Parameters
[in]speedWhich USB controller (FS or HS).
Returns
ra8_err_t error code.
Return values
k_ra8_okDevice-Audio ready.
k_ra8_err_invalid_argspeed out of range.
k_ra8_err_hw_init_failedUnderlying ra8_usb_device_init failed.
Precondition
Single-threaded init context.
ra8_mstp_init and ra8_pwr_init already ran.
Postcondition
Internal state machine armed; descriptor pointer cleared.
Pipe1 / pipe2 configured at the speed's default packet size.
Note
Not thread-safe.
See also
ra8_usb_paud_set_descriptors
ra8_usb_paud_close
Since
0.1.0

Definition at line 247 of file ra8_usb_paud.c.

References internal_configure_pipes(), internal_reset_shadow(), k_ra8_err_hw_init_failed, k_ra8_err_invalid_arg, k_ra8_ok, k_ra8_usb_speed_fs, k_ra8_usb_speed_hs, ra8_log_error_val, ra8_log_info_val, ra8_usb_device_init(), s_state, and s_tag.

Referenced by internal_usb_audio_usb_or_halt().

◆ ra8_usb_paud_recv_frame()

ra8_err_t ra8_usb_paud_recv_frame ( uint8_t * buf,
uint16_t max_len,
uint16_t * got_len )
nodiscard

Drain a playback audio frame from the iso-OUT endpoint.

Parameters
[out]bufReceive buffer.
[in]max_lenCapacity of buf, > 0.
[out]got_lenReceives the number of bytes actually placed.
Returns
ra8_err_t error code.
Return values
k_ra8_okBytes drained.
k_ra8_err_no_dataPipe was empty.
k_ra8_err_null_ptrbuf or got_len was NULL.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_invalid_argmax_len == 0.
Precondition
ra8_usb_paud_init succeeded.
Postcondition
On success *got_len reflects the actual byte count.
Note
Not thread-safe.
Since
0.1.0

Definition at line 317 of file ra8_usb_paud.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_paud_pipe_iso_out, RA8_CHECK_NULL_PTR, ra8_usb_queue_out(), s_state, and s_tag.

◆ ra8_usb_paud_send_frame()

ra8_err_t ra8_usb_paud_send_frame ( const uint8_t * frame,
uint16_t len )
nodiscard

Push a captured audio frame on the iso-IN endpoint.

Queues len bytes onto PIPE1. The caller is responsible for sample alignment (e.g. integer multiple of channels * bytes_per_sample) and for not exceeding the configured pipe max-packet.

Parameters
[in]frameAudio frame buffer.
[in]lenFrame byte length.
Returns
ra8_err_t error code.
Return values
k_ra8_okBytes queued onto iso-IN.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrframe was NULL with len > 0.
k_ra8_err_invalid_arglen == 0 or larger than the pipe max.
Precondition
ra8_usb_paud_init succeeded.
Postcondition
len bytes sit on PIPE1.
Note
Not thread-safe.
Since
0.1.0

Definition at line 303 of file ra8_usb_paud.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_err_null_ptr, k_ra8_paud_pipe_iso_in, ra8_usb_queue_in(), and s_state.

Referenced by internal_usb_audio_send_one_frame().

◆ ra8_usb_paud_set_descriptors()

ra8_err_t ra8_usb_paud_set_descriptors ( const uint8_t * desc,
uint16_t desc_len )
nodiscard

Install the caller-supplied audio descriptor blob.

The class layer keeps a pointer + length pair; the application owns the storage. The descriptor blob is the concatenation of: AudioControl interface header, input/output/feature units, an IAD, and AudioStreaming alt-settings + Format-Type-I + iso EP descriptors.

Parameters
[in]descPointer to the caller-owned descriptor blob.
[in]desc_lenByte length of desc.
Returns
ra8_err_t error code.
Return values
k_ra8_okPointer + length stored.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_null_ptrdesc was NULL.
k_ra8_err_invalid_argdesc_len was 0.
Precondition
ra8_usb_paud_init succeeded.
Postcondition
Subsequent GET_DESCRIPTOR(Configuration) requests can use this blob.
Note
Not thread-safe.
Since
0.1.0

Definition at line 284 of file ra8_usb_paud.c.

References k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, RA8_CHECK_NULL_PTR, s_state, and s_tag.

◆ ra8_usb_paud_set_format()

ra8_err_t ra8_usb_paud_set_format ( ra8_usb_paud_format_t format)
nodiscard

Apply a SET_CUR(sampling-frequency) shadow update.

Used by the class-setup callback (or directly by the application) to reflect a new sample-rate negotiated by the host. USB Audio 1.0 sec 5.2.3.2.3.1 "Sampling Frequency Control".

Parameters
[in]formatNew format triplet.
Returns
ra8_err_t error code.
Return values
k_ra8_okShadow updated.
k_ra8_err_invalid_stateDriver not initialized.
k_ra8_err_invalid_argFormat fields are zero / out of range.
Precondition
ra8_usb_paud_init succeeded.
Postcondition
ra8_usb_paud_get_format reflects the new value.
Note
Not thread-safe.
Since
0.1.0

Definition at line 343 of file ra8_usb_paud.c.

References ra8_usb_paud_format_t::bytes_per_sample, ra8_usb_paud_format_t::channels, k_ra8_err_invalid_arg, k_ra8_err_invalid_state, k_ra8_ok, k_ra8_paud_max_bps, k_ra8_paud_max_channels, k_ra8_paud_min_bps, k_ra8_paud_min_channels, s_state, and ra8_usb_paud_format_t::sample_rate_hz.

Referenced by internal_usb_audio_usb_or_halt().

◆ ra8_usb_paud_set_volume()

ra8_err_t ra8_usb_paud_set_volume ( int16_t volume_q8_8)
nodiscard

Apply a SET_CUR(volume) shadow update on the feature unit.

Volume on the audio feature unit is a 16-bit signed dB value with 1/256 dB resolution (USB Audio 1.0 sec 5.2.2.4.3.2 "Volume Control"). 0x8000 means "silence" / mute floor.

Parameters
[in]volume_q8_8New volume in Q8.8 dB format.
Returns
ra8_err_t error code.
Return values
k_ra8_okShadow updated.
k_ra8_err_invalid_stateDriver not initialized.
Precondition
ra8_usb_paud_init succeeded.
Postcondition
ra8_usb_paud_get_volume reflects the new value.
Note
Not thread-safe.
Since
0.1.0

Definition at line 373 of file ra8_usb_paud.c.

References k_ra8_err_invalid_state, k_ra8_ok, and s_state.

Referenced by internal_usb_audio_usb_or_halt().