//! This example test the RP Pico on board LED. //! //! It does not work with the RP Pico W board. See wifi_blinky.rs. #![no_std] #![no_main] use embassy_usb::{Builder, Config, class::cdc_acm::{CdcAcmClass, State}, UsbDevice, driver::EndpointError}; use embassy_executor::Spawner; use embassy_rp::{bind_interrupts, gpio, peripherals::USB, usb::{Driver, Instance, InterruptHandler}}; use embassy_time::Timer; use gpio::{Level, Output}; use defmt::{info, panic, unwrap}; use defmt_rtt as _; use panic_probe as _; use static_cell::StaticCell; bind_interrupts!(struct Irqs { USBCTRL_IRQ => InterruptHandler<USB>; }); #[embassy_executor::task] async fn usb_task(mut usb: UsbDevice<'static, Driver<'static, USB>>) { usb.run().await } #[embassy_executor::main] async fn main(spawner: Spawner) { let p = embassy_rp::init(Default::default()); let mut led = Output::new(p.PIN_15, Level::Low); let driver = embassy_rp::usb::Driver::new(p.USB, Irqs); let mut config = Config::new(0x9988, 0x8899); config.manufacturer = Some("Savanni"); config.product = Some("USB test device"); config.serial_number = Some("abcdefg"); config.max_power = 100; config.max_packet_size_0 = 64; let mut builder = { static CONFIG_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new(); static BOS_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new(); static CONTROL_BUF: StaticCell<[u8; 64]> = StaticCell::new(); let mut builder = Builder::new( driver, config, CONFIG_DESCRIPTOR.init([0; 256]), BOS_DESCRIPTOR.init([0; 256]), &mut [], CONTROL_BUF.init([0; 64]), ); builder }; let mut class = { static STATE: StaticCell<State> = StaticCell::new(); let state = STATE.init(State::new()); CdcAcmClass::new(&mut builder, state, 64) }; let usb = builder.build(); unwrap!(spawner.spawn(usb_task(usb))); loop { class.wait_connection().await; led.set_high(); info!("Connected"); // let _ = echo(&mut class).await; let _ = primes(&mut class).await; info!("Disconnected"); led.set_low(); } } struct Disconnected {} impl From<EndpointError> for Disconnected { fn from(val: EndpointError) -> Self { match val { EndpointError::BufferOverflow => { panic!("Buffer overflow"); } EndpointError::Disabled => Disconnected{}, } } } async fn echo<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { let mut buf = [0; 64]; loop { let n = class.read_packet(&mut buf).await?; buf[n] = b'\r'; buf[n+1] = b'\n'; let data = &buf[..n+2]; info!("data: {:x}", data); class.write_packet(&data).await?; } } async fn primes<'d, T: Instance + 'd>(class: &mut CdcAcmClass<'d, Driver<'d, T>>) -> Result<(), Disconnected> { let PRIMES: [u8; 55] = [1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251]; let mut buf = [0; 64]; loop { for idx in 0..PRIMES.len() { buf[0] = PRIMES[idx]; class.write_packet(&buf).await?; Timer::after_secs(1).await; }; } }