diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs index a0eb9e3a4655dd55c71b776368e9b74a28cc542d..6e7499aea1ed654ff1284499bf456a5181d868d5 100644 --- a/examples/rp/src/bin/usb_serial.rs +++ b/examples/rp/src/bin/usb_serial.rs @@ -28,27 +28,77 @@ async fn main(_spawner: Spawner) { let mut cp = cortex_m::peripheral::Peripherals::take().unwrap(); + // Create the USB driver, from the HAL. + let irq = interrupt::take!(USBCTRL_IRQ); + let driver = Driver::new(p.USB, irq); + + // Create embassy-usb Config + let mut config = Config::new(0xc0de, 0xcafe); + config.manufacturer = Some("Embassy"); + config.product = Some("USB-serial example"); + config.serial_number = Some("12345678"); + config.max_power = 100; + config.max_packet_size_0 = 64; + + // Required for windows compatiblity. + // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help + config.device_class = 0xEF; + config.device_sub_class = 0x02; + config.device_protocol = 0x01; + config.composite_with_iads = true; + + // Create embassy-usb DeviceBuilder using the driver and config. + // It needs some buffers for building the descriptors. + let mut device_descriptor = [0; 256]; + let mut config_descriptor = [0; 256]; + let mut bos_descriptor = [0; 256]; + let mut control_buf = [0; 64]; + + let mut state = State::new(); + + let mut builder = Builder::new( + driver, + config, + &mut device_descriptor, + &mut config_descriptor, + &mut bos_descriptor, + &mut control_buf, + None, + ); + + // Create classes on the builder. + let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); + + // Build the builder. + let mut usb = builder.build(); + + // Run the USB device. + let usb_fut = usb.run(); + // XXX: Can we get the number from the pin? let mut gpio = (Flex::new(p.PIN_6), 6); // let mut gpio = (Flex::new(p.PIN_10), 10); // let mut gpio = (Flex::new(p.PIN_13), 13); - run(&mut gpio.0, gpio.1, &mut cp.SYST); - - // // Do stuff with the class! - // let echo_fut = async { - // loop { - // class.wait_connection().await; - // info!("Connected"); - // let _ = usb_echo(&mut class, &mut gpio6, &mut cp.SYST).await; - // info!("Disconnected"); - // } - // }; + let usb = false; + if usb { + // // Do stuff with the class! + let echo_fut = async { + loop { + class.wait_connection().await; + info!("Connected"); + let _ = usb_run(&mut gpio.0, gpio.1, &mut cp.SYST, &mut class).await; + info!("Disconnected"); + } + }; - // // Run everything concurrently. - // // If we had made everything `'static` above instead, we could do this using separate tasks instead. - // join(usb_fut, echo_fut).await; + // Run everything concurrently. + // If we had made everything `'static` above instead, we could do this using separate tasks instead. + join(usb_fut, echo_fut).await; + } else { + run(&mut gpio.0, gpio.1, &mut cp.SYST); + } } struct Disconnected {} @@ -89,6 +139,11 @@ impl core::fmt::Write for FmtBuf { } } +async fn usb_run<'d, T: Instance + 'd, P: Pin>(pin: &mut Flex<'d, P>, pin_num: usize, syst: &mut SYST, + class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { + todo!("impl me") +} + fn run<'d, P: Pin>(pin: &mut Flex<'d, P>, pin_num: usize, syst: &mut SYST) -> Result<(), Disconnected> { info!("hello");