aboutsummaryrefslogtreecommitdiff
path: root/examples/nrf/src/bin
diff options
context:
space:
mode:
authorDario Nieuwenhuis <[email protected]>2022-04-06 02:37:17 +0200
committerDario Nieuwenhuis <[email protected]>2022-04-06 05:38:11 +0200
commitb2e517bb2860b1ec35bb744b8a28efae50cb2d59 (patch)
treec753e784334941fce38571c95a51e5ebebb3838a /examples/nrf/src/bin
parent3dbb7c9e159aa456c1d85cb4d5c8d1299013d0cc (diff)
usb/serial: add multitask example.
Diffstat (limited to 'examples/nrf/src/bin')
-rw-r--r--examples/nrf/src/bin/usb_serial_multitask.rs122
1 files changed, 122 insertions, 0 deletions
diff --git a/examples/nrf/src/bin/usb_serial_multitask.rs b/examples/nrf/src/bin/usb_serial_multitask.rs
new file mode 100644
index 000000000..bef704417
--- /dev/null
+++ b/examples/nrf/src/bin/usb_serial_multitask.rs
@@ -0,0 +1,122 @@
1#![no_std]
2#![no_main]
3#![feature(generic_associated_types)]
4#![feature(type_alias_impl_trait)]
5
6use core::mem;
7use defmt::{info, panic, unwrap};
8use embassy::executor::Spawner;
9use embassy::util::Forever;
10use embassy_nrf::pac;
11use embassy_nrf::usb::Driver;
12use embassy_nrf::Peripherals;
13use embassy_nrf::{interrupt, peripherals};
14use embassy_usb::driver::{ReadError, WriteError};
15use embassy_usb::{Config, UsbDevice, UsbDeviceBuilder};
16use embassy_usb_serial::{CdcAcmClass, State};
17
18use defmt_rtt as _; // global logger
19use panic_probe as _;
20
21type MyDriver = Driver<'static, peripherals::USBD>;
22
23#[embassy::task]
24async fn usb_task(mut device: UsbDevice<'static, MyDriver>) {
25 device.run().await;
26}
27
28#[embassy::task]
29async fn echo_task(mut class: CdcAcmClass<'static, MyDriver>) {
30 loop {
31 class.wait_connection().await;
32 info!("Connected");
33 let _ = echo(&mut class).await;
34 info!("Disconnected");
35 }
36}
37
38#[embassy::main]
39async fn main(spawner: Spawner, p: Peripherals) {
40 let clock: pac::CLOCK = unsafe { mem::transmute(()) };
41 let power: pac::POWER = unsafe { mem::transmute(()) };
42
43 info!("Enabling ext hfosc...");
44 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) });
45 while clock.events_hfclkstarted.read().bits() != 1 {}
46
47 info!("Waiting for vbus...");
48 while !power.usbregstatus.read().vbusdetect().is_vbus_present() {}
49 info!("vbus OK");
50
51 // Create the driver, from the HAL.
52 let irq = interrupt::take!(USBD);
53 let driver = Driver::new(p.USBD, irq);
54
55 // Create embassy-usb Config
56 let config = Config::new(0xc0de, 0xcafe);
57
58 struct Resources {
59 device_descriptor: [u8; 256],
60 config_descriptor: [u8; 256],
61 bos_descriptor: [u8; 256],
62 control_buf: [u8; 7],
63 serial_state: State<'static>,
64 }
65 static RESOURCES: Forever<Resources> = Forever::new();
66 let res = RESOURCES.put(Resources {
67 device_descriptor: [0; 256],
68 config_descriptor: [0; 256],
69 bos_descriptor: [0; 256],
70 control_buf: [0; 7],
71 serial_state: State::new(),
72 });
73
74 // Create embassy-usb DeviceBuilder using the driver and config.
75 let mut builder = UsbDeviceBuilder::new(
76 driver,
77 config,
78 &mut res.device_descriptor,
79 &mut res.config_descriptor,
80 &mut res.bos_descriptor,
81 &mut res.control_buf,
82 );
83
84 // Create classes on the builder.
85 let class = CdcAcmClass::new(&mut builder, &mut res.serial_state, 64);
86
87 // Build the builder.
88 let usb = builder.build();
89
90 unwrap!(spawner.spawn(usb_task(usb)));
91 unwrap!(spawner.spawn(echo_task(class)));
92}
93
94struct Disconnected {}
95
96impl From<ReadError> for Disconnected {
97 fn from(val: ReadError) -> Self {
98 match val {
99 ReadError::BufferOverflow => panic!("Buffer overflow"),
100 ReadError::Disabled => Disconnected {},
101 }
102 }
103}
104
105impl From<WriteError> for Disconnected {
106 fn from(val: WriteError) -> Self {
107 match val {
108 WriteError::BufferOverflow => panic!("Buffer overflow"),
109 WriteError::Disabled => Disconnected {},
110 }
111 }
112}
113
114async fn echo(class: &mut CdcAcmClass<'static, MyDriver>) -> Result<(), Disconnected> {
115 let mut buf = [0; 64];
116 loop {
117 let n = class.read_packet(&mut buf).await?;
118 let data = &buf[..n];
119 info!("data: {:x}", data);
120 class.write_packet(data).await?;
121 }
122}