aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
Diffstat (limited to 'examples')
-rw-r--r--examples/nrf/src/bin/usb_hid_keyboard.rs148
-rw-r--r--examples/nrf/src/bin/usb_hid_mouse.rs (renamed from examples/nrf/src/bin/usb_hid.rs)0
2 files changed, 148 insertions, 0 deletions
diff --git a/examples/nrf/src/bin/usb_hid_keyboard.rs b/examples/nrf/src/bin/usb_hid_keyboard.rs
new file mode 100644
index 000000000..af70a9a60
--- /dev/null
+++ b/examples/nrf/src/bin/usb_hid_keyboard.rs
@@ -0,0 +1,148 @@
1#![no_std]
2#![no_main]
3#![feature(generic_associated_types)]
4#![feature(type_alias_impl_trait)]
5
6use core::mem;
7use defmt::*;
8use embassy::executor::Spawner;
9use embassy::time::Duration;
10use embassy_nrf::gpio::{Input, Pin, Pull};
11use embassy_nrf::interrupt;
12use embassy_nrf::pac;
13use embassy_nrf::usb::Driver;
14use embassy_nrf::Peripherals;
15use embassy_usb::control::OutResponse;
16use embassy_usb::{Config, UsbDeviceBuilder};
17use embassy_usb_hid::{HidClass, ReportId, RequestHandler, State};
18use futures::future::join;
19use usbd_hid::descriptor::{KeyboardReport, SerializedDescriptor};
20
21use defmt_rtt as _; // global logger
22use panic_probe as _;
23
24#[embassy::main]
25async fn main(_spawner: Spawner, p: Peripherals) {
26 let clock: pac::CLOCK = unsafe { mem::transmute(()) };
27 let power: pac::POWER = unsafe { mem::transmute(()) };
28
29 info!("Enabling ext hfosc...");
30 clock.tasks_hfclkstart.write(|w| unsafe { w.bits(1) });
31 while clock.events_hfclkstarted.read().bits() != 1 {}
32
33 info!("Waiting for vbus...");
34 while !power.usbregstatus.read().vbusdetect().is_vbus_present() {}
35 info!("vbus OK");
36
37 // Create the driver, from the HAL.
38 let irq = interrupt::take!(USBD);
39 let driver = Driver::new(p.USBD, irq);
40
41 // Create embassy-usb Config
42 let mut config = Config::new(0xc0de, 0xcafe);
43 config.manufacturer = Some("Tactile Engineering");
44 config.product = Some("Testy");
45 config.serial_number = Some("12345678");
46 config.max_power = 100;
47 config.max_packet_size_0 = 64;
48
49 // Create embassy-usb DeviceBuilder using the driver and config.
50 // It needs some buffers for building the descriptors.
51 let mut device_descriptor = [0; 256];
52 let mut config_descriptor = [0; 256];
53 let mut bos_descriptor = [0; 256];
54 let mut control_buf = [0; 16];
55 let request_handler = MyRequestHandler {};
56
57 let mut state = State::<64, 64>::new();
58
59 let mut builder = UsbDeviceBuilder::new(
60 driver,
61 config,
62 &mut device_descriptor,
63 &mut config_descriptor,
64 &mut bos_descriptor,
65 &mut control_buf,
66 );
67
68 // Create classes on the builder.
69 let hid = HidClass::with_output_ep(
70 &mut builder,
71 &mut state,
72 KeyboardReport::desc(),
73 Some(&request_handler),
74 60,
75 64,
76 );
77
78 // Build the builder.
79 let mut usb = builder.build();
80
81 // Run the USB device.
82 let usb_fut = usb.run();
83
84 let mut button = Input::new(p.P0_11.degrade(), Pull::Up);
85
86 let (mut hid_in, hid_out) = hid.split();
87
88 // Do stuff with the class!
89 let in_fut = async {
90 loop {
91 button.wait_for_low().await;
92 info!("PRESSED");
93 let report = KeyboardReport {
94 keycodes: [4, 0, 0, 0, 0, 0],
95 leds: 0,
96 modifier: 0,
97 reserved: 0,
98 };
99 match hid_in.serialize(&report).await {
100 Ok(()) => {}
101 Err(e) => warn!("Failed to send report: {:?}", e),
102 };
103
104 button.wait_for_high().await;
105 info!("RELEASED");
106 let report = KeyboardReport {
107 keycodes: [0, 0, 0, 0, 0, 0],
108 leds: 0,
109 modifier: 0,
110 reserved: 0,
111 };
112 match hid_in.serialize(&report).await {
113 Ok(()) => {}
114 Err(e) => warn!("Failed to send report: {:?}", e),
115 };
116 }
117 };
118
119 let out_fut = async {
120 hid_out.run(&MyRequestHandler {}).await;
121 };
122 // Run everything concurrently.
123 // If we had made everything `'static` above instead, we could do this using separate tasks instead.
124 join(usb_fut, join(in_fut, out_fut)).await;
125}
126
127struct MyRequestHandler {}
128
129impl RequestHandler for MyRequestHandler {
130 fn get_report(&self, id: ReportId, _buf: &mut [u8]) -> Option<usize> {
131 info!("Get report for {:?}", id);
132 None
133 }
134
135 fn set_report(&self, id: ReportId, data: &[u8]) -> OutResponse {
136 info!("Set report for {:?}: {=[u8]}", id, data);
137 OutResponse::Accepted
138 }
139
140 fn set_idle(&self, id: Option<ReportId>, dur: Duration) {
141 info!("Set idle rate for {:?} to {:?}", id, dur);
142 }
143
144 fn get_idle(&self, id: Option<ReportId>) -> Option<Duration> {
145 info!("Get idle rate for {:?}", id);
146 None
147 }
148}
diff --git a/examples/nrf/src/bin/usb_hid.rs b/examples/nrf/src/bin/usb_hid_mouse.rs
index 741e234b6..741e234b6 100644
--- a/examples/nrf/src/bin/usb_hid.rs
+++ b/examples/nrf/src/bin/usb_hid_mouse.rs