aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/rp/src/bin/usb_serial.rs100
1 files changed, 55 insertions, 45 deletions
diff --git a/examples/rp/src/bin/usb_serial.rs b/examples/rp/src/bin/usb_serial.rs
index 3c9bc96dd..4a802994a 100644
--- a/examples/rp/src/bin/usb_serial.rs
+++ b/examples/rp/src/bin/usb_serial.rs
@@ -5,15 +5,15 @@
5#![no_std] 5#![no_std]
6#![no_main] 6#![no_main]
7 7
8use defmt::{info, panic}; 8use defmt::{info, panic, unwrap};
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_futures::join::join;
11use embassy_rp::bind_interrupts; 10use embassy_rp::bind_interrupts;
12use embassy_rp::peripherals::USB; 11use embassy_rp::peripherals::USB;
13use embassy_rp::usb::{Driver, Instance, InterruptHandler}; 12use embassy_rp::usb::{Driver, Instance, InterruptHandler};
14use embassy_usb::class::cdc_acm::{CdcAcmClass, State}; 13use embassy_usb::class::cdc_acm::{CdcAcmClass, State};
15use embassy_usb::driver::EndpointError; 14use embassy_usb::driver::EndpointError;
16use embassy_usb::{Builder, Config}; 15use embassy_usb::UsbDevice;
16use static_cell::StaticCell;
17use {defmt_rtt as _, panic_probe as _}; 17use {defmt_rtt as _, panic_probe as _};
18 18
19bind_interrupts!(struct Irqs { 19bind_interrupts!(struct Irqs {
@@ -21,7 +21,7 @@ bind_interrupts!(struct Irqs {
21}); 21});
22 22
23#[embassy_executor::main] 23#[embassy_executor::main]
24async fn main(_spawner: Spawner) { 24async fn main(spawner: Spawner) {
25 info!("Hello there!"); 25 info!("Hello there!");
26 26
27 let p = embassy_rp::init(Default::default()); 27 let p = embassy_rp::init(Default::default());
@@ -30,59 +30,69 @@ async fn main(_spawner: Spawner) {
30 let driver = Driver::new(p.USB, Irqs); 30 let driver = Driver::new(p.USB, Irqs);
31 31
32 // Create embassy-usb Config 32 // Create embassy-usb Config
33 let mut config = Config::new(0xc0de, 0xcafe); 33 let config = {
34 config.manufacturer = Some("Embassy"); 34 let mut config = embassy_usb::Config::new(0xc0de, 0xcafe);
35 config.product = Some("USB-serial example"); 35 config.manufacturer = Some("Embassy");
36 config.serial_number = Some("12345678"); 36 config.product = Some("USB-serial example");
37 config.max_power = 100; 37 config.serial_number = Some("12345678");
38 config.max_packet_size_0 = 64; 38 config.max_power = 100;
39 39 config.max_packet_size_0 = 64;
40 // Required for windows compatibility. 40
41 // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help 41 // Required for windows compatibility.
42 config.device_class = 0xEF; 42 // https://developer.nordicsemi.com/nRF_Connect_SDK/doc/1.9.1/kconfig/CONFIG_CDC_ACM_IAD.html#help
43 config.device_sub_class = 0x02; 43 config.device_class = 0xEF;
44 config.device_protocol = 0x01; 44 config.device_sub_class = 0x02;
45 config.composite_with_iads = true; 45 config.device_protocol = 0x01;
46 config.composite_with_iads = true;
47 config
48 };
46 49
47 // Create embassy-usb DeviceBuilder using the driver and config. 50 // Create embassy-usb DeviceBuilder using the driver and config.
48 // It needs some buffers for building the descriptors. 51 // It needs some buffers for building the descriptors.
49 let mut config_descriptor = [0; 256]; 52 let mut builder = {
50 let mut bos_descriptor = [0; 256]; 53 static CONFIG_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new();
51 let mut control_buf = [0; 64]; 54 static BOS_DESCRIPTOR: StaticCell<[u8; 256]> = StaticCell::new();
52 55 static CONTROL_BUF: StaticCell<[u8; 64]> = StaticCell::new();
53 let mut state = State::new(); 56
54 57 let builder = embassy_usb::Builder::new(
55 let mut builder = Builder::new( 58 driver,
56 driver, 59 config,
57 config, 60 CONFIG_DESCRIPTOR.init([0; 256]),
58 &mut config_descriptor, 61 BOS_DESCRIPTOR.init([0; 256]),
59 &mut bos_descriptor, 62 &mut [], // no msos descriptors
60 &mut [], // no msos descriptors 63 CONTROL_BUF.init([0; 64]),
61 &mut control_buf, 64 );
62 ); 65 builder
66 };
63 67
64 // Create classes on the builder. 68 // Create classes on the builder.
65 let mut class = CdcAcmClass::new(&mut builder, &mut state, 64); 69 let mut class = {
70 static STATE: StaticCell<State> = StaticCell::new();
71 let state = STATE.init(State::new());
72 CdcAcmClass::new(&mut builder, state, 64)
73 };
66 74
67 // Build the builder. 75 // Build the builder.
68 let mut usb = builder.build(); 76 let usb = builder.build();
69 77
70 // Run the USB device. 78 // Run the USB device.
71 let usb_fut = usb.run(); 79 unwrap!(spawner.spawn(usb_task(usb)));
72 80
73 // Do stuff with the class! 81 // Do stuff with the class!
74 let echo_fut = async { 82 loop {
75 loop { 83 class.wait_connection().await;
76 class.wait_connection().await; 84 info!("Connected");
77 info!("Connected"); 85 let _ = echo(&mut class).await;
78 let _ = echo(&mut class).await; 86 info!("Disconnected");
79 info!("Disconnected"); 87 }
80 } 88}
81 }; 89
90type MyUsbDriver = Driver<'static, USB>;
91type MyUsbDevice = UsbDevice<'static, MyUsbDriver>;
82 92
83 // Run everything concurrently. 93#[embassy_executor::task]
84 // If we had made everything `'static` above instead, we could do this using separate tasks instead. 94async fn usb_task(mut usb: MyUsbDevice) -> ! {
85 join(usb_fut, echo_fut).await; 95 usb.run().await
86} 96}
87 97
88struct Disconnected {} 98struct Disconnected {}