We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
hid.rs:
use core::cmp::min; use usb_device::Result; use usb_device::bus::{InterfaceNumber, StringIndex, UsbBus, UsbBusAllocator}; use usb_device::class::{ControlIn, ControlOut, UsbClass}; use usb_device::control; use usb_device::control::{Recipient, RequestType}; use usb_device::descriptor::DescriptorWriter; use usb_device::endpoint::{EndpointAddress, EndpointIn, EndpointOut}; use usb_device::UsbError; //use cortex_m_semihosting::hprintln; pub const USB_CLASS_HID: u8 = 0x03; const REPORT_DESCRIPTOR: &[u8] = &[ 0x06, 0xD0, 0xF1, // Usage Page (Reserved 0xF1D0) 0x09, 0x01, // Usage (0x01) 0xA1, 0x01, // Collection (Application) 0x09, 0x20, // Usage (0x20) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x40, // Report Count (64) 0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position) 0x09, 0x21, // Usage (0x21) 0x15, 0x00, // Logical Minimum (0) 0x26, 0xFF, 0x00, // Logical Maximum (255) 0x75, 0x08, // Report Size (8) 0x95, 0x40, // Report Count (64) 0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile) 0xC0, // End Collection ]; pub struct HidClass<'a, B: UsbBus> { intf: InterfaceNumber, read_ep: EndpointOut<'a, B>, write_ep: EndpointIn<'a, B>, buf: [u8; 65], len: usize, } impl<B: UsbBus> HidClass<'_, B> { pub fn new(alloc: &UsbBusAllocator<B>) -> HidClass<'_, B> { HidClass { intf: alloc.interface(), read_ep: alloc.interrupt(8, 10), write_ep: alloc.interrupt(8, 10), buf: [0; 65], len: 0, } } pub fn write(&mut self, data: &[u8]) -> Result<usize> { match self.write_ep.write(data) { Ok(count) => Ok(count), Err(UsbError::WouldBlock) => Ok(0), e => e, } } pub fn read(&mut self, data: &mut [u8]) -> Result<usize> { // Terrible buffering implementation for brevity's sake if self.len == 0 { self.len = match self.read_ep.read(&mut self.buf) { Ok(0) | Err(UsbError::WouldBlock) => return Ok(0), Ok(count) => count, e => return e, }; } let count = min(data.len(), self.len); &data[..count].copy_from_slice(&self.buf[0..count]); self.buf.rotate_left(count); self.len -= count; Ok(count) } } impl<B: UsbBus> UsbClass<B> for HidClass<'_, B> { fn get_configuration_descriptors(&self, writer: &mut DescriptorWriter) -> Result<()> { writer.interface( self.intf, 3, //USB_CLASS_HID, 0, 0)?; let descriptor_len = REPORT_DESCRIPTOR.len(); //hprintln!("report len: {}", descriptor_len).unwrap(); let descriptor_len = (descriptor_len as u16).to_le_bytes(); writer.write( 0x21, &[0x10, 0x01, 0x21, 0x01, 0x22, descriptor_len[0], descriptor_len[1]] )?; writer.endpoint(&self.write_ep)?; writer.endpoint(&self.read_ep)?; //hprintln!("get_configuration_descriptors!").unwrap(); Ok(()) } fn endpoint_in_complete(&mut self, _addr: EndpointAddress) { //hprintln!("endpoint_in_complete!").unwrap(); } fn control_in(&mut self, xfer: ControlIn<B>) { let req = xfer.request(); match (req.request_type, req.recipient) { (RequestType::Standard, Recipient::Interface) => { //hprintln!("control_in!").unwrap(); if req.request == control::Request::GET_DESCRIPTOR { let (dtype, index) = req.descriptor_type_index(); if dtype == 0x22 && index == 0 { let descriptor = REPORT_DESCRIPTOR; xfer.accept_with(descriptor).ok(); } } } _ => {} } } }
main.rs:
#![no_std] #![no_main] extern crate panic_semihosting; // logs messages to the host stderr; requires a debugger use cortex_m::asm::delay; use cortex_m_rt::entry; use stm32f1xx_hal::{prelude::*, stm32}; use usb_device::prelude::*; use stm32_usbd::UsbBus; //use cortex_m_semihosting::hprintln; mod hid; mod vendor; const VID: u16 = 0x1122; const PID: u16 = 0x3344; #[entry] fn main() -> ! { let dp = stm32::Peripherals::take().unwrap(); let mut flash = dp.FLASH.constrain(); let mut rcc = dp.RCC.constrain(); let clocks = rcc .cfgr .use_hse(8.mhz()) .sysclk(48.mhz()) .pclk1(24.mhz()) .freeze(&mut flash.acr); assert!(clocks.usbclk_valid()); let mut gpioa = dp.GPIOA.split(&mut rcc.apb2); // BluePill board has a pull-up resistor on the D+ line. // Pull the D+ pin down to send a RESET condition to the USB bus. let mut usb_dp = gpioa.pa12.into_push_pull_output(&mut gpioa.crh); usb_dp.set_low(); delay(clocks.sysclk().0 / 100); let usb_dm = gpioa.pa11; let usb_dp = usb_dp.into_floating_input(&mut gpioa.crh); let usb_bus = UsbBus::new(dp.USB, (usb_dm, usb_dp)); let mut hid = hid::HidClass::new(&usb_bus); //let mut vendor = vendor::HidClass::new(&usb_bus); // vid/pid: http://pid.codes/1209/CC1D/ let mut usb_dev = UsbDeviceBuilder::new( &usb_bus, UsbVidPid(VID, PID), ) .manufacturer("bitbegin") .product("hid") .serial_number("12345678") //.device_class(3) .build(); //hprintln!("reset!").unwrap(); //usb_dev.force_reset().expect("reset failed"); let mut buf = [0u8; 65]; loop { if !usb_dev.poll(&mut [&mut hid, &mut vendor]) { continue; } match hid.read(&mut buf) { Ok(count) if count > 0 => { // Echo back in upper case hid.write(&buf[0..count]).ok(); }, _ => { }, } } }
this will result in c0000011 - "xact error".
c0000011
if add device_class(0xff) to UsbDeviceBuilder, it will be detected by Windows. but i want to use hidapi, so how to configure hid-class?
device_class(0xff)
UsbDeviceBuilder
The text was updated successfully, but these errors were encountered:
I'm not sure I can help you with this. Try reproducing real device's descriptors and endpoint structure in your device.
Sorry, something went wrong.
@bitbegin Did you manage to solve the problem?
No branches or pull requests
Uh oh!
There was an error while loading. Please reload this page.
hid.rs:
main.rs:
this will result in
c0000011
- "xact error".if add
device_class(0xff)
toUsbDeviceBuilder
, it will be detected by Windows. but i want to use hidapi, so how to configure hid-class?The text was updated successfully, but these errors were encountered: