usbd_uac2: fix clippies, add builder, support IN data
This commit is contained in:
+4
-4
@@ -195,7 +195,7 @@ impl Descriptor for ClockSource {
|
|||||||
writer.write_u8(self.bm_attributes())?; // bmAttributes
|
writer.write_u8(self.bm_attributes())?; // bmAttributes
|
||||||
writer.write_u8(self.bm_controls())?; // bmControls
|
writer.write_u8(self.bm_controls())?; // bmControls
|
||||||
writer.write_u8(self.assoc_terminal)?; // bAssocTerminal
|
writer.write_u8(self.assoc_terminal)?; // bAssocTerminal
|
||||||
writer.write_u8(self.string.map_or(0, |n| u8::from(n)))?; // iClockSource
|
writer.write_u8(self.string.map_or(0, u8::from))?; // iClockSource
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -247,7 +247,7 @@ impl Descriptor for InputTerminal {
|
|||||||
| ((self.overflow_control as u8) << 2)
|
| ((self.overflow_control as u8) << 2)
|
||||||
| ((self.phantom_power_control as u8) << 4),
|
| ((self.phantom_power_control as u8) << 4),
|
||||||
)?;
|
)?;
|
||||||
writer.write_u8(self.string.map_or(0, |s| u8::from(s)))?;
|
writer.write_u8(self.string.map_or(0, u8::from))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -289,7 +289,7 @@ impl Descriptor for OutputTerminal {
|
|||||||
| ((self.underflow_control as u8) << 6),
|
| ((self.underflow_control as u8) << 6),
|
||||||
)?;
|
)?;
|
||||||
writer.write_u8(self.overflow_control as u8)?;
|
writer.write_u8(self.overflow_control as u8)?;
|
||||||
writer.write_u8(self.string.map_or(0, |n| u8::from(n)))?; // iTerminal
|
writer.write_u8(self.string.map_or(0, u8::from))?; // iTerminal
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -839,7 +839,7 @@ impl Descriptor for AudioStreamingInterface {
|
|||||||
writer.write_u32::<LittleEndian>(self.format_bitmap as u32)?;
|
writer.write_u32::<LittleEndian>(self.format_bitmap as u32)?;
|
||||||
writer.write_u8(self.num_channels)?;
|
writer.write_u8(self.num_channels)?;
|
||||||
writer.write(&self.channel_config.bytes)?;
|
writer.write(&self.channel_config.bytes)?;
|
||||||
writer.write_u8(self.string.map_or(0, |s| u8::from(s)))?;
|
writer.write_u8(self.string.map_or(0, u8::from))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+89
-61
@@ -16,7 +16,7 @@ use log::*;
|
|||||||
|
|
||||||
use num_traits::{ConstZero, ToPrimitive};
|
use num_traits::{ConstZero, ToPrimitive};
|
||||||
use usb_device::control::{Recipient, Request, RequestType};
|
use usb_device::control::{Recipient, Request, RequestType};
|
||||||
use usb_device::device::DEFAULT_ALTERNATE_SETTING;
|
use usb_device::device::{DEFAULT_ALTERNATE_SETTING, UsbDeviceBuilder, UsbVidPid};
|
||||||
use usb_device::endpoint::{self, Endpoint, EndpointDirection, In, Out};
|
use usb_device::endpoint::{self, Endpoint, EndpointDirection, In, Out};
|
||||||
use usb_device::{UsbDirection, class_prelude::*};
|
use usb_device::{UsbDirection, class_prelude::*};
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ impl RangeType for u32 {}
|
|||||||
/// Represent a range request/response.
|
/// Represent a range request/response.
|
||||||
///
|
///
|
||||||
/// ref: UAC2 5.2.2
|
/// ref: UAC2 5.2.2
|
||||||
#[derive(PartialEq, Eq, Ord)]
|
#[derive(PartialEq, Eq)]
|
||||||
pub struct RangeEntry<T: RangeType> {
|
pub struct RangeEntry<T: RangeType> {
|
||||||
pub min: T,
|
pub min: T,
|
||||||
pub max: T,
|
pub max: T,
|
||||||
@@ -93,10 +93,14 @@ impl<T: RangeType> RangeEntry<T> {
|
|||||||
// The spec guarantees that ranges do not overlap, so compare by min is correct.
|
// The spec guarantees that ranges do not overlap, so compare by min is correct.
|
||||||
impl<T: RangeType + PartialOrd> PartialOrd for RangeEntry<T> {
|
impl<T: RangeType + PartialOrd> PartialOrd for RangeEntry<T> {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
self.min.partial_cmp(&other.min)
|
Some(self.cmp(other))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T: RangeType + PartialOrd> Ord for RangeEntry<T> {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
self.min.cmp(&other.min)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represent Isochronous feedback as integer and fractional parts, internally as 16.16.
|
/// Represent Isochronous feedback as integer and fractional parts, internally as 16.16.
|
||||||
///
|
///
|
||||||
/// Provides conversions to and from the different USB formats.
|
/// Provides conversions to and from the different USB formats.
|
||||||
@@ -146,6 +150,10 @@ pub trait AudioHandler<'a, B: UsbBus> {
|
|||||||
/// `ep.read()`.
|
/// `ep.read()`.
|
||||||
fn audio_data_rx(&mut self, ep: &Endpoint<'a, B, endpoint::Out>);
|
fn audio_data_rx(&mut self, ep: &Endpoint<'a, B, endpoint::Out>);
|
||||||
|
|
||||||
|
/// Called when we must produce audio data for the host. `ep` is ready for
|
||||||
|
/// `ep.write()`.
|
||||||
|
fn audio_data_tx(&mut self, ep: &Endpoint<'a, B, endpoint::In>);
|
||||||
|
|
||||||
/// Called when it's time to send an isochronous feedback update. Should
|
/// Called when it's time to send an isochronous feedback update. Should
|
||||||
/// return the correct feedback payload. Feedback always runs at 1ms (in
|
/// return the correct feedback payload. Feedback always runs at 1ms (in
|
||||||
/// this implementation), and will be passed the nominal frame size.
|
/// this implementation), and will be passed the nominal frame size.
|
||||||
@@ -183,6 +191,7 @@ pub trait ClockSource {
|
|||||||
fn sample_rate(&self) -> u32;
|
fn sample_rate(&self) -> u32;
|
||||||
/// Called when the host requests to set the sample rate. Not necessarily called at all startups,
|
/// Called when the host requests to set the sample rate. Not necessarily called at all startups,
|
||||||
/// so alt_setting should start/stop the clock. Not required for 'fixed' clocks.
|
/// so alt_setting should start/stop the clock. Not required for 'fixed' clocks.
|
||||||
|
#[allow(unused_variables)]
|
||||||
fn set_sample_rate(
|
fn set_sample_rate(
|
||||||
&mut self,
|
&mut self,
|
||||||
sample_rate: u32,
|
sample_rate: u32,
|
||||||
@@ -239,7 +248,7 @@ pub trait ClockSource {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let cs = descriptors::ClockSource {
|
let cs = descriptors::ClockSource {
|
||||||
id: id,
|
id,
|
||||||
clock_type: Self::CLOCK_TYPE,
|
clock_type: Self::CLOCK_TYPE,
|
||||||
sof_sync: Self::SOF_SYNC,
|
sof_sync: Self::SOF_SYNC,
|
||||||
frequency_access,
|
frequency_access,
|
||||||
@@ -367,6 +376,7 @@ pub struct TerminalConfig<D: EndpointDirection> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<D: EndpointDirection> TerminalConfig<D> {
|
impl<D: EndpointDirection> TerminalConfig<D> {
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn new(
|
fn new(
|
||||||
base_id: u8,
|
base_id: u8,
|
||||||
clock_source_id: u8,
|
clock_source_id: u8,
|
||||||
@@ -400,7 +410,7 @@ impl<D: EndpointDirection> TerminalConfig<D> {
|
|||||||
TerminalConfigBuilder::new()
|
TerminalConfigBuilder::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<'a> TerminalConfigurationDescriptors for TerminalConfig<Out> {
|
impl TerminalConfigurationDescriptors for TerminalConfig<Out> {
|
||||||
fn get_configuration_descriptors(&self) -> (InputTerminal, OutputTerminal) {
|
fn get_configuration_descriptors(&self) -> (InputTerminal, OutputTerminal) {
|
||||||
let input_terminal = InputTerminal {
|
let input_terminal = InputTerminal {
|
||||||
id: self.base_id,
|
id: self.base_id,
|
||||||
@@ -437,7 +447,7 @@ impl<'a> TerminalConfigurationDescriptors for TerminalConfig<Out> {
|
|||||||
// fn get_interface_descriptor(&self, id: InterfaceIndex) )
|
// fn get_interface_descriptor(&self, id: InterfaceIndex) )
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> TerminalConfigurationDescriptors for TerminalConfig<In> {
|
impl TerminalConfigurationDescriptors for TerminalConfig<In> {
|
||||||
fn get_configuration_descriptors(&self) -> (InputTerminal, OutputTerminal) {
|
fn get_configuration_descriptors(&self) -> (InputTerminal, OutputTerminal) {
|
||||||
let output_terminal = OutputTerminal {
|
let output_terminal = OutputTerminal {
|
||||||
id: self.base_id,
|
id: self.base_id,
|
||||||
@@ -838,7 +848,7 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbClass<B>
|
|||||||
|
|
||||||
// UAC2 4.7
|
// UAC2 4.7
|
||||||
if let Some(descs) = additional_descs {
|
if let Some(descs) = additional_descs {
|
||||||
for desc in descs.into_iter() {
|
for desc in descs.iter() {
|
||||||
desc.write_descriptor(writer)?;
|
desc.write_descriptor(writer)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -893,10 +903,14 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbClass<B>
|
|||||||
|
|
||||||
fn endpoint_in_complete(&mut self, addr: EndpointAddress) {
|
fn endpoint_in_complete(&mut self, addr: EndpointAddress) {
|
||||||
debug!("EP {} IN complete", addr);
|
debug!("EP {} IN complete", addr);
|
||||||
if let Some(fb_ep) = self.feedback.as_ref()
|
if let Some(_fb_ep) = self.feedback.as_ref()
|
||||||
&& addr.index() == self.fb_ep
|
&& addr.index() == self.fb_ep
|
||||||
{
|
{
|
||||||
self.emit_feedback();
|
self.emit_feedback();
|
||||||
|
} else if let Some(in_ep) = self.input.as_ref()
|
||||||
|
&& addr.index() == self.in_ep
|
||||||
|
{
|
||||||
|
self.audio_impl.audio_data_tx(&in_ep.endpoint);
|
||||||
} else {
|
} else {
|
||||||
debug!(" unexpected IN on {}", addr);
|
debug!(" unexpected IN on {}", addr);
|
||||||
}
|
}
|
||||||
@@ -978,11 +992,11 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
|
|
||||||
fn class_request_out(&mut self, xfer: ControlOut<B>) {
|
fn class_request_out(&mut self, xfer: ControlOut<B>) {
|
||||||
let req = xfer.request();
|
let req = xfer.request();
|
||||||
match (req.recipient, req.request.try_into()) {
|
match (req.recipient, req.request.into()) {
|
||||||
(Recipient::Interface, Ok(ClassSpecificRequest::Cur)) => self.set_interface_cur(xfer),
|
(Recipient::Interface, ClassSpecificRequest::Cur) => self.set_interface_cur(xfer),
|
||||||
(Recipient::Interface, Ok(ClassSpecificRequest::Range)) => {}
|
(Recipient::Interface, ClassSpecificRequest::Range) => {}
|
||||||
(Recipient::Endpoint, Ok(ClassSpecificRequest::Cur)) => self.set_endpoint_cur(xfer),
|
(Recipient::Endpoint, ClassSpecificRequest::Cur) => self.set_endpoint_cur(xfer),
|
||||||
(Recipient::Endpoint, Ok(ClassSpecificRequest::Range)) => {}
|
(Recipient::Endpoint, ClassSpecificRequest::Range) => {}
|
||||||
_ => {
|
_ => {
|
||||||
debug!(" Unimplemented.");
|
debug!(" Unimplemented.");
|
||||||
}
|
}
|
||||||
@@ -992,13 +1006,11 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
fn class_request_in(&mut self, xfer: ControlIn<B>) {
|
fn class_request_in(&mut self, xfer: ControlIn<B>) {
|
||||||
let req = xfer.request();
|
let req = xfer.request();
|
||||||
|
|
||||||
match (req.recipient, req.request.try_into()) {
|
match (req.recipient, req.request.into()) {
|
||||||
(Recipient::Interface, Ok(ClassSpecificRequest::Cur)) => self.get_interface_cur(xfer),
|
(Recipient::Interface, ClassSpecificRequest::Cur) => self.get_interface_cur(xfer),
|
||||||
(Recipient::Interface, Ok(ClassSpecificRequest::Range)) => {
|
(Recipient::Interface, ClassSpecificRequest::Range) => self.get_interface_range(xfer),
|
||||||
self.get_interface_range(xfer)
|
(Recipient::Endpoint, ClassSpecificRequest::Cur) => self.get_endpoint_cur(xfer),
|
||||||
}
|
(Recipient::Endpoint, ClassSpecificRequest::Range) => self.get_endpoint_range(xfer),
|
||||||
(Recipient::Endpoint, Ok(ClassSpecificRequest::Cur)) => self.get_endpoint_cur(xfer),
|
|
||||||
(Recipient::Endpoint, Ok(ClassSpecificRequest::Range)) => self.get_endpoint_range(xfer),
|
|
||||||
_ => {
|
_ => {
|
||||||
debug!(" Unimplemented.");
|
debug!(" Unimplemented.");
|
||||||
}
|
}
|
||||||
@@ -1012,12 +1024,16 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
|
|
||||||
debug!(" SET_ALT_INTERFACE {} {}", iface, alt_setting);
|
debug!(" SET_ALT_INTERFACE {} {}", iface, alt_setting);
|
||||||
|
|
||||||
if self.input.is_some() && iface == self.in_iface {
|
if let Some(input) = &mut self.input
|
||||||
let old_alt = self.input.as_ref().unwrap().alt_setting;
|
&& iface == self.in_iface
|
||||||
|
{
|
||||||
|
let old_alt = input.alt_setting;
|
||||||
if old_alt != alt_setting {
|
if old_alt != alt_setting {
|
||||||
self.audio_impl
|
self.audio_impl
|
||||||
.alternate_setting_changed(UsbDirection::In, alt_setting);
|
.alternate_setting_changed(UsbDirection::In, alt_setting);
|
||||||
self.input.as_mut().unwrap().alt_setting = alt_setting;
|
input.alt_setting = alt_setting;
|
||||||
|
// Start the IN cycle
|
||||||
|
self.audio_impl.audio_data_tx(&input.endpoint);
|
||||||
xfer.accept().ok();
|
xfer.accept().ok();
|
||||||
}
|
}
|
||||||
} else if self.output.is_some() && iface == self.out_iface {
|
} else if self.output.is_some() && iface == self.out_iface {
|
||||||
@@ -1041,13 +1057,15 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
let req = xfer.request();
|
let req = xfer.request();
|
||||||
let iface = req.index as u8;
|
let iface = req.index as u8;
|
||||||
debug!(" GET_ALT_INTERFACE {}", iface);
|
debug!(" GET_ALT_INTERFACE {}", iface);
|
||||||
if self.input.is_some() && iface == self.in_iface {
|
if let Some(input) = self.input.as_ref()
|
||||||
xfer.accept_with(&[self.input.as_ref().unwrap().alt_setting])
|
&& iface == self.in_iface
|
||||||
.ok();
|
{
|
||||||
|
xfer.accept_with(&[input.alt_setting]).ok();
|
||||||
return;
|
return;
|
||||||
} else if self.output.is_some() && iface == self.out_iface {
|
} else if let Some(output) = self.output.as_ref()
|
||||||
xfer.accept_with(&[self.output.as_ref().unwrap().alt_setting])
|
&& iface == self.out_iface
|
||||||
.ok();
|
{
|
||||||
|
xfer.accept_with(&[output.alt_setting]).ok();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
debug!(" Unimplemented.");
|
debug!(" Unimplemented.");
|
||||||
@@ -1109,9 +1127,8 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
channel: u8,
|
channel: u8,
|
||||||
control: u8,
|
control: u8,
|
||||||
) {
|
) {
|
||||||
match entity {
|
if entity == 1 {
|
||||||
1 => return self.get_clock_cur(xfer, channel, control),
|
return self.get_clock_cur(xfer, channel, control);
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
debug!(" Unimplemented.");
|
debug!(" Unimplemented.");
|
||||||
}
|
}
|
||||||
@@ -1123,49 +1140,48 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
channel: u8,
|
channel: u8,
|
||||||
control: u8,
|
control: u8,
|
||||||
) {
|
) {
|
||||||
match entity {
|
if entity == 1 {
|
||||||
1 => return self.set_clock_cur(xfer, channel, control),
|
return self.set_clock_cur(xfer, channel, control);
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
debug!(" Unimplemented.");
|
debug!(" Unimplemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_streaming_interface_cur(
|
fn set_streaming_interface_cur(
|
||||||
&mut self,
|
&mut self,
|
||||||
xfer: ControlOut<B>,
|
_xfer: ControlOut<B>,
|
||||||
direction: UsbDirection,
|
_direction: UsbDirection,
|
||||||
entity: u8,
|
_entity: u8,
|
||||||
channel: u8,
|
_channel: u8,
|
||||||
control: u8,
|
_control: u8,
|
||||||
) {
|
) {
|
||||||
debug!(" Unimplemented.");
|
debug!(" Unimplemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_endpoint_cur(&mut self, xfer: ControlIn<B>) {
|
fn get_endpoint_cur(&mut self, xfer: ControlIn<B>) {
|
||||||
let req = xfer.request();
|
let req = xfer.request();
|
||||||
let entity = (req.index >> 8) as u8;
|
let _entity = (req.index >> 8) as u8;
|
||||||
let interface = (req.index & 0xff) as u8;
|
let _interface = (req.index & 0xff) as u8;
|
||||||
let control = (req.value >> 8) as u8;
|
let _control = (req.value >> 8) as u8;
|
||||||
let channel = (req.value & 0xff) as u8;
|
let _channel = (req.value & 0xff) as u8;
|
||||||
|
|
||||||
debug!(" Unimplemented.");
|
debug!(" Unimplemented.");
|
||||||
}
|
}
|
||||||
fn get_endpoint_range(&mut self, xfer: ControlIn<B>) {
|
fn get_endpoint_range(&mut self, xfer: ControlIn<B>) {
|
||||||
let req = xfer.request();
|
let req = xfer.request();
|
||||||
let entity = (req.index >> 8) as u8;
|
let _entity = (req.index >> 8) as u8;
|
||||||
let interface = (req.index & 0xff) as u8;
|
let _interface = (req.index & 0xff) as u8;
|
||||||
let control = (req.value >> 8) as u8;
|
let _control = (req.value >> 8) as u8;
|
||||||
let channel = (req.value & 0xff) as u8;
|
let _channel = (req.value & 0xff) as u8;
|
||||||
|
|
||||||
debug!(" Unimplemented.");
|
debug!(" Unimplemented.");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_endpoint_cur(&mut self, xfer: ControlOut<B>) {
|
fn set_endpoint_cur(&mut self, xfer: ControlOut<B>) {
|
||||||
let req = xfer.request();
|
let req = xfer.request();
|
||||||
let entity = (req.index >> 8) as u8;
|
let _entity = (req.index >> 8) as u8;
|
||||||
let interface = (req.index & 0xff) as u8;
|
let _interface = (req.index & 0xff) as u8;
|
||||||
let control = (req.value >> 8) as u8;
|
let _control = (req.value >> 8) as u8;
|
||||||
let channel = (req.value & 0xff) as u8;
|
let _channel = (req.value & 0xff) as u8;
|
||||||
|
|
||||||
debug!(" Unimplemented.");
|
debug!(" Unimplemented.");
|
||||||
}
|
}
|
||||||
@@ -1203,8 +1219,8 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_clock_cur(&mut self, xfer: ControlIn<B>, channel: u8, control: u8) {
|
fn get_clock_cur(&mut self, xfer: ControlIn<B>, channel: u8, control: u8) {
|
||||||
match control.try_into() {
|
match control.into() {
|
||||||
Ok(ClockSourceControlSelector::SamFreqControl) => {
|
ClockSourceControlSelector::SamFreqControl => {
|
||||||
debug!(" SamplingFreqControl");
|
debug!(" SamplingFreqControl");
|
||||||
if channel != 0 {
|
if channel != 0 {
|
||||||
error!(
|
error!(
|
||||||
@@ -1222,7 +1238,7 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
})
|
})
|
||||||
.ok();
|
.ok();
|
||||||
}
|
}
|
||||||
Ok(ClockSourceControlSelector::ClockValidControl) => {
|
ClockSourceControlSelector::ClockValidControl => {
|
||||||
debug!(" ClockValidControl");
|
debug!(" ClockValidControl");
|
||||||
if channel != 0 {
|
if channel != 0 {
|
||||||
error!(
|
error!(
|
||||||
@@ -1248,8 +1264,8 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn set_clock_cur(&mut self, xfer: ControlOut<B>, channel: u8, control: u8) {
|
fn set_clock_cur(&mut self, xfer: ControlOut<B>, channel: u8, control: u8) {
|
||||||
match control.try_into() {
|
match control.into() {
|
||||||
Ok(ClockSourceControlSelector::SamFreqControl) => {
|
ClockSourceControlSelector::SamFreqControl => {
|
||||||
debug!(" SamplingFreqControl");
|
debug!(" SamplingFreqControl");
|
||||||
if channel != 0 {
|
if channel != 0 {
|
||||||
error!(
|
error!(
|
||||||
@@ -1266,7 +1282,7 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
);
|
);
|
||||||
xfer.accept().ok();
|
xfer.accept().ok();
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(_e) => {
|
||||||
error!(" SET SamplingFreqControl CUR ERROR BAD DATA");
|
error!(" SET SamplingFreqControl CUR ERROR BAD DATA");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1277,8 +1293,8 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_clock_range(&mut self, xfer: ControlIn<B>, channel: u8, control: u8) {
|
fn get_clock_range(&mut self, xfer: ControlIn<B>, channel: u8, control: u8) {
|
||||||
match control.try_into() {
|
match control.into() {
|
||||||
Ok(ClockSourceControlSelector::SamFreqControl) => {
|
ClockSourceControlSelector::SamFreqControl => {
|
||||||
debug!(" SamplingFreqControl");
|
debug!(" SamplingFreqControl");
|
||||||
if channel != 0 {
|
if channel != 0 {
|
||||||
error!(
|
error!(
|
||||||
@@ -1321,3 +1337,15 @@ impl<'a, B: UsbBus, AU: AudioHandler<'a, B> + ClockSource> UsbAudioClass<'a, B,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set up a `UsbDeviceBuilder` with the device IDs for Usb Audio Class 2.0
|
||||||
|
pub fn builder<'a, B: UsbBus>(
|
||||||
|
alloc: &'a UsbBusAllocator<B>,
|
||||||
|
vid_pid: UsbVidPid,
|
||||||
|
) -> UsbDeviceBuilder<'a, B> {
|
||||||
|
UsbDeviceBuilder::new(alloc, vid_pid)
|
||||||
|
.composite_with_iads() // required by UAC2 4.6
|
||||||
|
.device_class(0xef) // required by UAC2 4.2
|
||||||
|
.device_sub_class(0x02) // required by UAC2 4.2
|
||||||
|
.device_protocol(0x01) // required by UAC2 4.2
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
// src/log.rs (or log/mod.rs)
|
// src/log.rs (or log/mod.rs)
|
||||||
|
#[allow(unused_imports)]
|
||||||
#[cfg(feature = "defmt")]
|
#[cfg(feature = "defmt")]
|
||||||
pub use defmt::{debug, error, info, trace, warn};
|
pub use defmt::{debug, error, info, trace, warn};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user