| Age | Commit message (Collapse) | Author |
|
Bring the audio work onto the current host core and build files before applying the remaining review fixes.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Record terminal and Feature Unit links while parsing the AudioControl block, then resolve the stream association after all entities are known. Common capture and playback descriptor orders are both supported.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Collect only format descriptors with discrete sampling frequencies. The configuration API exposes concrete tuples and cannot safely represent a continuous range as one selectable rate.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Convert full-speed bInterval values to the scheduler microframe timebase and size transfers for the complete service interval. Endpoints with bInterval greater than one no longer run at a one-frame cadence.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Associate one directly connected Feature Unit with each capture and playback stream. This lets applications control microphone and speaker paths independently.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Reset Feature Unit state when parsing a new audio function. Devices without a matching unit must not inherit an ID collected from an earlier interface or device.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Keep Feature Unit request data in driver-owned storage until asynchronous completion and use the width defined for each control. This avoids overlapping request state and malformed one-byte controls.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Clear the started state only after SET_INTERFACE alt 0 succeeds. A failed control transfer can then be retried instead of leaving software and device state inconsistent.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Close the previously selected HCD endpoint before opening another alternate setting. This prevents stale endpoint size and controller state from surviving a format change.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Apply the host memory section and alignment attributes to audio transfer storage. This keeps buffers accessible to controllers that require DMA-capable memory.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Associate UAC1 AudioStreaming endpoints by their usage type. Keep data and implicit-feedback IN endpoints as streams while leaving explicit feedback endpoints unopened until feedback scheduling is supported.
Signed-off-by: HiFiPHile <[email protected]>
|
|
Fix HFP HIL reliability issue
|
|
midi2 device: complete the UMP stream discovery responder
|
|
clamp committed video payload size to streaming ep buffer
|
|
Co-authored-by: Copilot Autofix powered by AI <[email protected]>
Signed-off-by: HiFiPhile <[email protected]>
|
|
Signed-off-by: HiFiPhile <[email protected]>
|
|
Text replies resume instead of dropping their tail packets, which used
to leave a Start/Continue sequence without an End. A new Function Block
Discovery now merges with a pending one instead of replacing it.
|
|
Adds the Device Identity Notification with an app callback, MIDI-CI
version and SysEx8 stream count in FB Info, honors the Endpoint
Discovery filter bitmap, and paces discovery replies by TX FIFO room.
|
|
A false return from tud_usbtmc_start_bus_read() here does not mean arming
failed: it means the endpoint is already armed, either because the
application re-armed it from its trigger callback or because a transfer is
still queued (usbd_edpt_xfer() reports failure when the endpoint is busy).
Both cases end in STATE_IDLE, so the state cannot disambiguate them either,
and stalling on the result would halt a healthy endpoint.
Co-Authored-By: Claude Opus 5 <[email protected]>
|
|
A single USB488 TRIGGER message left the bulk-OUT endpoint un-armed, so the
host's next bulk-OUT transfer timed out. The trigger itself succeeded
silently, so the failure surfaced on a later, unrelated command; only a
USBTMC device clear recovered it. The bundled examples/device/usbtmc
reproduced this as shipped.
Every other branch of the STATE_IDLE dispatch in usbtmcd_xfer_cb() leaves
the endpoint in a defined state: it either transitions out of STATE_IDLE so
a later tud_usbtmc_start_bus_read() can re-arm it, or it stalls and lets the
CLEAR_FEATURE(ENDPOINT_HALT) handler recover it. USBTMC_MSGID_USB488_TRIGGER
did neither, and because the state stayed STATE_IDLE, even an application
following the contract documented in usbtmc_device.h got a silent no-op from
tud_usbtmc_start_bus_read().
Transition to STATE_NAK so the re-arm can take effect, and stall the
endpoint when trigger is unsupported or the application callback rejects it,
matching the existing handling for messages the driver cannot process. The
callback result is deliberately not wrapped in TU_VERIFY(), which would
return before the stall/re-arm and reintroduce the same hang.
Since the driver now re-arms after a trigger, drop tud_usbtmc_msg_trigger_cb
from the list of callbacks after which the application must do so.
Fixes #3821
Co-Authored-By: Claude Opus 5 <[email protected]>
|
|
Provide a high-level audio streaming API over UAC 1.0 devices while
keeping the USB topology private: applications select supported
{format, sample_rate, channels} configurations per logical stream, and
the driver owns the mapping to AS interface, alternate setting, and
endpoint.
- One logical stream per direction per instance; multiple AS interfaces
and alternate settings in a direction are merged into the stream's
configuration list (discrete tuples; continuous ranges exposed as a
single configuration at the top rate)
- Asynchronous tuh_audio_configure(): SET_INTERFACE to the selected
alternate setting, open/reconfigure the endpoint, set the sampling
frequency when supported, initialize the FIFO and packet scheduler,
then invoke the completion callback
- Frame-based FIFO streaming: tuh_audio_read()/tuh_audio_write() queue
whole frames; the driver owns transfer replenishment and fractional
packet scheduling (44.1 kHz pays back the 0.1 frame/ms remainder via
an accumulator for exact average pacing)
- tuh_audio_start()/tuh_audio_stop() activate/deactivate the stream
interface through SET_INTERFACE (alt n / alt 0)
Driver correctness fixes:
- Parse only the AC header's interface collection; MIDI Streaming and
other subclasses are skipped
- Keep every discrete format as a separate configuration; endpoints are
opened only for the alternate setting selected by tuh_audio_configure()
- Check tuh_interface_set() return values and SET_INTERFACE transfer
results instead of ignoring failures
- Validate instance state, direction, buffers, and frame counts in every
transfer API
- Feature Unit requests use the control's real width (mute/AGC/loudness
1 byte, others 2 bytes) and convert multibyte values to host order
- Failed/stalled/aborted isochronous transfers reach only the error
callback, never the capture/playback callbacks
The audio_host example uses the new API: 48 kHz stereo by default,
automatic stream restart on error callbacks, a sine test tone on the
playback stream, and periodic mic-only / spk-only / echo phase switching.
|
|
morse-cedricvandenbergh/fix/ncm-link-state-notify-retry
ncm: retry link-state notification, fix carrier lost on collision
|
|
tud_network_link_state() delivered the NETWORK_CONNECTION notification
edge-triggered and fire-once: if a previous notification was still in
flight, notification_xmit() returned early and the notification for the
new link state was never queued. Because link_is_up is committed before
the send, the host could be left reporting a stale carrier state - e.g.
a permanent NO-CARRIER after a link up. The notification state was also
mutated from both the caller and the notify xfer-completion callback
with no serialisation, so on RTOS ports where tud_network_link_state()
runs in a task other than tud_task() the two could race.
Defer the whole link-state update onto the usbd task, so it can no
longer race the completion callback. A collision with an in-flight
notification is resolved by re-arming notification_xmit_state and
letting the existing completion callback drive it forward on the next
xfer completion, rather than adding a separate pending/retry flag.
A link toggle does not change the link speed, so strictly only the
NETWORK_CONNECTION notification needs (re)sending, but reusing the
existing speed-then-connection state machine keeps the fix on a single,
already-serialised code path.
Closes #3760
|
|
guard
The comment above audiod_tx_packet_size() states flow control needs a FIFO
of at least 4*Navg, but the guard tests nominal_size[1] <= fifo_depth * 4 -
true for any FIFO larger than a quarter packet - instead of
nominal_size[1] * 4 <= fifo_depth. As written, flow control engages on
FIFOs far below its own documented minimum, where the depth/2 setpoint sits
within one packet of empty and the packet_size = 0 branch (a zero-length
packet, i.e. an audible 1 ms dropout for audio-class hosts) is reachable
from ordinary scheduling jitter rather than only from gross clock
deviation. With the guard corrected, undersized FIFOs fall back to the
plain min(count, max) path as intended.
|
|
Signed-off-by: Javid Khan <[email protected]>
|
|
|
|
|
|
|
|
|
|
This commit refactors the TUH_AUDIO (USB Audio Host) class driver to
simplify its public API and improve multi-AS (Audio Streaming) interface
support. The changes are focused on three files: the core driver
(audio_host.c/h) and the example application (audio_app.c).
Key changes in src/class/audio/audio_host.h:
- Remove tuh_audio_descriptor_cb_t and tuh_audio_mount_cb_t structures.
The mount callback no longer passes a large descriptor-info struct;
applications query per-AS info via tuh_audio_as_get_info().
- Add tuh_audio_get_dev_addr() and tuh_audio_get_feature_unit_id()
accessors to retrieve device address and feature-unit ID from an
interface index.
- Simplify control-transfer APIs by replacing (daddr, itf_num, unit_id)
parameters with a single idx parameter:
tuh_audio_set_sampling_freq(idx, as_idx, ...)
tuh_audio_get_sampling_freq(idx, as_idx, ...)
tuh_audio_feature_unit_set(idx, control_selector, channel, ...)
tuh_audio_feature_unit_get(idx, control_selector, channel, ...)
- Add synchronous wrapper APIs using TU_API_SYNC macro:
tuh_audio_get_sampling_freq_sync()
tuh_audio_set_sampling_freq_sync()
tuh_audio_feature_unit_set_sync()
tuh_audio_feature_unit_get_sync()
- Update isochronous endpoint APIs to use (idx, as_idx) instead of
(daddr, idx):
tuh_audio_receive(idx, as_idx, buffer, len)
tuh_audio_send(idx, as_idx, buffer, len)
- Remove tuh_audio_descriptor_cb() weak callback.
- Update tuh_audio_mount_cb() signature from mount_cb(param) to no param.
- Update tuh_audio_rx_cb()/tuh_audio_tx_cb() first parameter from idx to
dev_addr for consistency with other class drivers.
Key changes in src/class/audio/audio_host.c:
- Delete tuh_audio_descriptor_cb weak stub.
- Refactor get_idx_by_ep_addr() to iterate all AS interfaces per device
instead of relying on single ep_in/ep_out fields.
- Add audioh_get_ep_addr_by_dir() helper to find an endpoint address by
direction across multiple AS interfaces.
- Simplify audioh_close() cleanup: remove now-removed single-endpoint
fields (ep_in, ep_out) and rely on tu_memclr(p_audio->as, ...).
- Update audioh_xfer_cb() to pass dev_addr (not idx) to rx/tx callbacks,
matching the new callback signature.
- Simplify audioh_open(): remove descriptor-callback emission and the
temporary desc_cb structure; store only ac_itf_num instead of
bInterfaceNumber + iInterface + as_interface_num.
- Rename local descriptor pointers for clarity:
desc_input_terminal (was desc_it)
desc_output_terminal (was desc_ot)
Key changes in examples/host/audio_host/src/audio_app.c:
- Remove now-unnecessary globals: audio_ep_in, audio_ep_out, audio_ac_itf,
audio_feature_unit_id.
- Initialize audio_dev_addr, audio_idx, audiostream_in_idx,
audiostream_out_idx to 0xFF (TUSB_INDEX_INVALID_8) instead of 0.
- Update print_as_interfaces() to use tuh_audio_as_get_count() and
tuh_audio_as_get_info() instead of accessing mount_cb_data.
- Update all callback signatures and API calls to match the new driver API.
|
|
bound cdc-data endpoints against descriptor length in acm_open
|
|
Signed-off-by: HiFiPhile <[email protected]>
|
|
Signed-off-by: HiFiPhile <[email protected]>
|
|
Signed-off-by: HiFiPhile <[email protected]>
|
|
const style
Rename descriptor pointer variables to use desc_ prefix for consistency with audio_device.c:
- it -> desc_input_terminal
- ot -> desc_output_terminal
- fu -> desc_feature_unit
- itf -> desc_interface
- p_ep -> desc_endpoint
Unify const qualifier placement to type_t const * style.
Add file header comment describing UAC 1.0 host driver capabilities.
Switch license header to SPDX identifier.
|
|
|
|
- Fix missing tu_htole16() conversions for wValue and wIndex in
tuh_audio_set_sampling_freq, tuh_audio_get_sampling_freq,
tuh_audio_feature_unit_set, and tuh_audio_feature_unit_get
- Fix incorrect wIndex parameter order in feature unit requests
(unit_id and itf_num were swapped)
- Replace static freq_buf with per-endpoint ctrl buffer in
tuh_audio_set_sampling_freq to avoid concurrency issues
- Update audio_host README to match actual example behavior
|
|
vendord_set_alt() aborted bulk/interrupt endpoints of the outgoing
altsetting (stall/clear-stall) but only dropped the iso endpoints'
tracking: an armed iso transfer stayed live in the dcd with its usbd
claim held and no tracked handle to stop it, and its completion fired
into an endpoint the class no longer recognizes. Reachable through the
usbtest example's alt0 (bulk) <-> alt1 (iso) SET_INTERFACE switching.
Track each selected iso endpoint's descriptor (points into the app's
static descriptor set) and deactivate on de-selection: with the
iso-alloc API re-activation is the abort/scrub primitive (resets
ep_status, aborts the stale transfer); without it usbd_edpt_close does,
and the next selection re-opens. Iso cannot be stalled like
bulk/interrupt, hence the separate path.
Build-verified: usbtest for stm32f072disco, ra4m1_ek, raspberry_pi_pico
(iso-alloc) and ch32v307v_r1_1v0 (close API).
|
|
control transfer buffer
- Stop parsing at first non-Audio interface in audioh_open to avoid claiming unrelated interfaces
- Call usbh_driver_set_config_complete for AS and unknown interfaces to allow enumeration to continue
- Add global ctrl endpoint buffer to audioh_epbuf_t to fix use-after-return in feature_unit_set
- Add sampling_freq NULL check and initialize to 0 in tuh_audio_get_sampling_freq
- Change BOARD_TUH_RHPORT from 1 to 0 in audio_host example
- Add only.txt with supported MCU/family list for audio_host example
|
|
Add TinyUSB Host Audio class driver supporting UAC 1.0 devices.
Features:
- Support multiple Audio Streaming (AS) interfaces with independent format storage
- Support both IN (Microphone) and OUT (Speaker) endpoints
- Per-AS interface format info: channels, sample rate, bit resolution
- Support Feature Unit volume control
- Support sampling frequency get/set
- Add host/audio_host example for STM32F407 discovery board
- Support mono-to-stereo conversion for loopback
Changes:
- Add src/class/audio/audio_host.c and audio_host.h
- Register AUDIO driver in usbh.c
- Add CFG_TUH_AUDIO macro in tusb_option.h
- Add host/audio_host example with CMake and Makefile build support
Tested with Jabra USB headset (stereo speaker + mono microphone) on STM32F407 disco.
|
|
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
|
|
Non-buffered per-type source/sink endpoints (bulk/int/iso) with manual RX
arming across altsettings.
Co-Authored-By: Claude Fable 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_01HeF2gZ1M7GWkz6Av4BpKPg
|
|
add a three-level TUSB_VALIDATION_NONE/BASIC/STRICT knob and default
CFG_TUH_VALIDATION_LEVEL to BASIC, then make acm_open the first user so
the enumeration bounds checks compile out at NONE for trusted-device
setups and stay on by default.
|
|
Signed-off-by: Javid Khan <[email protected]>
|
|
feat(midi2): derive function blocks from the GTB descriptor
|
|
Signed-off-by: HiFiPhile <[email protected]>
|
|
Fix USBTMC status byte interrupt buffer
|
|
bound ndp16 wLength against received ntb in recv_validate_datagram
|
|
Queue the USB488 READ_STATUS_BYTE interrupt notification through tud_usbtmc_transmit_notification_data so it uses the class notification endpoint buffer for the asynchronous transfer.
Fixes #2928
Generated-by: OpenAI Codex
Signed-off-by: aineoae86-sys <[email protected]>
|
|
|