much progress, descriptors and sample rates getting basically working?

This commit is contained in:
2026-04-23 14:38:28 -07:00
parent ac6618a162
commit 539e0aab98
16 changed files with 1435 additions and 533 deletions
+258
View File
@@ -0,0 +1,258 @@
#![no_main]
#![no_std]
// extern crate panic_semihosting;
extern crate panic_halt;
use core::cell::OnceCell;
use cortex_m::asm::delay;
use cortex_m_rt::entry;
use embedded_io::{ErrorType, Write};
use nb;
#[allow(unused_imports)]
use hal::prelude::*;
#[allow(unused_imports)]
use lpc55_hal as hal;
use lpc55_hal::{
drivers::{
Serial,
pins::{PinId, Pio0_29, Pio0_30},
serial::Tx,
},
peripherals::flexcomm::Usart0,
typestates::pin::{
flexcomm::{Usart, UsartPins},
function::{FC0_RXD_SDA_MOSI_DATA, FC0_TXD_SCL_MISO_WS},
state::Special,
},
};
use core::convert::Infallible;
use defmt;
use defmt_rtt as _;
use hal::drivers::{Timer, UsbBus, pins};
use static_cell::StaticCell;
use usb_device::{
bus,
device::{StringDescriptors, UsbDeviceBuilder, UsbVidPid},
endpoint::IsochronousSynchronizationType,
};
use usbd_uac2::{
self, AudioClassConfig, RangeEntry, TerminalConfig, USB_CLASS_AUDIO, UsbAudioClass,
UsbAudioClockImpl, UsbSpeed,
constants::{FunctionCode, TerminalType},
descriptors::{ChannelConfig, ClockSource, ClockType, FormatType1, LockDelay},
};
type SERIAL_RX_PIN = hal::Pin<Pio0_29, Special<FC0_RXD_SDA_MOSI_DATA>>;
type SERIAL_TX_PIN = hal::Pin<Pio0_30, Special<FC0_TXD_SCL_MISO_WS>>;
type SERIAL_PINS = (SERIAL_TX_PIN, SERIAL_RX_PIN);
static SERIAL: StaticCell<DefmtUart<Usart0>> = StaticCell::new();
pub struct DefmtUart<U>(pub Tx<U>)
where
U: Usart;
impl<U> ErrorType for DefmtUart<U>
where
U: Usart,
{
type Error = Infallible;
}
impl<U> Write for DefmtUart<U>
where
U: Usart,
{
fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
buf.iter().map(|c| nb::block!(self.0.write(*c))).last();
Ok(buf.len())
}
fn flush(&mut self) -> Result<(), Self::Error> {
// Blocking write, so flush is a no-op
Ok(())
}
}
struct Clock {}
impl Clock {
const RATES: [RangeEntry<u32>; 1] = [RangeEntry::new_fixed(44100)];
}
impl UsbAudioClockImpl for Clock {
const CLOCK_TYPE: usbd_uac2::descriptors::ClockType = ClockType::InternalFixed;
const SOF_SYNC: bool = false;
fn get_sample_rate(&self) -> core::result::Result<u32, usbd_uac2::UsbAudioClassError> {
Ok(Clock::RATES[0].min)
}
fn get_rates(
&self,
) -> core::result::Result<&[usbd_uac2::RangeEntry<u32>], usbd_uac2::UsbAudioClassError> {
Ok(&Clock::RATES)
}
}
struct Audio {}
impl<'a, B: bus::UsbBus> UsbAudioClass<'a, B> for Audio {}
#[entry]
fn main() -> ! {
let hal = hal::new();
let mut anactrl = hal.anactrl;
let mut pmc = hal.pmc;
let mut syscon = hal.syscon;
let mut gpio = hal.gpio.enabled(&mut syscon);
let mut iocon = hal.iocon.enabled(&mut syscon);
let mut red_led = pins::Pio1_6::take()
.unwrap()
.into_gpio_pin(&mut iocon, &mut gpio)
.into_output(hal::drivers::pins::Level::Low); // start turned on
let usb0_vbus_pin = pins::Pio0_22::take()
.unwrap()
.into_usb0_vbus_pin(&mut iocon);
let serial_rx_pin = pins::Pio0_29::take()
.unwrap()
.into_usart0_rx_pin(&mut iocon);
let serial_tx_pin = pins::Pio0_30::take()
.unwrap()
.into_usart0_tx_pin(&mut iocon);
iocon.disabled(&mut syscon).release(); // save the environment :)
let clocks = hal::ClockRequirements::default()
// .system_frequency(24.mhz())
// .system_frequency(72.mhz())
.system_frequency(96.MHz())
.configure(&mut anactrl, &mut pmc, &mut syscon)
.unwrap();
let mut _delay_timer = Timer::new(
hal.ctimer
.0
.enabled(&mut syscon, clocks.support_1mhz_fro_token().unwrap()),
);
let usart = hal
.flexcomm
.0
.enabled_as_usart(&mut syscon, &clocks.support_flexcomm_token().unwrap());
let serial_config = hal::drivers::serial::config::Config::default().speed(115_200.Hz());
let serial = Serial::new(usart, (serial_tx_pin, serial_rx_pin), serial_config).split();
let serial_tx = DefmtUart(serial.0);
// defmt_serial::defmt_serial(SERIAL.init(serial_tx));
let usb_peripheral = hal.usbhs.enabled_as_device(
&mut anactrl,
&mut pmc,
&mut syscon,
&mut _delay_timer,
clocks.support_usbhs_token().unwrap(),
);
let usb_bus = UsbBus::new(usb_peripheral, usb0_vbus_pin);
let clock = Clock {};
let audio = Audio {};
let config = AudioClassConfig::new(UsbSpeed::High, FunctionCode::Other, &clock, &audio)
.with_input_config(TerminalConfig::new(
2,
1,
2,
FormatType1 {
bit_resolution: 24,
bytes_per_sample: 4,
},
TerminalType::ExtLineConnector,
ChannelConfig::default_chans(2),
IsochronousSynchronizationType::Adaptive,
LockDelay::Milliseconds(10),
None,
))
.with_output_config(TerminalConfig::new(
4,
1,
2,
FormatType1 {
bit_resolution: 24,
bytes_per_sample: 4,
},
TerminalType::ExtLineConnector,
ChannelConfig::default_chans(2),
IsochronousSynchronizationType::Adaptive,
LockDelay::Milliseconds(10),
None,
));
let mut uac2 = config.build(&usb_bus).unwrap();
let mut usb_dev = UsbDeviceBuilder::new(&usb_bus, UsbVidPid(0x1209, 0xcc1d))
.composite_with_iads()
.strings(&[StringDescriptors::default()
.manufacturer("VE7XEN")
.product("Guac")
.serial_number("123456789")])
.unwrap()
.max_packet_size_0(64)
.unwrap()
.device_class(0xef)
.device_sub_class(0x02)
.device_protocol(0x01)
.build();
defmt::info!("main loop");
let mut need_zlp = false;
let mut buf = [0u8; 8];
let mut size = 0;
let mut buf_in_use = false;
loop {
// if !usb_dev.poll(&mut []) {
// if !usb_dev.poll(&mut [&mut serial]) {
if !usb_dev.poll(&mut [&mut uac2]) {
continue;
}
// let mut buf = [0u8; 512];
// match serial.read(&mut buf) {
// Ok(count) if count > 0 => {
// assert!(count == 1);
// // hprintln!("received some data on the serial port: {:?}", &buf[..count]).ok();
// // cortex_m_semihosting::hprintln!("received:\n{}", core::str::from_utf8(&buf[..count]).unwrap()).ok();
// red_led.set_low().ok(); // Turn on
// // cortex_m_semihosting::hprintln!("read {:?}", &buf[..count]).ok();
// cortex_m_semihosting::hprintln!("read {:?}", count).ok();
// // Echo back in upper case
// for c in buf[0..count].iter_mut() {
// if (0x61 <= *c && *c <= 0x7a) || (0x41 <= *c && *c <= 0x5a) {
// *c ^= 0x20;
// }
// }
// let mut write_offset = 0;
// while write_offset < count {
// match serial.write(&buf[write_offset..count]) {
// Ok(len) if len > 0 => {
// write_offset += len;
// cortex_m_semihosting::hprintln!("wrote {:?}", len).ok();
// },
// _ => {},
// }
// }
// // hprintln!("wrote it back").ok();
// }
// _ => {}
// }
red_led.set_high().ok(); // Turn off
}
}