in IDE dependency tree / definition lookup - for porting

Post here first, or if you can't find a relevant section!
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: in IDE dependency tree / definition lookup - for porting

Post by BennehBoy »

BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: in IDE dependency tree / definition lookup - for porting

Post by BennehBoy »

I thought the core 'HID (keyboard and mouse)' might be a good place to start looking at how to interface with the core to get at the usb stack.

So with that in my I compiled a blinky sketch with this option selected.

Upon insertion into the USB port on Windows 10 this results in the error "USB device not recognised". lsusb on linux (rpi os) shows no new devices inserted.

I tried this on both a bluepill, and a black 407vet6. Both fail.

Is this area of the code WIP @fpiSTM?

Here's the simple sketch I had in mind to inject an alt tab - just mucking about at this point....

Code: Select all

#include "usbd_hid_composite_if.h"

void setup() {
  // put your setup code here, to run once:

#define PRESS_REPORT_SIZE 8
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(PB6, INPUT);
}

void loop() {
  // put your main code here, to run repeatedly:
  uint8_t press_report[PRESS_REPORT_SIZE] = {0};

  if(digitalRead(PB6) == true){
      digitalWrite(LED_BUILTIN, LOW);     
      
      press_report[2] = 0xe2;  // send 'alt' 
      press_report[3] = 0x2b;  // send 'tab' 

      HID_Composite_keyboard_sendReport(press_report, PRESS_REPORT_SIZE);
      
      HAL_Delay(50); 
      
      press_report[2] = 0;
      press_report[3] = 0;

      HID_Composite_keyboard_sendReport(press_report, PRESS_REPORT_SIZE);
      
      HAL_Delay(200);

      digitalWrite(LED_BUILTIN, HIGH);       
    }
}
Naturally the pins may vary between boards and I would adjust accordingly.
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

i think the usb 'stack' is likely rather 'independent' of the arduino 'core', in a sense that if usb isn't initiated from power up (e.g. reset), in setup() we can probably simply do usbcomposite.begin(). and usb can be started up from there. this is probably good as other devices / clocks can be setup ahead of usb being initialized. while i've not experimented with it, it seemed usbcomposite.begin() is kind of missing.
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: in IDE dependency tree / definition lookup - for porting

Post by BennehBoy »

Yes I believe they are independent, but the code for HID Composite may have been a good place to start and see what needs initialising and how (with appropriate back track downward). If it worked :D

CDC is probably just as good a place to start, if not better since it's functional.

There're some interesting PR's too, a CDC/MSC Composite being one that probably illustrates most of the areas of interest.

For me it's a complete journey into unknown territory, so I likely sound like an idiot to anyone sat in a position of knowledge.
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

i've not played with usbcomposite, maybe i'd play with it. i went deep and picked up some 'basics' of usb. hid is one that has a huge learning curve and still learning. hid covers a huge number of 'profiles', but i'd guess only the most basic e.g. keyboard and mouse are supported natively by the 'standard' drivers.

cdc is the 'good' place to start as we're most familiar with it and it is rather 'simple'.
keep the device class specs handy and the usb 2.0 specs as well
https://www.usb.org/documents

then a usb-sniffer is needed
wireshark is one of them, it works on linux for me using the linux native usbmon driver. i'm not sure about windows though.
https://wiki.wireshark.org/CaptureSetup/USB
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: in IDE dependency tree / definition lookup - for porting

Post by BennehBoy »

I have wireshark installed on my rpi4 and was capturing the failed HID initialisation last night. Need to revisit the usb specs/protocols thoroughly to chase that down but would guess it's a malformed descriptor, or something moved on in the core's usb implementation as a result of a change required for CDC that didn't get reflected into the HID code.
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

usb hid initialization looks like this:

first there is a get descriptor call, this is the decoded output from my custom usbmon decoder:

Code: Select all

Evtype	C	Callback
URBtype	Ci	Control input
URBstatus	0	
Interval	0	
StartFrame	0	
ErrorCount	0	
issetup	false	
Setup:bmtype	0	
S:bmty:Dir	0	
S:bmty:Typ	0	
S:bmty:Recipient	0	
Setup:request	0	
Setup:wValue	0	
Setup:wIndex	0	
Setup:wLength	0	
dataLen	59	
dataTag	=	
Words	09023b00 020100a0 fa090400 00010301 01000921 10010001 22360007 05810308 000a0904 01000103 00000009 21100100 01223200 07058203 03000a		;
Linked	True	
PrevReq		GET_DESCRIPTOR
Decode		Desc type:CONFIGURATION ,Desc idx:0
		Configuration Descriptor
bLength	9	
bDescriptorType	2	DEVICE
wTotalLength	59	
bNumInterfaces	2	
bConfigurationValue	1	
iConfiguration	0	
bmAttributes	160	SelfPwr:0 ,RemoteWake:1
bMaxPower	250	
		Interface Descriptor
bLength	9	
bDescriptorType	4	INTERFACE
bInterfaceNumber	0	
bAlternateSetting	0	
bNumEndpoints	1	
bInterfaceClass	3	HID (Human Interface Device)
bInterfaceSubClass	1	Boot Interface Subclass
bInterfaceProtocol	1	Keyboard
iInterface	0	
		Endpoint Descriptor
bLength	7	
bDescriptorType	5	ENDPOINT
bEndpointAddress	81	Addr: 1, Dir:1 IN
bmAttributes	3	Xfer: 3Interrupt,Sync: 0No_Sync,Usage: 0Data
wMaxPacketSize	8	
bInterval	10	
		Interface Descriptor
bLength	9	
bDescriptorType	4	INTERFACE
bInterfaceNumber	1	
bAlternateSetting	0	
bNumEndpoints	1	
bInterfaceClass	3	HID (Human Interface Device)
bInterfaceSubClass	0	
bInterfaceProtocol	0	
iInterface	0	
		Endpoint Descriptor
bLength	7	
bDescriptorType	5	ENDPOINT
bEndpointAddress	82	Addr: 1, Dir:1 IN
bmAttributes	3	Xfer: 3Interrupt,Sync: 0No_Sync,Usage: 0Data
wMaxPacketSize	3	
then normally followed by separate get descriptor call for each interface

Code: Select all

Evtype	C	Callback
URBtype	Ci	Control input
URBstatus	0	
Interval	0	
StartFrame	0	
ErrorCount	0	
issetup	false	
Setup:bmtype	0	
S:bmty:Dir	0	
S:bmty:Typ	0	
S:bmty:Recipient	0	
Setup:request	0	
Setup:wValue	0	
Setup:wIndex	0	
Setup:wLength	0	
dataLen	50	
dataTag	=	
Words	050c0901 a1018501 19002a3c 02150026 3c029501 75108100 c0050109 80a10185 02198129 83250175 01950381 02950581 01c0 ...
Linked	True	
PrevReq		GET_DESCRIPTOR
Decode		Desc type:Report ,Desc idx:0
		Report descrptor
bLength	50	
bDescriptorType	22	Report
Decode		0x05, 0x0c,         // Usage Page (Consumer)
0x09, 0x01,         // Usage (Consumer Control)
0xa1, 0x01,         // Collection (Usage Modifier)
0x85, 0x01,         //   Report ID (1)
0x19, 0x00,         //   Usage Minimum (0)
0x2a, 0x3c, 0x02,   //   Usage Maximum (572)
0x15, 0x00,         //   Logical Minimum (0)
0x26, 0x3c, 0x02,   //   Logical Maximum (572)
0x95, 0x01,         //   Report Count (1)
0x75, 0x10,         //   Report Size (16)
0x81, 0x00,         //   Input (Data, Array, Absolute, No Wrap, Linear, Preferred state, No null position, Bit fields)
0xc0,               // End Collection ()
0x05, 0x01,         // Usage Page (Generic Desktop Controls)
0x09, 0x80,         // Usage (System Control)
0xa1, 0x01,         // Collection (Usage Modifier)
0x85, 0x02,         //   Report ID (2)
0x19, 0x81,         //   Usage Minimum (129)
0x29, 0x83,         //   Usage Maximum (131)
0x25, 0x01,         //   Logical Maximum (1)
0x75, 0x01,         //   Report Size (1)
0x95, 0x03,         //   Report Count (3)
0x81, 0x02,         //   Input (Data, Variable, Absolute, No Wrap, Linear, Preferred state, No null position, Bit fields)
0x95, 0x05,         //   Report Count (5)
0x81, 0x01,         //   Input (Const, Array, Absolute, No Wrap, Linear, Preferred state, No null position, Bit fields)
0xc0,               // End Collection ()

// 50 bytes
^^ if you'd scroll down and take a look i've decoded the report descriptor using that custom java app
that report descriptor

i think it is literally a series of calls, 1st the 'get descriptor' call, for the device, then another call for the configuration, and later another call for each interface. the report descriptor is commonly nested down at the interface. but literally these looks like a bunch of bytes in actual implementation.
there are hid parsers 'out there' like this
https://eleccelerator.com/usbdescreqparser/
https://github.com/NZSmartie/PyHIDParser
the hard part initially is i tried to understand all these cryptic hid report descriptors. in actual implementation, the callback should just return the bunch of bytes for the 'get descriptor' calls.

what then would matter is that for each of the 'Interrupt IN' events (initiated by the host), we'd need to return the bunch of data according to the format we've declared in the hid report descriptor. a hard part is to understand how the hid report descriptor describe the structure of the interrupt IN data packets. on the device, this interrupt IN event is most likely a callback as well. deciphering these would enable us to create any sort of hid devices since we can always return a different 'report descriptor', we can emulate a mouse, keyboard, etc, add all that range of possible 'usage pages' and 'usages', the scope of possible usages can be very large indeed
https://www.usb.org/sites/default/files ... 1_12v2.pdf
but i think most of these the host won't repond to them except for the mouse and keyboard
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

in addition for the tools
http://people.redhat.com/zaitcev/linux/
^search text 'usbmon 6.1' on the web
https://www.mankier.com/8/usbmon

linux normally truncate the displayed bytes from /sys/kernel/debug/usb/usbmon
https://www.kernel.org/doc/Documentation/usb/usbmon.txt

the utility above gets around the truncation using the same text format for usbmon
wireshark probably gets around that truncation as well in its own drivers
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

i think swd / gdb debugging would help here, we'd need to figure out where are the callback hooks, place stops at the actual custom callback functions.
if they did not stop there e.g. get_descriptor custom callback, it'd point to a possible problem. e.g. the hook is not assigned etc. i've yet to get familiar with the usbcore functionality. i'd think there are a set of steps to register the callbacks, initialize etc.
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

i think it is about time i make my handwired keyboard e.g.
https://deskthority.net/viewtopic.php?t=6050
https://geekhack.org/index.php?topic=87689.0
https://henrydiy.wixsite.com/keyboarddiy/handwire-guide

1st generate layout
http://www.keyboard-layout-editor.com/
then generate the plate
http://builder.swillkb.com/

it used to be that one of the hard part is the firmware & hid
but now we have stm32f103 pill boards etc
and given this little understanding about hid
what seemed left is just to buy the switches
https://www.aliexpress.com/wholesale?ca ... ard+switch
and start wiring one up
and a fun part about our little keyboard is that it has a 'powerful' adc so it can double up as a multi-meter + oscilloscope
:lol:
Post Reply

Return to “General discussion”