mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/usb_device/hid' into 'master'
usb: Add HID device example Closes IDFGH-7637, IDFGH-5054, IDF-581, and IDFGH-6013 See merge request espressif/esp-idf!19177
This commit is contained in:
commit
5bd6696557
@ -107,7 +107,7 @@ menu "TinyUSB Stack"
|
|||||||
Name of the MSC device.
|
Name of the MSC device.
|
||||||
|
|
||||||
config TINYUSB_DESC_HID_STRING
|
config TINYUSB_DESC_HID_STRING
|
||||||
depends on TINYUSB_HID_ENABLED
|
depends on TINYUSB_HID_COUNT > 0
|
||||||
string "HID Device String"
|
string "HID Device String"
|
||||||
default "Espressif HID Device"
|
default "Espressif HID Device"
|
||||||
help
|
help
|
||||||
@ -175,6 +175,14 @@ menu "TinyUSB Stack"
|
|||||||
help
|
help
|
||||||
Enable TinyUSB MIDI feature.
|
Enable TinyUSB MIDI feature.
|
||||||
endmenu # "MIDI"
|
endmenu # "MIDI"
|
||||||
endif # TINYUSB
|
|
||||||
|
|
||||||
|
menu "Human Interface Device Class (HID)"
|
||||||
|
config TINYUSB_HID_COUNT
|
||||||
|
int "TinyUSB HID interfaces count"
|
||||||
|
default 0
|
||||||
|
range 0 4
|
||||||
|
help
|
||||||
|
Setting value greater than 0 will enable TinyUSB HID feature.
|
||||||
|
endmenu # "HID Device Class (HID)"
|
||||||
|
endif # TINYUSB
|
||||||
endmenu # "TinyUSB Stack"
|
endmenu # "TinyUSB Stack"
|
||||||
|
@ -11,7 +11,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define USB_ESPRESSIF_VID 0x303A
|
#define USB_ESPRESSIF_VID 0x303A
|
||||||
#define USB_STRING_DESCRIPTOR_ARRAY_SIZE 8
|
#define USB_STRING_DESCRIPTOR_ARRAY_SIZE 7
|
||||||
|
|
||||||
typedef enum{
|
typedef enum{
|
||||||
TINYUSB_USBDEV_0,
|
TINYUSB_USBDEV_0,
|
||||||
|
@ -41,8 +41,8 @@ extern "C" {
|
|||||||
# define CONFIG_TINYUSB_MSC_ENABLED 0
|
# define CONFIG_TINYUSB_MSC_ENABLED 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_TINYUSB_HID_ENABLED
|
#ifndef CONFIG_TINYUSB_HID_COUNT
|
||||||
# define CONFIG_TINYUSB_HID_ENABLED 0
|
# define CONFIG_TINYUSB_HID_COUNT 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_TINYUSB_MIDI_ENABLED
|
#ifndef CONFIG_TINYUSB_MIDI_ENABLED
|
||||||
@ -82,9 +82,6 @@ extern "C" {
|
|||||||
// MSC Buffer size of Device Mass storage
|
// MSC Buffer size of Device Mass storage
|
||||||
#define CFG_TUD_MSC_BUFSIZE CONFIG_TINYUSB_MSC_BUFSIZE
|
#define CFG_TUD_MSC_BUFSIZE CONFIG_TINYUSB_MSC_BUFSIZE
|
||||||
|
|
||||||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
|
||||||
#define CFG_TUD_HID_BUFSIZE CONFIG_TINYUSB_HID_BUFSIZE
|
|
||||||
|
|
||||||
#define CFG_TUD_MIDI_EP_BUFSIZE 64
|
#define CFG_TUD_MIDI_EP_BUFSIZE 64
|
||||||
#define CFG_TUD_MIDI_EPSIZE CFG_TUD_MIDI_EP_BUFSIZE
|
#define CFG_TUD_MIDI_EPSIZE CFG_TUD_MIDI_EP_BUFSIZE
|
||||||
#define CFG_TUD_MIDI_RX_BUFSIZE 64
|
#define CFG_TUD_MIDI_RX_BUFSIZE 64
|
||||||
@ -97,7 +94,7 @@ extern "C" {
|
|||||||
#define CFG_TUD_CDC 0
|
#define CFG_TUD_CDC 0
|
||||||
#endif
|
#endif
|
||||||
#define CFG_TUD_MSC CONFIG_TINYUSB_MSC_ENABLED
|
#define CFG_TUD_MSC CONFIG_TINYUSB_MSC_ENABLED
|
||||||
#define CFG_TUD_HID CONFIG_TINYUSB_HID_ENABLED
|
#define CFG_TUD_HID CONFIG_TINYUSB_HID_COUNT
|
||||||
#define CFG_TUD_MIDI CONFIG_TINYUSB_MIDI_ENABLED
|
#define CFG_TUD_MIDI CONFIG_TINYUSB_MIDI_ENABLED
|
||||||
#define CFG_TUD_CUSTOM_CLASS CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED
|
#define CFG_TUD_CUSTOM_CLASS CONFIG_TINYUSB_CUSTOM_CLASS_ENABLED
|
||||||
|
|
||||||
|
@ -33,12 +33,12 @@ esp_err_t tinyusb_driver_install(const tinyusb_config_t *config)
|
|||||||
.otg_mode = USB_OTG_MODE_DEVICE,
|
.otg_mode = USB_OTG_MODE_DEVICE,
|
||||||
};
|
};
|
||||||
usb_phy_gpio_conf_t gpio_conf = {
|
usb_phy_gpio_conf_t gpio_conf = {
|
||||||
.vp_io_num = USBPHY_VP_NUM,
|
.vp_io_num = USBPHY_VP_NUM,
|
||||||
.vm_io_num = USBPHY_VM_NUM,
|
.vm_io_num = USBPHY_VM_NUM,
|
||||||
.rcv_io_num = USBPHY_RCV_NUM,
|
.rcv_io_num = USBPHY_RCV_NUM,
|
||||||
.oen_io_num = USBPHY_OEN_NUM,
|
.oen_io_num = USBPHY_OEN_NUM,
|
||||||
.vpo_io_num = USBPHY_VPO_NUM,
|
.vpo_io_num = USBPHY_VPO_NUM,
|
||||||
.vmo_io_num = USBPHY_VMO_NUM,
|
.vmo_io_num = USBPHY_VMO_NUM,
|
||||||
};
|
};
|
||||||
if (config->external_phy) {
|
if (config->external_phy) {
|
||||||
phy_conf.target = USB_PHY_TARGET_EXT;
|
phy_conf.target = USB_PHY_TARGET_EXT;
|
||||||
@ -48,6 +48,10 @@ esp_err_t tinyusb_driver_install(const tinyusb_config_t *config)
|
|||||||
}
|
}
|
||||||
ESP_RETURN_ON_ERROR(usb_new_phy(&phy_conf, &phy_hdl), TAG, "Install USB PHY failed");
|
ESP_RETURN_ON_ERROR(usb_new_phy(&phy_conf, &phy_hdl), TAG, "Install USB PHY failed");
|
||||||
|
|
||||||
|
#if (CONFIG_TINYUSB_HID_COUNT > 0)
|
||||||
|
// For HID device, configuration descriptor must be provided
|
||||||
|
ESP_RETURN_ON_FALSE(config->configuration_descriptor, ESP_ERR_INVALID_ARG, TAG, "Configuration descriptor must be provided for HID device");
|
||||||
|
#endif
|
||||||
dev_descriptor = config->device_descriptor ? config->device_descriptor : &descriptor_dev_kconfig;
|
dev_descriptor = config->device_descriptor ? config->device_descriptor : &descriptor_dev_kconfig;
|
||||||
string_descriptor = config->string_descriptor ? config->string_descriptor : descriptor_str_kconfig;
|
string_descriptor = config->string_descriptor ? config->string_descriptor : descriptor_str_kconfig;
|
||||||
cfg_descriptor = config->configuration_descriptor ? config->configuration_descriptor : descriptor_cfg_kconfig;
|
cfg_descriptor = config->configuration_descriptor ? config->configuration_descriptor : descriptor_cfg_kconfig;
|
||||||
|
@ -56,8 +56,7 @@ tusb_desc_strarray_device_t descriptor_str_tinyusb = {
|
|||||||
"123456", // 3: Serials, should use chip ID
|
"123456", // 3: Serials, should use chip ID
|
||||||
"TinyUSB CDC", // 4: CDC Interface
|
"TinyUSB CDC", // 4: CDC Interface
|
||||||
"TinyUSB MSC", // 5: MSC Interface
|
"TinyUSB MSC", // 5: MSC Interface
|
||||||
"TinyUSB HID", // 6: HID
|
"TinyUSB MIDI" // 6: MIDI
|
||||||
"TinyUSB MIDI" // 7: MIDI
|
|
||||||
};
|
};
|
||||||
/* End of TinyUSB default */
|
/* End of TinyUSB default */
|
||||||
|
|
||||||
@ -121,28 +120,14 @@ tusb_desc_strarray_device_t descriptor_str_kconfig = {
|
|||||||
"",
|
"",
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CONFIG_TINYUSB_HID_ENABLED
|
|
||||||
CONFIG_TINYUSB_DESC_HID_STRING // 6: HIDs
|
|
||||||
#else
|
|
||||||
"",
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CONFIG_TINYUSB_MIDI_ENABLED
|
#if CONFIG_TINYUSB_MIDI_ENABLED
|
||||||
CONFIG_TINYUSB_DESC_MIDI_STRING // 7: MIDI
|
CONFIG_TINYUSB_DESC_MIDI_STRING // 6: MIDI
|
||||||
#else
|
#else
|
||||||
"",
|
"",
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//------------- HID Report Descriptor -------------//
|
|
||||||
#if CFG_TUD_HID
|
|
||||||
enum {
|
|
||||||
REPORT_ID_KEYBOARD = 1,
|
|
||||||
REPORT_ID_MOUSE
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//------------- Configuration Descriptor -------------//
|
//------------- Configuration Descriptor -------------//
|
||||||
enum {
|
enum {
|
||||||
#if CFG_TUD_CDC
|
#if CFG_TUD_CDC
|
||||||
@ -159,10 +144,6 @@ enum {
|
|||||||
ITF_NUM_MSC,
|
ITF_NUM_MSC,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_HID
|
|
||||||
ITF_NUM_HID,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CFG_TUD_MIDI
|
#if CFG_TUD_MIDI
|
||||||
ITF_NUM_MIDI,
|
ITF_NUM_MIDI,
|
||||||
ITF_NUM_MIDI_STREAMING,
|
ITF_NUM_MIDI_STREAMING,
|
||||||
@ -175,7 +156,6 @@ enum {
|
|||||||
TUSB_DESC_TOTAL_LEN = TUD_CONFIG_DESC_LEN +
|
TUSB_DESC_TOTAL_LEN = TUD_CONFIG_DESC_LEN +
|
||||||
CFG_TUD_CDC * TUD_CDC_DESC_LEN +
|
CFG_TUD_CDC * TUD_CDC_DESC_LEN +
|
||||||
CFG_TUD_MSC * TUD_MSC_DESC_LEN +
|
CFG_TUD_MSC * TUD_MSC_DESC_LEN +
|
||||||
CFG_TUD_HID * TUD_HID_DESC_LEN +
|
|
||||||
CFG_TUD_MIDI * TUD_MIDI_DESC_LEN
|
CFG_TUD_MIDI * TUD_MIDI_DESC_LEN
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -197,24 +177,13 @@ enum {
|
|||||||
EPNUM_MSC,
|
EPNUM_MSC,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_HID
|
|
||||||
EPNUM_HID,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CFG_TUD_MIDI
|
#if CFG_TUD_MIDI
|
||||||
EPNUM_MIDI,
|
EPNUM_MIDI,
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#if CFG_TUD_HID //HID Report Descriptor
|
|
||||||
uint8_t const desc_hid_report[] = {
|
|
||||||
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID_KEYBOARD), ),
|
|
||||||
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(REPORT_ID_MOUSE), )
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
uint8_t const descriptor_cfg_kconfig[] = {
|
uint8_t const descriptor_cfg_kconfig[] = {
|
||||||
// interface count, string index, total length, attribute, power in mA
|
// Configuration number, interface count, string index, total length, attribute, power in mA
|
||||||
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||||
|
|
||||||
#if CFG_TUD_CDC
|
#if CFG_TUD_CDC
|
||||||
@ -232,14 +201,9 @@ uint8_t const descriptor_cfg_kconfig[] = {
|
|||||||
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512
|
TUD_MSC_DESCRIPTOR(ITF_NUM_MSC, 5, EPNUM_MSC, 0x80 | EPNUM_MSC, 64), // highspeed 512
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if CFG_TUD_HID
|
|
||||||
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
|
|
||||||
TUD_HID_DESCRIPTOR(ITF_NUM_HID, 6, HID_PROTOCOL_NONE, sizeof(desc_hid_report), 0x80 | EPNUM_HID, 16, 10)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if CFG_TUD_MIDI
|
#if CFG_TUD_MIDI
|
||||||
// Interface number, string index, EP Out & EP In address, EP size
|
// Interface number, string index, EP Out & EP In address, EP size
|
||||||
TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 7, EPNUM_MIDI, 0x80 | EPNUM_MIDI, 64) // highspeed 512
|
TUD_MIDI_DESCRIPTOR(ITF_NUM_MIDI, 6, EPNUM_MIDI, 0x80 | EPNUM_MIDI, 64) // highspeed 512
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -28,7 +28,13 @@ void app_main(void)
|
|||||||
/* Setting TinyUSB up */
|
/* Setting TinyUSB up */
|
||||||
ESP_LOGI(TAG, "USB initialization");
|
ESP_LOGI(TAG, "USB initialization");
|
||||||
|
|
||||||
tinyusb_config_t tusb_cfg = { 0 }; // the configuration uses default values
|
const tinyusb_config_t tusb_cfg = {
|
||||||
|
.device_descriptor = NULL,
|
||||||
|
.string_descriptor = NULL,
|
||||||
|
.external_phy = false, // In the most cases you need to use a `false` value
|
||||||
|
.configuration_descriptor = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
||||||
|
|
||||||
tinyusb_config_cdcacm_t acm_cfg = { 0 }; // the configuration uses default values
|
tinyusb_config_cdcacm_t acm_cfg = { 0 }; // the configuration uses default values
|
||||||
|
8
examples/peripherals/usb/device/tusb_hid/CMakeLists.txt
Normal file
8
examples/peripherals/usb/device/tusb_hid/CMakeLists.txt
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# For more information about build system see
|
||||||
|
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
|
||||||
|
# The following five lines of boilerplate have to be in your project's
|
||||||
|
# CMakeLists in this exact order for cmake to work correctly
|
||||||
|
cmake_minimum_required(VERSION 3.16)
|
||||||
|
|
||||||
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
|
project(tusb_hid)
|
80
examples/peripherals/usb/device/tusb_hid/README.md
Normal file
80
examples/peripherals/usb/device/tusb_hid/README.md
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
| Supported Targets | ESP32-S2 | ESP32-S3 |
|
||||||
|
| ----------------- | -------- | -------- |
|
||||||
|
|
||||||
|
# TinyUSB Human Interface Device Example
|
||||||
|
|
||||||
|
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||||
|
|
||||||
|
Human interface devices (HID) are one of the most common USB devices, it is implemented in various devices such as keyboards, mice, game controllers, sensors and alphanumeric display devices.
|
||||||
|
In this example, we implement USB keyboard and mouse.
|
||||||
|
Upon connection to USB host (PC), the example application will sent 'key a/A pressed & released' events and move mouse in a square trajectory. To send these HID reports again, press the BOOT button, that is present on most ESP development boards (GPIO0).
|
||||||
|
|
||||||
|
As a USB stack, a TinyUSB component is used.
|
||||||
|
|
||||||
|
## How to use example
|
||||||
|
|
||||||
|
### Hardware Required
|
||||||
|
|
||||||
|
Any ESP board that have USB-OTG supported.
|
||||||
|
|
||||||
|
#### Pin Assignment
|
||||||
|
|
||||||
|
_Note:_ In case your board doesn't have micro-USB connector connected to USB-OTG peripheral, you may have to DIY a cable and connect **D+** and **D-** to the pins listed below.
|
||||||
|
|
||||||
|
See common pin assignments for USB Device examples from [upper level](../../README.md#common-pin-assignments).
|
||||||
|
|
||||||
|
Boot signal (GPIO0) is used to send HID reports to USB host.
|
||||||
|
|
||||||
|
### Build and Flash
|
||||||
|
|
||||||
|
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
idf.py -p PORT flash monitor
|
||||||
|
```
|
||||||
|
|
||||||
|
(Replace PORT with the name of the serial port to use.)
|
||||||
|
|
||||||
|
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||||
|
|
||||||
|
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||||
|
|
||||||
|
## Example Output
|
||||||
|
|
||||||
|
After the flashing you should see the output at idf monitor:
|
||||||
|
|
||||||
|
```
|
||||||
|
I (290) cpu_start: Starting scheduler on PRO CPU.
|
||||||
|
I (0) cpu_start: Starting scheduler on APP CPU.
|
||||||
|
I (310) example: USB initialization
|
||||||
|
I (310) tusb_desc:
|
||||||
|
┌─────────────────────────────────┐
|
||||||
|
│ USB Device Descriptor Summary │
|
||||||
|
├───────────────────┬─────────────┤
|
||||||
|
│bDeviceClass │ 0 │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│bDeviceSubClass │ 0 │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│bDeviceProtocol │ 0 │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│bMaxPacketSize0 │ 64 │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│idVendor │ 0x303a │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│idProduct │ 0x4004 │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│bcdDevice │ 0x100 │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│iManufacturer │ 0x1 │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│iProduct │ 0x2 │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│iSerialNumber │ 0x3 │
|
||||||
|
├───────────────────┼─────────────┤
|
||||||
|
│bNumConfigurations │ 0x1 │
|
||||||
|
└───────────────────┴─────────────┘
|
||||||
|
I (480) TinyUSB: TinyUSB Driver installed
|
||||||
|
I (480) example: USB initialization DONE
|
||||||
|
I (2490) example: Sending Keyboard report
|
||||||
|
I (3040) example: Sending Mouse report
|
||||||
|
```
|
@ -0,0 +1,5 @@
|
|||||||
|
idf_component_register(
|
||||||
|
SRCS "tusb_hid_example_main.c"
|
||||||
|
INCLUDE_DIRS "."
|
||||||
|
REQUIRES driver tinyusb
|
||||||
|
)
|
@ -0,0 +1,175 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Unlicense OR CC0-1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#include "tinyusb.h"
|
||||||
|
#include "class/hid/hid_device.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
|
||||||
|
#define APP_BUTTON (GPIO_NUM_0) // Use BOOT signal by default
|
||||||
|
static const char *TAG = "example";
|
||||||
|
|
||||||
|
/************* TinyUSB descriptors ****************/
|
||||||
|
|
||||||
|
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_HID * TUD_HID_DESC_LEN)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief HID report descriptor
|
||||||
|
*
|
||||||
|
* In this example we implement Keyboard + Mouse HID device,
|
||||||
|
* so we must define both report descriptors
|
||||||
|
*/
|
||||||
|
const uint8_t hid_report_descriptor[] = {
|
||||||
|
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(HID_ITF_PROTOCOL_KEYBOARD) ),
|
||||||
|
TUD_HID_REPORT_DESC_MOUSE(HID_REPORT_ID(HID_ITF_PROTOCOL_MOUSE) )
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Configuration descriptor
|
||||||
|
*
|
||||||
|
* This is a simple configuration descriptor that defines 1 configuration and 1 HID interface
|
||||||
|
*/
|
||||||
|
static const uint8_t hid_configuration_descriptor[] = {
|
||||||
|
// Configuration number, interface count, string index, total length, attribute, power in mA
|
||||||
|
TUD_CONFIG_DESCRIPTOR(1, 1, 0, TUSB_DESC_TOTAL_LEN, TUSB_DESC_CONFIG_ATT_REMOTE_WAKEUP, 100),
|
||||||
|
|
||||||
|
// Interface number, string index, boot protocol, report descriptor len, EP In address, size & polling interval
|
||||||
|
TUD_HID_DESCRIPTOR(0, 0, false, sizeof(hid_report_descriptor), 0x81, 16, 10),
|
||||||
|
};
|
||||||
|
|
||||||
|
/********* TinyUSB HID callbacks ***************/
|
||||||
|
|
||||||
|
// Invoked when received GET HID REPORT DESCRIPTOR request
|
||||||
|
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
|
||||||
|
uint8_t const *tud_hid_descriptor_report_cb(uint8_t instance)
|
||||||
|
{
|
||||||
|
// We use only one interface and one HID report descriptor, so we can ignore parameter 'instance'
|
||||||
|
return hid_report_descriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received GET_REPORT control request
|
||||||
|
// Application must fill buffer report's content and return its length.
|
||||||
|
// Return zero will cause the stack to STALL request
|
||||||
|
uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen)
|
||||||
|
{
|
||||||
|
(void) instance;
|
||||||
|
(void) report_id;
|
||||||
|
(void) report_type;
|
||||||
|
(void) buffer;
|
||||||
|
(void) reqlen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Invoked when received SET_REPORT control request or
|
||||||
|
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
|
||||||
|
void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/********* Application ***************/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MOUSE_DIR_RIGHT,
|
||||||
|
MOUSE_DIR_DOWN,
|
||||||
|
MOUSE_DIR_LEFT,
|
||||||
|
MOUSE_DIR_UP,
|
||||||
|
MOUSE_DIR_MAX,
|
||||||
|
} mouse_dir_t;
|
||||||
|
|
||||||
|
#define DISTANCE_MAX 125
|
||||||
|
#define DELTA_SCALAR 5
|
||||||
|
|
||||||
|
static void mouse_draw_square_next_delta(int8_t *delta_x_ret, int8_t *delta_y_ret)
|
||||||
|
{
|
||||||
|
static mouse_dir_t cur_dir = MOUSE_DIR_RIGHT;
|
||||||
|
static uint32_t distance = 0;
|
||||||
|
|
||||||
|
// Calculate next delta
|
||||||
|
if (cur_dir == MOUSE_DIR_RIGHT) {
|
||||||
|
*delta_x_ret = DELTA_SCALAR;
|
||||||
|
*delta_y_ret = 0;
|
||||||
|
} else if (cur_dir == MOUSE_DIR_DOWN) {
|
||||||
|
*delta_x_ret = 0;
|
||||||
|
*delta_y_ret = DELTA_SCALAR;
|
||||||
|
} else if (cur_dir == MOUSE_DIR_LEFT) {
|
||||||
|
*delta_x_ret = -DELTA_SCALAR;
|
||||||
|
*delta_y_ret = 0;
|
||||||
|
} else if (cur_dir == MOUSE_DIR_UP) {
|
||||||
|
*delta_x_ret = 0;
|
||||||
|
*delta_y_ret = -DELTA_SCALAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update cumulative distance for current direction
|
||||||
|
distance += DELTA_SCALAR;
|
||||||
|
// Check if we need to change direction
|
||||||
|
if (distance >= DISTANCE_MAX) {
|
||||||
|
distance = 0;
|
||||||
|
cur_dir++;
|
||||||
|
if (cur_dir == MOUSE_DIR_MAX) {
|
||||||
|
cur_dir = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void app_send_hid_demo(void)
|
||||||
|
{
|
||||||
|
// Keyboard output: Send key 'a/A' pressed and released
|
||||||
|
ESP_LOGI(TAG, "Sending Keyboard report");
|
||||||
|
uint8_t keycode[6] = {HID_KEY_A};
|
||||||
|
tud_hid_keyboard_report(HID_ITF_PROTOCOL_KEYBOARD, 0, keycode);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(50));
|
||||||
|
tud_hid_keyboard_report(HID_ITF_PROTOCOL_KEYBOARD, 0, NULL);
|
||||||
|
|
||||||
|
// Mouse output: Move mouse cursor in square trajectory
|
||||||
|
ESP_LOGI(TAG, "Sending Mouse report");
|
||||||
|
int8_t delta_x;
|
||||||
|
int8_t delta_y;
|
||||||
|
for (int i = 0; i < (DISTANCE_MAX / DELTA_SCALAR) * 4; i++) {
|
||||||
|
// Get the next x and y delta in the draw square pattern
|
||||||
|
mouse_draw_square_next_delta(&delta_x, &delta_y);
|
||||||
|
tud_hid_mouse_report(HID_ITF_PROTOCOL_MOUSE, 0x00, delta_x, delta_y, 0, 0);
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(20));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void app_main(void)
|
||||||
|
{
|
||||||
|
// Initialize button that will trigger HID reports
|
||||||
|
const gpio_config_t boot_button_config = {
|
||||||
|
.pin_bit_mask = BIT64(APP_BUTTON),
|
||||||
|
.mode = GPIO_MODE_INPUT,
|
||||||
|
.intr_type = GPIO_INTR_DISABLE,
|
||||||
|
.pull_up_en = true,
|
||||||
|
.pull_down_en = false,
|
||||||
|
};
|
||||||
|
ESP_ERROR_CHECK(gpio_config(&boot_button_config));
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "USB initialization");
|
||||||
|
const tinyusb_config_t tusb_cfg = {
|
||||||
|
.device_descriptor = NULL,
|
||||||
|
.string_descriptor = NULL,
|
||||||
|
.external_phy = false,
|
||||||
|
.configuration_descriptor = hid_configuration_descriptor,
|
||||||
|
};
|
||||||
|
|
||||||
|
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
||||||
|
ESP_LOGI(TAG, "USB initialization DONE");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
if (tud_mounted()) {
|
||||||
|
static bool send_hid_data = true;
|
||||||
|
if (send_hid_data) {
|
||||||
|
app_send_hid_demo();
|
||||||
|
}
|
||||||
|
send_hid_data = !gpio_get_level(APP_BUTTON);
|
||||||
|
}
|
||||||
|
vTaskDelay(pdMS_TO_TICKS(100));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||||
|
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||||
|
#
|
||||||
|
CONFIG_TINYUSB=y
|
||||||
|
CONFIG_TINYUSB_HID_COUNT=1
|
@ -80,7 +80,8 @@ void app_main(void)
|
|||||||
tinyusb_config_t const tusb_cfg = {
|
tinyusb_config_t const tusb_cfg = {
|
||||||
.device_descriptor = NULL, // If device_descriptor is NULL, tinyusb_driver_install() will use Kconfig
|
.device_descriptor = NULL, // If device_descriptor is NULL, tinyusb_driver_install() will use Kconfig
|
||||||
.string_descriptor = NULL,
|
.string_descriptor = NULL,
|
||||||
.external_phy = false // In the most cases you need to use a `false` value
|
.external_phy = false,
|
||||||
|
.configuration_descriptor = NULL,
|
||||||
};
|
};
|
||||||
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
||||||
|
|
||||||
|
@ -47,18 +47,20 @@ void app_main(void)
|
|||||||
"012-345", // 3: Serials, should use chip ID
|
"012-345", // 3: Serials, should use chip ID
|
||||||
};
|
};
|
||||||
|
|
||||||
tinyusb_config_t tusb_cfg = {
|
const tinyusb_config_t tusb_cfg = {
|
||||||
.descriptor = &my_descriptor,
|
.descriptor = &my_descriptor,
|
||||||
.string_descriptor = my_string_descriptor,
|
.string_descriptor = my_string_descriptor,
|
||||||
.external_phy = false // In the most cases you need to use a `false` value
|
.external_phy = false,
|
||||||
|
.configuration_descriptor = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
tinyusb_config_t tusb_cfg = {
|
const tinyusb_config_t tusb_cfg = {
|
||||||
.descriptor = NULL,
|
.device_descriptor = NULL,
|
||||||
.string_descriptor = NULL,
|
.string_descriptor = NULL,
|
||||||
.external_phy = false // In the most cases you need to use a `false` value
|
.external_phy = false,
|
||||||
|
.configuration_descriptor = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -44,7 +44,13 @@ void tinyusb_cdc_line_state_changed_callback(int itf, cdcacm_event_t *event)
|
|||||||
void app_main(void)
|
void app_main(void)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "USB initialization");
|
ESP_LOGI(TAG, "USB initialization");
|
||||||
const tinyusb_config_t tusb_cfg = {}; // the configuration using default values
|
const tinyusb_config_t tusb_cfg = {
|
||||||
|
.device_descriptor = NULL,
|
||||||
|
.string_descriptor = NULL,
|
||||||
|
.external_phy = false,
|
||||||
|
.configuration_descriptor = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
ESP_ERROR_CHECK(tinyusb_driver_install(&tusb_cfg));
|
||||||
|
|
||||||
tinyusb_config_cdcacm_t acm_cfg = {
|
tinyusb_config_cdcacm_t acm_cfg = {
|
||||||
|
Loading…
Reference in New Issue
Block a user