/*************************************************************************** * Copyright (c) 2024 Microsoft Corporation * Copyright (c) 2026-present Eclipse ThreadX contributors * * This program and the accompanying materials are made available under the * terms of the MIT License which is available at * https://opensource.org/licenses/MIT. * * SPDX-License-Identifier: MIT **************************************************************************/ /**************************************************************************/ /**************************************************************************/ /** */ /** USBX Component */ /** */ /** Audio Class */ /** */ /**************************************************************************/ /**************************************************************************/ /* Include necessary system files. */ #define UX_SOURCE_CODE #include "ux_api.h" #include "ux_host_class_audio.h" #include "ux_host_stack.h" /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _ux_host_class_audio_read PORTABLE C */ /* 6.1.12 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ /* This function reads from the audio streaming interface. */ /* */ /* Note the request buffer should be ready for at least one packet, */ /* and request length is always limited to one packet size. */ /* */ /* INPUT */ /* */ /* audio Pointer to audio class */ /* audio_transfer_request Pointer to transfer request */ /* */ /* OUTPUT */ /* */ /* Completion Status */ /* */ /* CALLS */ /* */ /* _ux_host_class_audio_transfer_request Audio transfer request */ /* _ux_host_stack_class_instance_verify Verify instance is valid */ /* _ux_host_mutex_on Get mutex */ /* _ux_host_mutex_off Release mutex */ /* */ /* CALLED BY */ /* */ /* Application */ /* Audio Class */ /* */ /**************************************************************************/ UINT _ux_host_class_audio_read(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST *audio_transfer_request) { UINT status; ULONG mps; /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_HOST_CLASS_AUDIO_READ, audio, audio_transfer_request -> ux_host_class_audio_transfer_request_data_pointer, audio_transfer_request -> ux_host_class_audio_transfer_request_requested_length, 0, UX_TRACE_HOST_CLASS_EVENTS, 0, 0) /* Ensure the instance is valid. */ if (_ux_host_stack_class_instance_verify(_ux_system_host_class_audio_name, (VOID *) audio) != UX_SUCCESS) { /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_INSTANCE_UNKNOWN); /* If trace is enabled, insert this event into the trace buffer. */ UX_TRACE_IN_LINE_INSERT(UX_TRACE_ERROR, UX_HOST_CLASS_INSTANCE_UNKNOWN, audio, 0, 0, UX_TRACE_ERRORS, 0, 0) return(UX_HOST_CLASS_INSTANCE_UNKNOWN); } /* Protect thread reentry to this instance. */ _ux_host_mutex_on(&audio -> ux_host_class_audio_mutex); /* Ensure we have a selected interface that allows isoch transmission. */ if (audio -> ux_host_class_audio_isochronous_endpoint -> ux_endpoint_descriptor.wMaxPacketSize == 0) { /* Unprotect thread reentry to this instance. */ _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Error trap. */ _ux_system_error_handler(UX_SYSTEM_LEVEL_THREAD, UX_SYSTEM_CONTEXT_CLASS, UX_HOST_CLASS_AUDIO_WRONG_INTERFACE); /* Return error status. */ return(UX_HOST_CLASS_AUDIO_WRONG_INTERFACE); } /* For audio in, we read packets at a time, so the transfer request size is the size of the endpoint max packet size. */ mps = _ux_host_class_audio_max_packet_size_get(audio); audio_transfer_request -> ux_host_class_audio_transfer_request_packet_size = mps; audio_transfer_request -> ux_host_class_audio_transfer_request_requested_length = mps; /* Ask the stack to hook this transfer request to the iso ED. */ status = _ux_host_class_audio_transfer_request(audio, audio_transfer_request); /* Unprotect thread reentry to this instance. */ _ux_host_mutex_off(&audio -> ux_host_class_audio_mutex); /* Return completion status. */ return(status); } /**************************************************************************/ /* */ /* FUNCTION RELEASE */ /* */ /* _uxe_host_class_audio_read PORTABLE C */ /* 6.3.0 */ /* AUTHOR */ /* */ /* Chaoqiong Xiao, Microsoft Corporation */ /* */ /* DESCRIPTION */ /* */ /* This function checks errors in audio read function call. */ /* */ /* INPUT */ /* */ /* audio Pointer to audio class */ /* audio_transfer_request Pointer to transfer request */ /* */ /* OUTPUT */ /* */ /* Status */ /* */ /* CALLS */ /* */ /* _ux_host_class_audio_read Hook a audio read request */ /* */ /* CALLED BY */ /* */ /* Application */ /* */ /**************************************************************************/ UINT _uxe_host_class_audio_read(UX_HOST_CLASS_AUDIO *audio, UX_HOST_CLASS_AUDIO_TRANSFER_REQUEST *audio_transfer_request) { /* Sanity checks. */ if ((UX_NULL == audio) || (audio_transfer_request == UX_NULL)) return(UX_INVALID_PARAMETER); /* Invoke audio read function. */ return(_ux_host_class_audio_read(audio, audio_transfer_request)); }