Last active
May 11, 2025 16:25
-
-
Save haideralipunjabi/69f848591a4d8b86ebbde04a0be8c8c9 to your computer and use it in GitHub Desktop.
Attempt at using ESP32 S2 Mini to control HDMI USB Switch
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* SPDX-FileCopyrightText: 2022-2024 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)), | |
}; | |
const char *hid_string_descriptor[5] = { | |
(char[]){0x09, 0x04}, | |
"Logitech", // Manufacturer | |
"Composite Device", // Product | |
"LOGI123456", // Serial | |
"Keyboard Interface", // HID interface | |
}; | |
const tusb_desc_device_t custom_device_descriptor = { | |
.bLength = sizeof(tusb_desc_device_t), | |
.bDescriptorType = TUSB_DESC_DEVICE, | |
.bcdUSB = 0x0100, // USB 2.0 | |
.bDeviceClass = 0x00, | |
.bDeviceSubClass = 0x00, | |
.bDeviceProtocol = 0x00, | |
.bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, | |
.idVendor = 0x0513, // Example: Logitech | |
.idProduct = 0x0318, // Example: Known keyboard PID | |
.bcdDevice = 0x0100, | |
.iManufacturer = 0x01, | |
.iProduct = 0x02, | |
.iSerialNumber = 0x03, | |
.bNumConfigurations = 0x01}; | |
/** | |
* @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, 4, true, sizeof(hid_report_descriptor), 0x81, 8, 1), | |
}; | |
/********* 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 ***************/ | |
void send_key(uint8_t keycode) | |
{ | |
uint8_t keycodes[6] = {0}; | |
keycodes[0] = keycode; | |
ESP_LOGI(TAG, "Sending Keyboard report"); | |
tud_hid_keyboard_report(HID_ITF_PROTOCOL_KEYBOARD, 0, keycodes); | |
vTaskDelay(pdMS_TO_TICKS(50)); | |
tud_hid_keyboard_report(HID_ITF_PROTOCOL_KEYBOARD, 0, NULL); | |
vTaskDelay(pdMS_TO_TICKS(500)); | |
} | |
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 = &custom_device_descriptor, | |
.string_descriptor = hid_string_descriptor, | |
.string_descriptor_count = sizeof(hid_string_descriptor) / sizeof(hid_string_descriptor[0]), | |
.external_phy = false, | |
#if (TUD_OPT_HIGH_SPEED) | |
.fs_configuration_descriptor = hid_configuration_descriptor, // HID configuration descriptor for full-speed and high-speed are the same | |
.hs_configuration_descriptor = hid_configuration_descriptor, | |
.qualifier_descriptor = NULL, | |
#else | |
.configuration_descriptor = hid_configuration_descriptor, | |
#endif // TUD_OPT_HIGH_SPEED | |
}; | |
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) | |
{ | |
send_key(HID_KEY_CONTROL_LEFT); | |
send_key(HID_KEY_CONTROL_LEFT); | |
send_key(HID_KEY_2); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment