usbd_human_interface_device/
lib.rs

1#![no_std]
2#![warn(clippy::pedantic)]
3#![warn(clippy::style)]
4#![warn(clippy::cargo)]
5#![allow(clippy::module_name_repetitions)]
6#![allow(clippy::missing_errors_doc)]
7#![allow(clippy::missing_panics_doc)]
8#![allow(clippy::struct_excessive_bools)]
9#![allow(clippy::ignored_unit_patterns)]
10#![warn(clippy::unwrap_used)]
11#![warn(clippy::expect_used)]
12#![warn(clippy::use_self)]
13
14//! ```rust, no_run
15//! # use core::option::Option;
16//! # use core::result::Result;
17//! # use core::todo;
18//! # use usb_device::bus::PollResult;
19//! # use fugit::{ExtU32, MillisDurationU32};
20//! use usbd_human_interface_device::page::Keyboard;
21//! use usbd_human_interface_device::device::keyboard::{KeyboardLedsReport, NKROBootKeyboardConfig};
22//! use usbd_human_interface_device::prelude::*;
23//! # use usb_device::class_prelude::*;
24//! # use usb_device::prelude::*;
25//! # use usb_device::UsbDirection;
26//! #
27//! # trait InputPin {
28//! #     fn is_high(&self) -> Result<bool, core::convert::Infallible>;
29//! #     fn is_low(&self) -> Result<bool, core::convert::Infallible>;
30//! # }
31//! #
32//! # struct DummyUsbBus;
33//! # impl UsbBus for DummyUsbBus{fn alloc_ep(&mut self, ep_dir: UsbDirection, ep_addr: Option<EndpointAddress>, ep_type: EndpointType, max_packet_size: u16, interval: u8) -> usb_device::Result<EndpointAddress> {
34//! #         todo!()
35//! #     }
36//! #
37//! # fn enable(&mut self) {
38//! #         todo!()
39//! #     }
40//! #
41//! # fn reset(&self) {
42//! #         todo!()
43//! #     }
44//! #
45//! # fn set_device_address(&self, addr: u8) {
46//! #         todo!()
47//! #     }
48//! #
49//! # fn write(&self, ep_addr: EndpointAddress, buf: &[u8]) -> usb_device::Result<usize> {
50//! #         todo!()
51//! #     }
52//! #
53//! # fn read(&self, ep_addr: EndpointAddress, buf: &mut [u8]) -> usb_device::Result<usize> {
54//! #         todo!()
55//! #     }
56//! #
57//! # fn set_stalled(&self, ep_addr: EndpointAddress, stalled: bool) {
58//! #         todo!()
59//! #     }
60//! #
61//! # fn is_stalled(&self, ep_addr: EndpointAddress) -> bool {
62//! #         todo!()
63//! #     }
64//! #
65//! # fn suspend(&self) {
66//! #         todo!()
67//! #     }
68//! #
69//! # fn resume(&self) {
70//! #         todo!()
71//! #     }
72//! #
73//! # fn poll(&self) -> PollResult {
74//! #         todo!()
75//! #     }}
76//! #
77//! # let usb_bus = DummyUsbBus{};
78//! # let pin: &dyn InputPin = todo!();
79//! # let update_leds: fn(KeyboardLedsReport) = todo!();
80//! #
81//! # struct CountDown;
82//! #
83//! # impl CountDown{
84//! #     fn start(&mut self, count: MillisDurationU32){}
85//! #     fn wait(&mut self) -> Result<(), ()>{ todo!() }
86//! # }
87//! #
88//! # struct Timer;
89//! # impl Timer {
90//! #    fn count_down(&self) -> CountDown {
91//! #        todo!()
92//! #    }
93//! # }
94//! # let timer: Timer = todo!();
95//!
96//! let usb_alloc = UsbBusAllocator::new(usb_bus);
97//!
98//! let mut keyboard = UsbHidClassBuilder::new()
99//!     .add_device(
100//!         NKROBootKeyboardConfig::default(),
101//!     )
102//!     .build(&usb_alloc);
103//!
104//! let mut usb_dev = UsbDeviceBuilder::new(&usb_alloc, UsbVidPid(0x1209, 0x0001))
105//!     .strings(&[
106//!         StringDescriptors::default()
107//!             .manufacturer("usbd-human-interface-device")
108//!             .product("NKRO Keyboard")
109//!             .serial_number("TEST")]
110//!     ).unwrap()       
111//!     .build();
112//!
113//! let mut tick_timer = timer.count_down();
114//! tick_timer.start(1.millis());
115//!
116//! loop {
117//!     let keys = if pin.is_high().unwrap() {
118//!             [Keyboard::A]
119//!         } else {
120//!             [Keyboard::NoEventIndicated]
121//!     };
122//!
123//!     keyboard.device().write_report(keys).ok();
124//!
125//!     // tick once per ms/at 1kHz
126//!     if tick_timer.wait().is_ok() {
127//!         keyboard.tick().unwrap();
128//!     }
129//!
130//!     if usb_dev.poll(&mut [&mut keyboard]) {
131//!         match keyboard.device().read_report() {
132//!
133//!             Ok(l) => {
134//!                 update_leds(l);
135//!             }
136//!             _ => {}
137//!
138//!         }
139//!     }
140//! }
141//! ```
142
143#![doc = include_str!("../README.md")]
144
145pub(crate) mod fmt;
146
147//Allow the use of std in tests
148#[cfg(test)]
149extern crate std;
150
151use usb_device::UsbError;
152
153pub mod descriptor;
154pub mod device;
155pub mod interface;
156pub mod page;
157pub mod prelude;
158pub mod usb_class;
159
160#[cfg_attr(feature = "defmt", derive(defmt::Format))]
161#[derive(Debug)]
162pub enum UsbHidError {
163    WouldBlock,
164    Duplicate,
165    UsbError(UsbError),
166    SerializationError,
167}
168
169impl From<UsbError> for UsbHidError {
170    fn from(e: UsbError) -> Self {
171        match e {
172            UsbError::WouldBlock => Self::WouldBlock,
173            _ => Self::UsbError(e),
174        }
175    }
176}
177
178mod private {
179    /// Super trait used to mark traits with an exhaustive set of
180    /// implementations
181    pub trait Sealed {}
182}