156 lines
4.3 KiB
Rust
156 lines
4.3 KiB
Rust
use embassy_executor::Spawner;
|
|
use embassy_stm32::gpio::{Level, Output, Speed};
|
|
use embassy_stm32::peripherals;
|
|
use embassy_stm32::time::Hertz;
|
|
use embassy_stm32::usb::Driver;
|
|
use embassy_stm32::{interrupt, Config};
|
|
use embassy_time::{Duration, Timer};
|
|
use embassy_usb::Builder;
|
|
use embassy_usb_serial::{CdcAcmClass, State};
|
|
use futures::future::join;
|
|
|
|
use arrayvec::{ArrayString, ArrayVec};
|
|
|
|
#[embassy_executor::task]
|
|
pub async fn usb_task(usb: peripherals::USB, dp_pin: peripherals::PA12, dm_pin: peripherals::PA11) {
|
|
let irq = interrupt::take!(USB_LP_CAN1_RX0);
|
|
let driver = Driver::new(usb, irq, dp_pin, dm_pin);
|
|
|
|
// Create embassy-usb Config
|
|
let config = embassy_usb::Config::new(0xc0de, 0xcafe);
|
|
//config.max_packet_size_0 = 64;
|
|
|
|
// 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; 7];
|
|
|
|
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();
|
|
|
|
// Do stuff with the class!
|
|
let usb_handler_fut = async {
|
|
loop {
|
|
class.wait_connection().await;
|
|
defmt::info!("USB connected");
|
|
let mut packet = [0; 64];
|
|
let mut buffer = ArrayVec::<u8, 64>::new();
|
|
|
|
loop {
|
|
let n = match class.read_packet(&mut packet).await {
|
|
Ok(n) => n,
|
|
Err(err) => {
|
|
defmt::error!("Unable to read packet: {}", err);
|
|
break;
|
|
}
|
|
};
|
|
|
|
if buffer.try_extend_from_slice(&packet[..n]).is_err() {
|
|
buffer.clear();
|
|
buffer.try_extend_from_slice(&packet[..n]).unwrap();
|
|
}
|
|
|
|
let mut line_end = 0;
|
|
for i in 0..buffer.len() {
|
|
if buffer[i] == '\r' as u8 {
|
|
line_end = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
defmt::info!("Line end: {}", line_end);
|
|
defmt::info!("buffer: {}", buffer.as_slice());
|
|
|
|
if line_end > 0 {
|
|
let cmd = parse_command(&buffer.as_slice()[..line_end]);
|
|
for _ in 0..line_end + 1 {
|
|
buffer.remove(0);
|
|
}
|
|
defmt::info!("truncated buffer");
|
|
|
|
if cmd != Gs232Cmd::Unkown {
|
|
match class.write_packet(b"\r").await {
|
|
Ok(_) => {}
|
|
Err(err) => {
|
|
defmt::error!("Unable to write packet: {}", err);
|
|
break;
|
|
}
|
|
};
|
|
}
|
|
}
|
|
}
|
|
defmt::info!("USB disconnected");
|
|
}
|
|
};
|
|
|
|
join(usb.run(), usb_handler_fut).await;
|
|
}
|
|
|
|
#[derive(PartialEq)]
|
|
enum Gs232Cmd {
|
|
Unkown,
|
|
GetAl,
|
|
GetEz,
|
|
GetAlEz,
|
|
MoveTo(u16, u16),
|
|
Stop,
|
|
}
|
|
|
|
fn parse_command(data: &[u8]) -> Gs232Cmd {
|
|
match data[0] as char {
|
|
'B' => {
|
|
if data.len() == 1 {
|
|
Gs232Cmd::GetAl
|
|
} else {
|
|
Gs232Cmd::Unkown
|
|
}
|
|
}
|
|
|
|
'C' => {
|
|
if data.len() == 2 && data[1] as char == '2' {
|
|
Gs232Cmd::GetAlEz
|
|
} else if data.len() == 1 {
|
|
Gs232Cmd::GetEz
|
|
} else {
|
|
Gs232Cmd::Unkown
|
|
}
|
|
}
|
|
|
|
'W' => {
|
|
if data.len() == 8 {
|
|
|
|
Gs232Cmd::Unkown
|
|
} else {
|
|
Gs232Cmd::Unkown
|
|
}
|
|
}
|
|
|
|
'S' => {
|
|
if data.len() == 1 {
|
|
Gs232Cmd::Stop
|
|
} else {
|
|
Gs232Cmd::Unkown
|
|
}
|
|
}
|
|
|
|
_ => Gs232Cmd::Unkown,
|
|
}
|
|
}
|