cancel
Showing results for 
Search instead for 
Did you mean: 

Bare metal USB HID

Nickelgrass
Senior

Hello,

I am trying to implement a USB HID keyboard on an STM32F042 without HAL or LL, just simple register defs. I took an example code generated in CubeIDE with HAL and a few other examples. I extended the example with HAL to also implement the LEDs which all works fine. 

I understand how it basically works. I define the descriptors and configure the Endpoints etc. Then I need to transfer the descriptors when the host requires them. But what I can not figure out is how exactly the descriptors are actually transferred. The HAL is so overloaded that it seems impossible to find the exact lines of code where the descriptors are transferred to the host and how that is done exactly. Also where do I put the report descriptor to send some key presses? Can anyone give me some info on how that is done?

11 REPLIES 11
Nickelgrass
Senior

So all "seems" to work correctly. I can see on a logic analyzer that the descriptor requests are received and served correctly. But my EP1 is never polled and the USB bus is reset in intervals of 3 to 5 seconds and enumeration starts new. So there must be something wrong in my descriptors. Also it seems that the report descriptor is never requested. 

const uint8_t USB_DeviceDescriptor[] =
{
	0x12,       				// lenght
	0x01,      					// descriptor type device
	0x00, 0x02, 				// usb 2.0
	0x00,       				// device class 0 = defined in interface
	0x00,       				// subclass
	0x00,      					// protocoll
	0x40,       				// packetsize 64 byte
	0x83, 0x04, 				// vendor ST
	0x52, 0x57, 				// product id
	0x00, 0x01, 				// device
	0x01,       				// Manufacturer
	0x02,       				// Product
	0x03,       				// SerialNumber
	0x01        				// bNumConfigurations
};

const uint8_t USB_ConfigDescriptor[] =
{
	0x09,                       // length
	0x02,                       // descriptor type configuration
	0x22, 0x00,                 // total length 34 bytes
	0x01,                       // interfaces 1
	0x01,                       // config value
	0x00,                       // config
	0x80,                       // attributes bus powered remote wakeup
	0x32,                       // power 100 mA
	// interface descriptor
	0x09,                       // length
	0x04,                       // descriptor type interface
	0x00,                       // interface number
	0x00,                       // alternate setting
	0x01,                       // endpoints
	0x03,                       // interface class HID
	0x01,                       // subclass (boot = 1, extended = 0)
	0x01,                       // protocol keyboard
	0x00,                       // interface
	// HID descriptor
	0x09,                       // length
	0x21,                       // descriptor type HID
	0x11, 0x01,                 // HID 1.11
	0x00,                       // country code 0
	0x01,                       // num descriptors
	0x22,                       // descriptor type report
	45, 0x00, 					// length of USB_HID_KeyboardReportDescriptor (set to 0 for only boot mode) 45
	// endpoint descriptor in interrupt
	0x07,                       // length
	0x05,                       // descriptor type endpoint
	0x81,                       // endpoint address 1
	0x03,                       // attributes interrupt
	0x08, 0x00,                 // packet size 8
	0x0A  						// polling interval in ms
};

// standard report descriptor without media keys
const uint8_t USB_HID_KeyboardReportDescriptor[] =
{
	0x05, 0x01,       			// usage page generic desktop
	0x09, 0x06,       			// usage keyboard
	0xA1, 0x01,       			// collection application
	0x05, 0x07,       			// usage page key codes
	0x19, 0xE0,       			// usage min 224
	0x29, 0xE7,       			// usage max 231
	0x15, 0x00,      			// logical min 0
	0x25, 0x01,       			// logical max 1
	0x75, 0x01,     			// report size 1
	0x95, 0x08,     			// report count 8
	0x81, 0x02,       			// input data, var, abs modifier byte
	0x95, 0x01,       			// report count 1
	0x75, 0x08,       			// report size 8
	0x81, 0x01,       			// input const, array, abs reserved byte
	0x95, 0x06,       			// report count 6
	0x75, 0x08,       			// report size 8
	0x15, 0x00,       			// logical min 0
	0x25, 0x65,       			// logical max 101 keys
	0x05, 0x07,       			// usage page key codes
	0x19, 0x00,       			// usage min 0
	0x29, 0x65,       			// usage max 101
	0x81, 0x00,       			// input data, array
	0xC0              			// end collection
};

The request for qualifier descriptor is stalled. 

I have compared and tried all sorts of different examples but it just wont get past the enumeration.

Edit: the point where it stops is when the host requests the clear feature. What is the response to that? Now I just Ack it.

Nickelgrass
Senior

Found the issue, cant edit the post. Now the USB driver works and I have my HID running. It was EP1 not configured in combination with missing the token.