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:
commit
e1a8280e2b
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
100
sys/include/usb/usbus/hid_io.h
Normal file
100
sys/include/usb/usbus/hid_io.h
Normal 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 */
|
||||
/** @} */
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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("");
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user