usb-hid: add Config struct, to avoid too many params.
This commit is contained in:
parent
c0de54a341
commit
f35bde684a
@ -41,6 +41,24 @@ const HID_REQ_SET_REPORT: u8 = 0x09;
|
|||||||
const HID_REQ_GET_PROTOCOL: u8 = 0x03;
|
const HID_REQ_GET_PROTOCOL: u8 = 0x03;
|
||||||
const HID_REQ_SET_PROTOCOL: u8 = 0x0b;
|
const HID_REQ_SET_PROTOCOL: u8 = 0x0b;
|
||||||
|
|
||||||
|
pub struct Config<'d> {
|
||||||
|
/// HID report descriptor.
|
||||||
|
pub report_descriptor: &'d [u8],
|
||||||
|
|
||||||
|
/// Handler for control requests.
|
||||||
|
pub request_handler: Option<&'d dyn RequestHandler>,
|
||||||
|
|
||||||
|
/// Configures how frequently the host should poll for reading/writing HID reports.
|
||||||
|
///
|
||||||
|
/// A lower value means better throughput & latency, at the expense
|
||||||
|
/// of CPU on the device & bandwidth on the bus. A value of 10 is reasonable for
|
||||||
|
/// high performance uses, and a value of 255 is good for best-effort usecases.
|
||||||
|
pub poll_ms: u8,
|
||||||
|
|
||||||
|
/// Max packet size for both the IN and OUT endpoints.
|
||||||
|
pub max_packet_size: u16,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||||
pub enum ReportId {
|
pub enum ReportId {
|
||||||
@ -82,23 +100,20 @@ pub struct HidReaderWriter<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N
|
|||||||
fn build<'d, D: Driver<'d>>(
|
fn build<'d, D: Driver<'d>>(
|
||||||
builder: &mut UsbDeviceBuilder<'d, D>,
|
builder: &mut UsbDeviceBuilder<'d, D>,
|
||||||
state: &'d mut State<'d>,
|
state: &'d mut State<'d>,
|
||||||
report_descriptor: &'static [u8],
|
config: Config<'d>,
|
||||||
request_handler: Option<&'d dyn RequestHandler>,
|
|
||||||
poll_ms: u8,
|
|
||||||
max_packet_size: u16,
|
|
||||||
with_out_endpoint: bool,
|
with_out_endpoint: bool,
|
||||||
) -> (Option<D::EndpointOut>, D::EndpointIn, &'d AtomicUsize) {
|
) -> (Option<D::EndpointOut>, D::EndpointIn, &'d AtomicUsize) {
|
||||||
let control = state.control.write(Control::new(
|
let control = state.control.write(Control::new(
|
||||||
report_descriptor,
|
config.report_descriptor,
|
||||||
request_handler,
|
config.request_handler,
|
||||||
&state.out_report_offset,
|
&state.out_report_offset,
|
||||||
));
|
));
|
||||||
|
|
||||||
let len = report_descriptor.len();
|
let len = config.report_descriptor.len();
|
||||||
let if_num = builder.alloc_interface_with_handler(control);
|
let if_num = builder.alloc_interface_with_handler(control);
|
||||||
let ep_in = builder.alloc_interrupt_endpoint_in(max_packet_size, poll_ms);
|
let ep_in = builder.alloc_interrupt_endpoint_in(config.max_packet_size, config.poll_ms);
|
||||||
let ep_out = if with_out_endpoint {
|
let ep_out = if with_out_endpoint {
|
||||||
Some(builder.alloc_interrupt_endpoint_out(max_packet_size, poll_ms))
|
Some(builder.alloc_interrupt_endpoint_out(config.max_packet_size, config.poll_ms))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@ -145,27 +160,12 @@ impl<'d, D: Driver<'d>, const READ_N: usize, const WRITE_N: usize>
|
|||||||
/// This will allocate one IN and one OUT endpoints. If you only need writing (sending)
|
/// This will allocate one IN and one OUT endpoints. If you only need writing (sending)
|
||||||
/// HID reports, consider using [`HidWriter::new`] instead, which allocates an IN endpoint only.
|
/// HID reports, consider using [`HidWriter::new`] instead, which allocates an IN endpoint only.
|
||||||
///
|
///
|
||||||
/// poll_ms configures how frequently the host should poll for reading/writing
|
|
||||||
/// HID reports. A lower value means better throughput & latency, at the expense
|
|
||||||
/// of CPU on the device & bandwidth on the bus. A value of 10 is reasonable for
|
|
||||||
/// high performance uses, and a value of 255 is good for best-effort usecases.
|
|
||||||
pub fn new(
|
pub fn new(
|
||||||
builder: &mut UsbDeviceBuilder<'d, D>,
|
builder: &mut UsbDeviceBuilder<'d, D>,
|
||||||
state: &'d mut State<'d>,
|
state: &'d mut State<'d>,
|
||||||
report_descriptor: &'static [u8],
|
config: Config<'d>,
|
||||||
request_handler: Option<&'d dyn RequestHandler>,
|
|
||||||
poll_ms: u8,
|
|
||||||
max_packet_size: u16,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (ep_out, ep_in, offset) = build(
|
let (ep_out, ep_in, offset) = build(builder, state, config, true);
|
||||||
builder,
|
|
||||||
state,
|
|
||||||
report_descriptor,
|
|
||||||
request_handler,
|
|
||||||
poll_ms,
|
|
||||||
max_packet_size,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
reader: HidReader {
|
reader: HidReader {
|
||||||
@ -249,20 +249,9 @@ impl<'d, D: Driver<'d>, const N: usize> HidWriter<'d, D, N> {
|
|||||||
pub fn new(
|
pub fn new(
|
||||||
builder: &mut UsbDeviceBuilder<'d, D>,
|
builder: &mut UsbDeviceBuilder<'d, D>,
|
||||||
state: &'d mut State<'d>,
|
state: &'d mut State<'d>,
|
||||||
report_descriptor: &'static [u8],
|
config: Config<'d>,
|
||||||
request_handler: Option<&'d dyn RequestHandler>,
|
|
||||||
poll_ms: u8,
|
|
||||||
max_packet_size: u16,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let (ep_out, ep_in, _offset) = build(
|
let (ep_out, ep_in, _offset) = build(builder, state, config, false);
|
||||||
builder,
|
|
||||||
state,
|
|
||||||
report_descriptor,
|
|
||||||
request_handler,
|
|
||||||
poll_ms,
|
|
||||||
max_packet_size,
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(ep_out.is_none());
|
assert!(ep_out.is_none());
|
||||||
|
|
||||||
@ -422,17 +411,17 @@ pub trait RequestHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Control<'d> {
|
struct Control<'d> {
|
||||||
report_descriptor: &'static [u8],
|
report_descriptor: &'d [u8],
|
||||||
request_handler: Option<&'d dyn RequestHandler>,
|
request_handler: Option<&'d dyn RequestHandler>,
|
||||||
out_report_offset: &'d AtomicUsize,
|
out_report_offset: &'d AtomicUsize,
|
||||||
hid_descriptor: [u8; 9],
|
hid_descriptor: [u8; 9],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Control<'a> {
|
impl<'d> Control<'d> {
|
||||||
fn new(
|
fn new(
|
||||||
report_descriptor: &'static [u8],
|
report_descriptor: &'d [u8],
|
||||||
request_handler: Option<&'a dyn RequestHandler>,
|
request_handler: Option<&'d dyn RequestHandler>,
|
||||||
out_report_offset: &'a AtomicUsize,
|
out_report_offset: &'d AtomicUsize,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Control {
|
Control {
|
||||||
report_descriptor,
|
report_descriptor,
|
||||||
|
@ -88,14 +88,13 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Create classes on the builder.
|
// Create classes on the builder.
|
||||||
let hid = HidReaderWriter::<_, 1, 8>::new(
|
let config = embassy_usb_hid::Config {
|
||||||
&mut builder,
|
report_descriptor: KeyboardReport::desc(),
|
||||||
&mut state,
|
request_handler: Some(&request_handler),
|
||||||
KeyboardReport::desc(),
|
poll_ms: 60,
|
||||||
Some(&request_handler),
|
max_packet_size: 64,
|
||||||
60,
|
};
|
||||||
64,
|
let hid = HidReaderWriter::<_, 1, 8>::new(&mut builder, &mut state, config);
|
||||||
);
|
|
||||||
|
|
||||||
// Build the builder.
|
// Build the builder.
|
||||||
let mut usb = builder.build();
|
let mut usb = builder.build();
|
||||||
|
@ -52,7 +52,7 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||||||
let mut control_buf = [0; 16];
|
let mut control_buf = [0; 16];
|
||||||
let request_handler = MyRequestHandler {};
|
let request_handler = MyRequestHandler {};
|
||||||
|
|
||||||
let mut control = State::new();
|
let mut state = State::new();
|
||||||
|
|
||||||
let mut builder = UsbDeviceBuilder::new(
|
let mut builder = UsbDeviceBuilder::new(
|
||||||
driver,
|
driver,
|
||||||
@ -65,14 +65,14 @@ async fn main(_spawner: Spawner, p: Peripherals) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Create classes on the builder.
|
// Create classes on the builder.
|
||||||
let mut writer = HidWriter::<_, 5>::new(
|
let config = embassy_usb_hid::Config {
|
||||||
&mut builder,
|
report_descriptor: MouseReport::desc(),
|
||||||
&mut control,
|
request_handler: Some(&request_handler),
|
||||||
MouseReport::desc(),
|
poll_ms: 60,
|
||||||
Some(&request_handler),
|
max_packet_size: 8,
|
||||||
60,
|
};
|
||||||
8,
|
|
||||||
);
|
let mut writer = HidWriter::<_, 5>::new(&mut builder, &mut state, config);
|
||||||
|
|
||||||
// Build the builder.
|
// Build the builder.
|
||||||
let mut usb = builder.build();
|
let mut usb = builder.build();
|
||||||
|
Loading…
Reference in New Issue
Block a user