From 02b48c95f805d4c73fd481efd56dc8478bfa5145 Mon Sep 17 00:00:00 2001
From: Matt Johnston <matt@ucc.asn.au>
Date: Sun, 2 Oct 2022 10:28:56 +0800
Subject: [PATCH] start of bringing back usb

---
 examples/rp/src/bin/usb_serial.rs | 83 +++++++++++++++++++++++++------
 1 file changed, 69 insertions(+), 14 deletions(-)

diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs
index a0eb9e3a..6e7499ae 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");
 
-- 
GitLab