Zephyr USB Feature reports

Does Zephyr support USB feature reports? I see examples in Devzone, but they look like they are pre-Zephyr. If an example exists using Zephyr, please include a link.

Thanks for your help.

  • Hi Ray,

    Zephyr does support USB feature reports. You ca maybe refer the nRF_Desktop application which uses one HID feature report:

    HID Data Handling

    HID feature report

    HID feature report desc

    Best Regards,

    Priyanka

  • Hi Priyanka,

    I reviewed the source code for the nRF_Deskop application you mention and other source code in the Nordic library. I was able to find and copy the required sections of code to get basic USB feature report communication to work. The code below will send and receive blocks of eight bytes. If you have any updates I should include in the code please let me know. I will continue with the project and let you know if I have any further issues with USB feature reports.

    Best Regards,

    Ray

    static const struct hid_ops ops = {
    	.get_report   = get_report,
    	.set_report   = set_report,
    	.int_in_ready = in_ready_cb,
    };
    
    static const uint8_t hid_report_desc[] = HID_REPORT_DESC();
    
    
    usb_hid_register_device(hid0_dev, hid_report_desc,
    	sizeof(hid_kbd_report_desc), &ops);
    
    
    static int get_report(const struct device *dev, struct usb_setup_packet *setup, int32_t *len_to_set, uint8_t **data)
    {
    	uint8_t request_value[2];
    
    	sys_put_le16(setup->wValue, request_value);
    
    	switch (request_value[1]) 
    	{
    		case REPORT_TYPE_FEATURE:
    		{
    			size_t length = setup->wLength;
    			uint8_t *buf = *data;
    
    			*len_to_set = length;
    
    			// Data from PC
    			LOG_DBG("length=%d data=%02x %02x %02x %02x %02x %02x %02x %02x", setup->wLength, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
    
    			return 0;
    
    			break;
    		}
    
    		case REPORT_TYPE_INPUT:
    		{
    			LOG_DBG("input report");
    			break;
    		}
    
    		default:
    		{
    			/* Should not happen. */
    			break;
    		}
    	}
    	
    	return -ENOTSUP;
    }
    
    static int set_report(const struct device *dev, struct usb_setup_packet *setup, int32_t *len, uint8_t **data)
    {
    	uint8_t request_value[2];
    
    	sys_put_le16(setup->wValue, request_value);
    
    	switch (request_value[1]) 
    	{
    		case REPORT_TYPE_FEATURE:
    		{
    			size_t length = setup->wLength;
    			uint8_t *buf = *data;
    
    			// Send eight 0x55 bytes
    			memset(buf, 0x55, 8);
    
    			// Data to PC
    			LOG_DBG("length=%d data=%02x %02x %02x %02x %02x %02x %02x %02x", setup->wLength, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]);
    
    			return 0;
    
    			break;
    		}
    
    		case REPORT_TYPE_OUTPUT:
    		{
    			LOG_DBG("output report");
    			break;
    		}
    
    		default:
    		{
    			/* Should not happen. */
    			break;
    		}
    	}
    
    	return -ENOTSUP;
    }

  • Hi Ray,

    This could also be of use to you: https://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/services/usb/hid.html  Slight smile

    As you have mentioned, please continue with your project and don't hesitate to contact in case of further queries.

    -Priyanka

Related