The device is currently emmitting primes. pi-usb-serial and serial-comm give me a template for being able to do communication with a USB device through a serial port.
113 lines
3.4 KiB
Rust
113 lines
3.4 KiB
Rust
//! 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;
|
|
};
|
|
}
|
|
}
|