Skip to content

Commit

Permalink
embassy-usb: add string descriptor support for hid class
Browse files Browse the repository at this point in the history
  • Loading branch information
adamaq01 committed Jan 12, 2025
1 parent e8ec586 commit a423193
Show file tree
Hide file tree
Showing 9 changed files with 22 additions and 2 deletions.
16 changes: 14 additions & 2 deletions embassy-usb/src/class/hid.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use usbd_hid::descriptor::AsInputReport;

use crate::control::{InResponse, OutResponse, Recipient, Request, RequestType};
use crate::driver::{Driver, Endpoint, EndpointError, EndpointIn, EndpointOut};
use crate::types::InterfaceNumber;
use crate::types::{InterfaceNumber, StringIndex};
use crate::{Builder, Handler};

const USB_CLASS_HID: u8 = 0x03;
Expand All @@ -36,6 +36,9 @@ pub struct Config<'d> {
/// HID report descriptor.
pub report_descriptor: &'d [u8],

/// Optional string descriptor for the HID interface.
pub string_descriptor: Option<&'d str>,

/// Handler for control requests.
pub request_handler: Option<&'d mut dyn RequestHandler>,

Expand Down Expand Up @@ -112,7 +115,8 @@ fn build<'d, D: Driver<'d>>(
let mut func = builder.function(USB_CLASS_HID, USB_SUBCLASS_NONE, USB_PROTOCOL_NONE);
let mut iface = func.interface();
let if_num = iface.interface_number();
let mut alt = iface.alt_setting(USB_CLASS_HID, USB_SUBCLASS_NONE, USB_PROTOCOL_NONE, None);
let string_index = config.string_descriptor.map(|_| iface.string());
let mut alt = iface.alt_setting(USB_CLASS_HID, USB_SUBCLASS_NONE, USB_PROTOCOL_NONE, string_index);

// HID descriptor
alt.descriptor(
Expand Down Expand Up @@ -145,6 +149,7 @@ fn build<'d, D: Driver<'d>>(
let control = state.control.write(Control::new(
if_num,
config.report_descriptor,
string_index.zip(config.string_descriptor),
config.request_handler,
&state.out_report_offset,
));
Expand Down Expand Up @@ -411,6 +416,7 @@ pub trait RequestHandler {
struct Control<'d> {
if_num: InterfaceNumber,
report_descriptor: &'d [u8],
string_descriptor: Option<(StringIndex, &'d str)>,
request_handler: Option<&'d mut dyn RequestHandler>,
out_report_offset: &'d AtomicUsize,
hid_descriptor: [u8; 9],
Expand All @@ -420,12 +426,14 @@ impl<'d> Control<'d> {
fn new(
if_num: InterfaceNumber,
report_descriptor: &'d [u8],
string_descriptor: Option<(StringIndex, &'d str)>,
request_handler: Option<&'d mut dyn RequestHandler>,
out_report_offset: &'d AtomicUsize,
) -> Self {
Control {
if_num,
report_descriptor,
string_descriptor,
request_handler,
out_report_offset,
hid_descriptor: [
Expand Down Expand Up @@ -549,4 +557,8 @@ impl<'d> Handler for Control<'d> {
_ => None,
}
}

fn get_string(&mut self, index: StringIndex, _lang_id: u16) -> Option<&str> {
self.string_descriptor.and_then(|(idx, s)| (index == idx).then_some(s))
}
}
1 change: 1 addition & 0 deletions examples/nrf52840/src/bin/usb_hid_keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ async fn main(_spawner: Spawner) {
// Create classes on the builder.
let config = embassy_usb::class::hid::Config {
report_descriptor: KeyboardReport::desc(),
string_descriptor: None,
request_handler: None,
poll_ms: 60,
max_packet_size: 64,
Expand Down
1 change: 1 addition & 0 deletions examples/nrf52840/src/bin/usb_hid_mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async fn main(_spawner: Spawner) {
// Create classes on the builder.
let config = embassy_usb::class::hid::Config {
report_descriptor: MouseReport::desc(),
string_descriptor: None,
request_handler: Some(&mut request_handler),
poll_ms: 60,
max_packet_size: 8,
Expand Down
1 change: 1 addition & 0 deletions examples/rp/src/bin/usb_hid_keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ async fn main(_spawner: Spawner) {
// Create classes on the builder.
let config = embassy_usb::class::hid::Config {
report_descriptor: KeyboardReport::desc(),
string_descriptor: None,
request_handler: None,
poll_ms: 60,
max_packet_size: 64,
Expand Down
1 change: 1 addition & 0 deletions examples/rp/src/bin/usb_hid_mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ async fn main(_spawner: Spawner) {
// Create classes on the builder.
let config = embassy_usb::class::hid::Config {
report_descriptor: MouseReport::desc(),
string_descriptor: None,
request_handler: None,
poll_ms: 60,
max_packet_size: 64,
Expand Down
1 change: 1 addition & 0 deletions examples/rp23/src/bin/usb_hid_keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ async fn main(_spawner: Spawner) {
// Create classes on the builder.
let config = embassy_usb::class::hid::Config {
report_descriptor: KeyboardReport::desc(),
string_descriptor: None,
request_handler: None,
poll_ms: 60,
max_packet_size: 64,
Expand Down
1 change: 1 addition & 0 deletions examples/stm32f4/src/bin/usb_hid_keyboard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ async fn main(_spawner: Spawner) {
// Create classes on the builder.
let config = embassy_usb::class::hid::Config {
report_descriptor: KeyboardReport::desc(),
string_descriptor: None,
request_handler: None,
poll_ms: 60,
max_packet_size: 8,
Expand Down
1 change: 1 addition & 0 deletions examples/stm32f4/src/bin/usb_hid_mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ async fn main(_spawner: Spawner) {
// Create classes on the builder.
let config = embassy_usb::class::hid::Config {
report_descriptor: MouseReport::desc(),
string_descriptor: None,
request_handler: Some(&mut request_handler),
poll_ms: 60,
max_packet_size: 8,
Expand Down
1 change: 1 addition & 0 deletions examples/stm32l5/src/bin/usb_hid_mouse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ async fn main(_spawner: Spawner) {
// Create classes on the builder.
let config = embassy_usb::class::hid::Config {
report_descriptor: MouseReport::desc(),
string_descriptor: None,
request_handler: Some(&mut request_handler),
poll_ms: 60,
max_packet_size: 8,
Expand Down

0 comments on commit a423193

Please sign in to comment.