1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-12-25 06:23:53 +01:00

Merge pull request #16689 from Ollrogge/usb_hid_pr2

usbus/hid_io: add missing header file, add RX callback function
This commit is contained in:
Peter Kietzmann 2021-08-04 15:56:33 +02:00 committed by GitHub
commit e1a8280e2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 187 additions and 68 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Nils Ollrogge
* Copyright (C) 2021 Nils Ollrogge
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for
@ -16,7 +16,7 @@
* @file
* @brief Definition for USB HID interfaces
*
* @author Nils Ollrogge <nils-ollrogge@outlook.de>
* @author Nils Ollrogge <nils.ollrogge@fu-berlin.de>
*/
#ifndef USB_HID_H

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Nils Ollrogge
* Copyright (C) 2021 Nils Ollrogge
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for
@ -21,7 +21,7 @@
* specific handling. A different module is required to provide
* functional handling of the data e.g. UART or STDIO integration.
*
* @author Nils Ollrogge <nils-ollrogge@outlook.de>
* @author Nils Ollrogge <nils.ollrogge@fu-berlin.de>
*/
#ifndef USB_USBUS_HID_H

View File

@ -0,0 +1,100 @@
/*
* Copyright (C) 2021 Nils Ollrogge
*
* This file is subject to the terms and conditions of the GNU Lesser General
* Public License v2.1. See the file LICENSE in the top level directory for
* more details.
*/
/**
* @defgroup usbus_hid_io USBUS HID IO
* @ingroup usb_hid
* @brief USBUS HID IO interface module
*
* @{
*
* @file
* @brief USB HID callback and read/write functions
*
* @author Nils Ollrogge <nils.ollrogge@fu-berlin.de>
*/
#ifndef USB_USBUS_HID_IO_H
#define USB_USBUS_HID_IO_H
#include <string.h>
#include <stdint.h>
#include "usb/usbus.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief USBUS HID IO RX callback function
*/
typedef void (*usb_hid_io_cb_t)(void *);
/**
* @brief Set USBUS HID IO RX callback
*
* @param[in] cb callback function to use
* @param[in] arg argument that will be passed to @p cb
*/
void usb_hid_io_set_rx_cb(usb_hid_io_cb_t cb, void *arg);
/**
* @brief Write data to USB HID IN endpoint buffer
*
* @pre `buffer != NULL`
*
* @param[in] buffer buffer containing data to write
* @param[in] len length of buffer
*/
void usb_hid_io_write(const void *buffer, size_t len);
/**
* @brief Read data from USB HID OUT endpoint (blocking)
*
* Wrapper for @ref isrpipe_read
*
* @pre `buffer != NULL`
*
* @param[out] buffer buffer to read data into
* @param[in] len length of buffer
*
* @return Number of bytes read
*/
int usb_hid_io_read(void *buffer, size_t len);
/**
* @brief Read data from USB HID OUT endpoint (with timeout, blocking)
*
* Wrapper for @ref isrpipe_read_timeout
*
* @pre `buffer != NULL`
*
* @param[out] buffer buffer to read data into
* @param[in] len length of buffer
* @param[in] timeout timeout in microseconds
*
* @return Number of bytes read
*/
int usb_hid_io_read_timeout(void *buffer, size_t len, uint32_t timeout);
/**
* @brief Initialize an USB HID IO interface
*
* @param[in] usbus USBUS context
* @param[in] report_desc USB_HID report descriptor
* @param[in] report_desc_size size of USB_HID report descriptor
*/
void usb_hid_io_init(usbus_t *usbus, const uint8_t *report_desc, size_t report_desc_size);
#ifdef __cplusplus
}
#endif
#endif /* USB_USBUS_HID_IO_H */
/** @} */

View File

@ -11,7 +11,7 @@
* @{
* @file
*
* @author Nils Ollrogge <nils-ollrogge@outlook.de>
* @author Nils Ollrogge <nils.ollrogge@fu-berlin.de>
* @}
*/
@ -107,9 +107,9 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
hid->hid_descr.arg = hid;
/*
Configure Interface as USB_HID interface, choosing NONE for subclass and
protocol in order to represent a generic I/O device
*/
Configure Interface as USB_HID interface, choosing NONE for subclass and
protocol in order to represent a generic I/O device
*/
hid->iface.class = USB_CLASS_HID;
hid->iface.subclass = USB_HID_SUBCLASS_NONE;
hid->iface.protocol = USB_HID_PROTOCOL_NONE;
@ -118,9 +118,9 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
/* IN endpoint to send data to host */
hid->ep_in = usbus_add_endpoint(usbus, &hid->iface,
USB_EP_TYPE_INTERRUPT,
USB_EP_DIR_IN,
CONFIG_USBUS_HID_INTERRUPT_EP_SIZE);
USB_EP_TYPE_INTERRUPT,
USB_EP_DIR_IN,
CONFIG_USBUS_HID_INTERRUPT_EP_SIZE);
/* interrupt endpoint polling rate in ms */
hid->ep_in->interval = 0x05;
@ -129,8 +129,8 @@ static void _init(usbus_t *usbus, usbus_handler_t *handler)
/* OUT endpoint to receive data from host */
hid->ep_out = usbus_add_endpoint(usbus, &hid->iface,
USB_EP_TYPE_INTERRUPT, USB_EP_DIR_OUT,
CONFIG_USBUS_HID_INTERRUPT_EP_SIZE);
USB_EP_TYPE_INTERRUPT, USB_EP_DIR_OUT,
CONFIG_USBUS_HID_INTERRUPT_EP_SIZE);
/* interrupt endpoint polling rate in ms */
hid->ep_out->interval = 0x05;
@ -150,9 +150,9 @@ static void _event_handler(usbus_t *usbus, usbus_handler_t *handler,
(void)handler;
switch (event) {
default:
DEBUG("USB HID unhandled event: 0x%x\n", event);
break;
default:
DEBUG("USB HID unhandled event: 0x%x\n", event);
break;
}
}
@ -167,39 +167,39 @@ static int _control_handler(usbus_t *usbus, usbus_handler_t *handler,
/* Requests defined in USB HID 1.11 spec section 7 */
switch (setup->request) {
case USB_SETUP_REQ_GET_DESCRIPTOR: {
uint8_t desc_type = setup->value >> 8;
if (desc_type == USB_HID_DESCR_REPORT) {
usbus_control_slicer_put_bytes(usbus, hid->report_desc,
hid->report_desc_size);
}
else if (desc_type == USB_HID_DESCR_HID) {
_gen_hid_descriptor(usbus, NULL);
}
break;
case USB_SETUP_REQ_GET_DESCRIPTOR: {
uint8_t desc_type = setup->value >> 8;
if (desc_type == USB_HID_DESCR_REPORT) {
usbus_control_slicer_put_bytes(usbus, hid->report_desc,
hid->report_desc_size);
}
case USB_HID_REQUEST_GET_REPORT:
break;
case USB_HID_REQUEST_GET_IDLE:
break;
case USB_HID_REQUEST_GET_PROTOCOL:
break;
case USB_HID_REQUEST_SET_REPORT:
if ((state == USBUS_CONTROL_REQUEST_STATE_OUTDATA)) {
size_t size = 0;
uint8_t *data = usbus_control_get_out_data(usbus, &size);
if (size > 0) {
hid->cb(hid, data, size);
}
else if (desc_type == USB_HID_DESCR_HID) {
_gen_hid_descriptor(usbus, NULL);
}
break;
}
case USB_HID_REQUEST_GET_REPORT:
break;
case USB_HID_REQUEST_GET_IDLE:
break;
case USB_HID_REQUEST_GET_PROTOCOL:
break;
case USB_HID_REQUEST_SET_REPORT:
if ((state == USBUS_CONTROL_REQUEST_STATE_OUTDATA)) {
size_t size = 0;
uint8_t *data = usbus_control_get_out_data(usbus, &size);
if (size > 0) {
hid->cb(hid, data, size);
}
break;
case USB_HID_REQUEST_SET_IDLE:
break;
case USB_HID_REQUEST_SET_PROTOCOL:
break;
default:
DEBUG("USB_HID: unknown request %d \n", setup->request);
return -1;
}
break;
case USB_HID_REQUEST_SET_IDLE:
break;
case USB_HID_REQUEST_SET_PROTOCOL:
break;
default:
DEBUG("USB_HID: unknown request %d \n", setup->request);
return -1;
}
return 1;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Nils Ollrogge
* Copyright (C) 2021 Nils Ollrogge
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -7,12 +7,11 @@
*/
/**
* @ingroup usbus_hid
* @ingroup usbus_hid_io
* @{
* @file
* @brief This file implements a USB HID callback and read/write functions.
*
* @author Nils Ollrogge <nils-ollrogge@outlook.de>
* @author Nils Ollrogge <nils.ollrogge@fu-berlin.de>
* @}
*/
@ -25,6 +24,7 @@
#include "usb/usbus.h"
#include "usb/usbus/hid.h"
#include "usb/usbus/hid_io.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
@ -32,20 +32,25 @@
static usbus_hid_device_t hid;
static uint8_t _hid_rx_buf_mem[CONFIG_USBUS_HID_INTERRUPT_EP_SIZE];
static isrpipe_t _hid_stdio_isrpipe = ISRPIPE_INIT(_hid_rx_buf_mem);
static usb_hid_io_cb_t _rx_cb;
static void *_rx_cb_arg;
int usb_hid_io_read(void *buffer, size_t size)
int usb_hid_io_read(void *buffer, size_t len)
{
return isrpipe_read(&_hid_stdio_isrpipe, buffer, size);
assert(buffer);
return isrpipe_read(&_hid_stdio_isrpipe, buffer, len);
}
int usb_hid_io_read_timeout(void *buffer, size_t size, uint32_t timeout)
int usb_hid_io_read_timeout(void *buffer, size_t len, uint32_t timeout)
{
return isrpipe_read_timeout(&_hid_stdio_isrpipe, buffer, size, timeout);
assert(buffer);
return isrpipe_read_timeout(&_hid_stdio_isrpipe, buffer, len, timeout);
}
void usb_hid_io_write(const void *buffer, size_t len)
{
uint8_t* buffer_ep = hid.ep_in->ep->buf;
assert(buffer);
uint8_t *buffer_ep = hid.ep_in->ep->buf;
uint16_t max_size = hid.ep_in->maxpacketsize;
size_t offset = 0;
@ -73,10 +78,22 @@ static void _hid_rx_pipe(usbus_hid_device_t *hid, uint8_t *data, size_t len)
for (size_t i = 0; i < len; i++) {
isrpipe_write_one(&_hid_stdio_isrpipe, data[i]);
}
if (_rx_cb) {
_rx_cb(_rx_cb_arg);
}
}
void usb_hid_io_init(usbus_t *usbus, uint8_t *report_desc,
void usb_hid_io_init(usbus_t *usbus, const uint8_t *report_desc,
size_t report_desc_size)
{
assert(usbus);
assert(report_desc);
usbus_hid_init(usbus, &hid, _hid_rx_pipe, report_desc, report_desc_size);
}
void usb_hid_io_set_rx_cb(usb_hid_io_cb_t cb, void *arg)
{
_rx_cb = cb;
_rx_cb_arg = arg;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2020 Nils Ollrogge
* Copyright (C) 2021 Nils Ollrogge
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
@ -13,7 +13,7 @@
*
* @brief Tests for USB HID
*
* @author Nils Ollrogge <nils-ollrogge@outlook.de>
* @author Nils Ollrogge <nils.ollrogge@fu-berlin.de>
*/
#include <stdio.h>
@ -22,13 +22,14 @@
#include "usb/usbus.h"
#include "xtimer.h"
#include "usb/usbus/hid.h"
#include "usb/usbus/hid_io.h"
/*
this descriptor is used, because the basic usb_hid interface was developed in
conjunction with FIDO2. Descriptor is taken from CTAP2 specification
(version 20190130) section 8.1.8.2
*/
static uint8_t report_desc_ctap[] = {
static const uint8_t report_desc_ctap[] = {
0x06, 0xD0, 0xF1, /* HID_UsagePage ( FIDO_USAGE_PAGE ) */
0x09, 0x01, /* HID_Usage ( FIDO_USAGE_CTAPHID ) */
0xA1, 0x01, /* HID_Collection ( HID_Application ) */
@ -49,19 +50,20 @@ static uint8_t report_desc_ctap[] = {
static usbus_t usbus;
static char _stack[USBUS_STACKSIZE];
static char test_arg[] = { "Test argument" };
void usb_hid_io_init(usbus_t *usbus, uint8_t *report_desc,
size_t report_desc_size);
ssize_t usb_hid_io_read(void *buffer, size_t len);
static void rx_cb(void *arg)
{
printf("USB_HID rx_cb: %s \n", (char *)arg);
}
void init(void)
static void init(void)
{
usbdev_t *usbdev = usbdev_get_ctx(0);
usbus_init(&usbus, usbdev);
usb_hid_io_init(&usbus, report_desc_ctap, sizeof(report_desc_ctap));
usb_hid_io_set_rx_cb(rx_cb, test_arg);
usbus_create(_stack, USBUS_STACKSIZE, USBUS_PRIO, USBUS_TNAME, &usbus);
}
@ -80,10 +82,10 @@ int main(void)
ssize_t len =
usb_hid_io_read(buffer, CONFIG_USBUS_HID_INTERRUPT_EP_SIZE);
printf("Msg received via USB HID: ");
puts("Msg received via USB HID: ");
for (int i = 0; i < len; i++) {
putc(buffer[i], stdout);
}
printf("\n");
puts("");
}
}