use core::future::Future; use embassy_rp::usb::Driver; use embassy_rp::{interrupt, peripherals::USB}; use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; use embassy_usb::class::hid::{HidWriter, ReportId, RequestHandler}; use embassy_usb::control::OutResponse; use embassy_usb::{Builder, Config, UsbDevice}; use usbd_hid::descriptor::{MouseReport, SerializedDescriptor}; static mut DEVICE_DESCRIPTOR_BUFFER: [u8; 256] = [0; 256]; static mut CONFIG_DESCRIPTOR_BUFFER: [u8; 256] = [0; 256]; static mut BOS_DESCRIPTOR_BUFFER: [u8; 256] = [0; 256]; static mut MSOS_DESCRIPTOR_BUFFER: [u8; 256] = [0; 256]; static mut CONTROL_BUFFER: [u8; 64] = [0; 64]; static mut STATE: Option> = None; static mut USB: Option>> = None; pub struct Serial<'a> { class: CdcAcmClass<'a, Driver<'a, USB>>, } impl Serial<'static> { pub fn new(usb: USB) -> Serial<'static> { // Create the driver, from the HAL. let irq = interrupt::take!(USBCTRL_IRQ); let driver = Driver::new(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; unsafe { STATE = Some(State::new()); } let mut builder = Builder::new( driver, config, unsafe { &mut DEVICE_DESCRIPTOR_BUFFER }, unsafe { &mut CONFIG_DESCRIPTOR_BUFFER }, unsafe { &mut BOS_DESCRIPTOR_BUFFER }, unsafe { &mut MSOS_DESCRIPTOR_BUFFER }, unsafe { &mut CONTROL_BUFFER }, ); // Create classes on the builder. let class = CdcAcmClass::new(&mut builder, unsafe { STATE.as_mut().unwrap() }, 64); // Build the builder. unsafe { USB = Some(builder.build()); }; Self { class } } }