-
-
Save rust-play/09c7c199cf384a67568a206c87d912e4 to your computer and use it in GitHub Desktop.
Code shared from the Rust Playground
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![no_std] | |
#![no_main] | |
use defmt::info; | |
use embassy_executor::Spawner; | |
use embassy_stm32::{ | |
bind_interrupts, peripherals, | |
time::Hertz, | |
usb_otg::{self, Driver, Instance}, | |
Config, | |
}; | |
use embassy_usb::{ | |
class::cdc_acm::{CdcAcmClass, State}, | |
driver::EndpointError, | |
Builder, | |
}; | |
use futures::future::join; | |
use {defmt_rtt as _, panic_probe as _}; | |
bind_interrupts!(struct Irqs { | |
OTG_HS => usb_otg::InterruptHandler<peripherals::USB_OTG_HS>; | |
}); | |
#[embassy_executor::main] | |
async fn main(_spawner: Spawner) { | |
info!("Hello World!"); | |
let mut config = Config::default(); | |
{ | |
use embassy_stm32::rcc::*; | |
config.rcc.hse = Some(Hse { | |
freq: Hertz(8_000_000), | |
mode: HseMode::Oscillator, | |
}); | |
config.rcc.pll_src = PllSource::HSE; | |
config.rcc.pll = Some(Pll { | |
prediv: PllPreDiv::DIV4, | |
mul: PllMul::MUL168, | |
divp: Some(PllPDiv::DIV2), // 8mhz / 4 * 168 / 2 = 168Mhz. | |
divq: Some(PllQDiv::DIV7), // 8mhz / 4 * 168 / 7 = 48Mhz. | |
divr: None, | |
}); | |
config.rcc.ahb_pre = AHBPrescaler::DIV1; | |
config.rcc.apb1_pre = APBPrescaler::DIV4; | |
config.rcc.apb2_pre = APBPrescaler::DIV2; | |
config.rcc.sys = Sysclk::PLL1_P; | |
// config.rcc.mux.clk48sel = mux::Clk48sel::PLL1_Q; | |
} | |
let p = embassy_stm32::init(config); | |
// Create the driver, from the HAL. | |
let mut ep_out_buffer = [0u8; 256]; | |
let mut config = embassy_stm32::usb_otg::Config::default(); | |
config.vbus_detection = true; | |
let driver = Driver::new_fs( | |
p.USB_OTG_HS, | |
Irqs, | |
p.PB15, | |
p.PB14, | |
&mut ep_out_buffer, | |
config, | |
); | |
// Create embassy-usb Config | |
let mut config = embassy_usb::Config::new(0xc0de, 0xcafe); | |
config.manufacturer = Some("Embassy"); | |
config.product = Some("USB-serial example"); | |
config.serial_number = Some("12345678"); | |
// Required for windows compatibility. | |
// 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 msos_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 msos_descriptor, | |
&mut [], // no msos descriptors | |
&mut control_buf, | |
); | |
// 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(); | |
// Do stuff with the class! | |
let echo_fut = async { | |
loop { | |
class.wait_connection().await; | |
info!("Connected"); | |
let _ = echo(&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; | |
} | |
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?; | |
let data = &buf[..n]; | |
info!("data: {:x}", data); | |
class.write_packet(data).await?; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment