|
ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
|
Native USB device-side Audio (UAC1) class layer implementation. More...
#include "ra8_usb_paud.h"#include <stdint.h>#include "ra8_attributes.h"#include "ra8_check.h"#include "ra8_err.h"#include "ra8_log.h"#include "ra8_usb.h"Go to the source code of this file.
Data Structures | |
| struct | ra8_usb_paud_state_t |
| Singleton shadow state for the device-Audio function. More... | |
Enumerations | |
| enum | ra8_usb_paud_setup_field_t : uint8_t { k_ra8_paud_bm_class_iface_in = 0xA1U , k_ra8_paud_bm_class_iface_out = 0x21U , k_ra8_paud_bm_class_ep_in = 0xA2U , k_ra8_paud_bm_class_ep_out = 0x22U } |
| Constants used to recognise audio class-specific SETUPs. More... | |
| enum | ra8_usb_paud_default_t : uint32_t { k_ra8_paud_default_rate_hz = 48000U , k_ra8_paud_default_channels = 2U , k_ra8_paud_default_bps = 2U , k_ra8_paud_default_volume = 0U } |
| Spec defaults the class layer seeds at init. More... | |
| enum | ra8_usb_paud_limit_t : uint8_t { k_ra8_paud_max_channels = 2U , k_ra8_paud_max_bps = 4U , k_ra8_paud_min_bps = 1U , k_ra8_paud_min_channels = 1U } |
| Format-shadow validation limits. More... | |
Functions | |
| static uint16_t | internal_iso_max_packet (ra8_usb_speed_t speed) |
| Pick the iso-max-packet ceiling matching the negotiated speed. | |
| static void | internal_configure_pipes (ra8_usb_speed_t speed) |
| Configure the two iso pipes. | |
| static void | internal_reset_shadow (ra8_usb_speed_t speed) |
| Reset shadow state to spec defaults. | |
| static bool | internal_is_known_class_request (uint8_t b_request) |
| Recognise an audio class request code we forward. | |
| static bool | internal_is_class_envelope (uint8_t bm) |
| Recognise an audio class request envelope. | |
| 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. | |
Variables | |
| static const char * | s_tag = "USBPAUD" |
| static ra8_usb_paud_state_t | s_state = {} |
Native USB device-side Audio (UAC1) class layer implementation.
Glues the device-mode ra8_usb driver to a USB Audio Class 1.0 function so the EK-RA8D2 enumerates as a microphone (iso IN), a speaker (iso OUT), or both. This file is the native peripheral-Audio class layer; FSP's r_usb_paud_driver.c is reference material only, nothing is pulled in verbatim.
Mapping vs FSP:
Reference: USB Audio 1.0 sec 5.2.1 "Request Layout" and sec A.9 "Audio Class-Specific Request Codes".
Definition in file ra8_usb_paud.c.
| enum ra8_usb_paud_default_t : uint32_t |
Spec defaults the class layer seeds at init.
48 kHz / stereo / 16-bit is the most common HID-class / UAC1 default for capture and playback gadgets.
| Enumerator | |
|---|---|
| k_ra8_paud_default_rate_hz | 48 kHz default rate. |
| k_ra8_paud_default_channels | Stereo default. |
| k_ra8_paud_default_bps | 16-bit default. |
| k_ra8_paud_default_volume | 0 dB volume default. |
Definition at line 69 of file ra8_usb_paud.c.
| enum ra8_usb_paud_limit_t : uint8_t |
Format-shadow validation limits.
| Enumerator | |
|---|---|
| k_ra8_paud_max_channels | Stereo cap. |
| k_ra8_paud_max_bps | 32-bit max sub-frame. |
| k_ra8_paud_min_bps | 8-bit min sub-frame. |
| k_ra8_paud_min_channels | Mono min. |
Definition at line 80 of file ra8_usb_paud.c.
| enum ra8_usb_paud_setup_field_t : uint8_t |
Constants used to recognise audio class-specific SETUPs.
Per USB Audio 1.0 sec 5.2 "Class-Specific Request" the standard envelopes are interface-recipient class (0x21 / 0xA1) for AC / AS interface controls and endpoint-recipient class (0x22 / 0xA2) for endpoint-controls (e.g. sampling-frequency).
| Enumerator | |
|---|---|
| k_ra8_paud_bm_class_iface_in | Class | Iface | In. |
| k_ra8_paud_bm_class_iface_out | Class | Iface | Out. |
| k_ra8_paud_bm_class_ep_in | Class | EP | In. |
| k_ra8_paud_bm_class_ep_out | Class | EP | Out. |
Definition at line 55 of file ra8_usb_paud.c.
|
static |
Configure the two iso pipes.
See implementation.
| [in] | speed | See implementation. |
Definition at line 150 of file ra8_usb_paud.c.
References internal_iso_max_packet(), k_ra8_paud_ep_iso_in_addr, k_ra8_paud_ep_iso_out_addr, k_ra8_paud_pipe_iso_in, k_ra8_paud_pipe_iso_out, k_ra8_usb_ep_dir_in, k_ra8_usb_ep_dir_out, k_ra8_usb_ep_type_iso, and ra8_usb_configure_endpoint().
|
static |
Recognise an audio class request envelope.
See implementation.
| [in] | bm | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 236 of file ra8_usb_paud.c.
References k_ra8_paud_bm_class_ep_in, k_ra8_paud_bm_class_ep_out, k_ra8_paud_bm_class_iface_in, and k_ra8_paud_bm_class_iface_out.
Referenced by ra8_usb_paud_handle_setup().
|
static |
Recognise an audio class request code we forward.
See implementation.
| [in] | b_request | See implementation. |
| k_ra8_ok | Operation succeeded. |
Definition at line 212 of file ra8_usb_paud.c.
References k_ra8_paud_req_get_cur, k_ra8_paud_req_get_max, k_ra8_paud_req_get_min, k_ra8_paud_req_get_res, k_ra8_paud_req_get_stat, k_ra8_paud_req_set_cur, k_ra8_paud_req_set_max, k_ra8_paud_req_set_min, and k_ra8_paud_req_set_res.
Referenced by ra8_usb_paud_handle_setup().
|
static |
Pick the iso-max-packet ceiling matching the negotiated speed.
See implementation.
| [in] | speed | See implementation. |
speed. | k_ra8_paud_iso_max_packet_hs | speed is k_ra8_usb_speed_hs. |
| k_ra8_paud_iso_max_packet_fs_default | Any other speed. |
Definition at line 131 of file ra8_usb_paud.c.
References k_ra8_paud_iso_max_packet_fs_default, k_ra8_paud_iso_max_packet_hs, and k_ra8_usb_speed_hs.
Referenced by internal_configure_pipes(), and internal_reset_shadow().
|
static |
Reset shadow state to spec defaults.
See implementation.
| [in] | speed | See implementation. |
Definition at line 183 of file ra8_usb_paud.c.
References internal_iso_max_packet(), k_ra8_paud_default_bps, k_ra8_paud_default_channels, k_ra8_paud_default_rate_hz, k_ra8_paud_default_volume, and s_state.
Referenced by ra8_usb_paud_init().
|
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).
| [in] | setup_fn | Application's handler. NULL detaches. |
| [in] | ctx | Context pointer threaded back into setup_fn. |
| k_ra8_ok | Handler installed. |
| k_ra8_err_invalid_state | Driver not initialized. |
Definition at line 397 of file ra8_usb_paud.c.
References k_ra8_err_invalid_state, k_ra8_ok, and s_state.
|
nodiscard |
Tear down the device-Audio function and release the controller.
| k_ra8_ok | Released. |
| k_ra8_err_invalid_state | Driver was never initialized. |
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.
|
nodiscard |
Read the current iso stream format.
| [out] | out_format | Receives the current format. |
| k_ra8_ok | Value copied. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | out_format was NULL. |
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.
|
nodiscard |
Read the current feature-unit volume.
| [out] | out_volume | Receives the current volume in Q8.8 dB. |
| k_ra8_ok | Value copied. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | out_volume was NULL. |
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.
|
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.
| [in] | setup | The SETUP packet returned by ra8_usb_read_setup_if_valid. |
| k_ra8_ok | SETUP handled (status stage queued internally). |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | setup was NULL. |
| k_ra8_err_not_supported | bRequest is not an audio class request this layer cares about. |
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.
|
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.
| [in] | speed | Which USB controller (FS or HS). |
| k_ra8_ok | Device-Audio ready. |
| k_ra8_err_invalid_arg | speed out of range. |
| k_ra8_err_hw_init_failed | Underlying ra8_usb_device_init failed. |
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().
|
nodiscard |
Drain a playback audio frame from the iso-OUT endpoint.
| [out] | buf | Receive buffer. |
| [in] | max_len | Capacity of buf, > 0. |
| [out] | got_len | Receives the number of bytes actually placed. |
| k_ra8_ok | Bytes drained. |
| k_ra8_err_no_data | Pipe was empty. |
| k_ra8_err_null_ptr | buf or got_len was NULL. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_invalid_arg | max_len == 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.
|
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.
| [in] | frame | Audio frame buffer. |
| [in] | len | Frame byte length. |
| k_ra8_ok | Bytes queued onto iso-IN. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | frame was NULL with len > 0. |
| k_ra8_err_invalid_arg | len == 0 or larger than the pipe max. |
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().
|
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.
| [in] | desc | Pointer to the caller-owned descriptor blob. |
| [in] | desc_len | Byte length of desc. |
| k_ra8_ok | Pointer + length stored. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_null_ptr | desc was NULL. |
| k_ra8_err_invalid_arg | desc_len was 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.
|
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".
| [in] | format | New format triplet. |
| k_ra8_ok | Shadow updated. |
| k_ra8_err_invalid_state | Driver not initialized. |
| k_ra8_err_invalid_arg | Format fields are zero / out of range. |
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().
|
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.
| [in] | volume_q8_8 | New volume in Q8.8 dB format. |
| k_ra8_ok | Shadow updated. |
| k_ra8_err_invalid_state | Driver not initialized. |
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().
|
static |
Definition at line 108 of file ra8_usb_paud.c.
|
static |
Definition at line 39 of file ra8_usb_paud.c.