Initial working USB communication

This commit is contained in:
Jack O'Sullivan 2024-12-11 18:59:17 +00:00
parent a35f1cccc1
commit 4817c80df3
6 changed files with 64 additions and 23 deletions

View File

@ -6,7 +6,7 @@
enable = true;
version = "3.13";
libraries = with pkgs; [
libusb1
zlib # required by hidapi (?)
];
uv = {
enable = true;

View File

@ -4,5 +4,5 @@ version = "0.1.0"
description = "Valconomy controller"
requires-python = ">=3.13"
dependencies = [
"pyusb>=1.2.1",
"hidapi>=0.14.0.post4",
]

33
controller/uv.lock generated
View File

@ -2,12 +2,33 @@ version = 1
requires-python = ">=3.13"
[[package]]
name = "pyusb"
version = "1.2.1"
name = "hidapi"
version = "0.14.0.post4"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/d9/6e/433a5614132576289b8643fe598dd5d51b16e130fd591564be952e15bb45/pyusb-1.2.1.tar.gz", hash = "sha256:a4cc7404a203144754164b8b40994e2849fde1cfff06b08492f12fff9d9de7b9", size = 75292 }
dependencies = [
{ name = "setuptools" },
]
sdist = { url = "https://files.pythonhosted.org/packages/47/72/21ccaaca6ffb06f544afd16191425025d831c2a6d318635e9c8854070f2d/hidapi-0.14.0.post4.tar.gz", hash = "sha256:48fce253e526d17b663fbf9989c71c7ef7653ced5f4be65f1437c313fb3dbdf6", size = 174388 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/15/a8/4982498b2ab44d1fcd5c49f07ea3795eab01601dc143b009d333fcace3b9/pyusb-1.2.1-py3-none-any.whl", hash = "sha256:2b4c7cb86dbadf044dfb9d3a4ff69fd217013dbe78a792177a3feb172449ea36", size = 58439 },
{ url = "https://files.pythonhosted.org/packages/38/c7/8601f03a6eeeac35655245177b50bb00e707f3392e0a79c34637f8525207/hidapi-0.14.0.post4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:6f96ae777e906f0a9d6f75e873313145dfec2b774f558bfcae8ba34f09792460", size = 70358 },
{ url = "https://files.pythonhosted.org/packages/c1/5d/7376cf339fbe6fca26048e3c7e183ef4d99c046cc5d8378516a745914327/hidapi-0.14.0.post4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6439fc9686518d0336fac8c5e370093279f53c997540065fce131c97567118d8", size = 68034 },
{ url = "https://files.pythonhosted.org/packages/8c/5a/4bca20898c699810f016d2719b980fc57fe36d5012d03eca7a89ace98547/hidapi-0.14.0.post4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2acadb4f1ae569c4f73ddb461af8733e8f5efcb290c3d0ef1b0671ba793b0ae3", size = 1075570 },
{ url = "https://files.pythonhosted.org/packages/6a/c6/66e6b7c27297249bc737115dff4a1e819d3e0e73885160a3104ebec7ac13/hidapi-0.14.0.post4-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:884fa003d899113e14908bd3b519c60b48fc3cec0410264dcbdad1c4a8fc2e8d", size = 1081482 },
{ url = "https://files.pythonhosted.org/packages/86/a8/21e9860eddeefd0dc41b3f7e6e81cd9ff53c2b07130f57776b56a1dddc66/hidapi-0.14.0.post4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a2d466b995f8ff387d68c052d3b74ee981a4ddc4f1a99f32f2dc7022273dc11", size = 1069549 },
{ url = "https://files.pythonhosted.org/packages/e8/01/3adf46a7ea5bf31f12e09d4392e1810e662101ba6611214ea6e2c35bea7a/hidapi-0.14.0.post4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e1f6409854c0a8ed4d1fdbe88d5ee4baf6f19996d1561f76889a132cb083574d", size = 698200 },
{ url = "https://files.pythonhosted.org/packages/f0/19/db15cd21bef1b0dc8ef4309c5734b64affb7e88540efd3c090f153cdae0b/hidapi-0.14.0.post4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bca568a2b7d0d454c7921d70b1cc44f427eb6f95961b6d7b3b9b4532d0de74ef", size = 671554 },
{ url = "https://files.pythonhosted.org/packages/f5/23/f896ee8f0977710c354bd1b9ac6d5206c12842bd39d78a357c866f8ec6b6/hidapi-0.14.0.post4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9f14ac2737fd6f58d88d2e6bf8ebd03aac7b486c14d3f570b7b1d0013d61b726", size = 703897 },
{ url = "https://files.pythonhosted.org/packages/9a/5e/3c93bb12b01392b538870bc710786fee86a9ced074a8b5c091a59786ee07/hidapi-0.14.0.post4-cp313-cp313-win32.whl", hash = "sha256:b6b9c4dbf7d7e2635ff129ce6ea82174865c073b75888b8b97dda5a3d9a70493", size = 62688 },
{ url = "https://files.pythonhosted.org/packages/6a/a6/0d43ac0be00db25fb0c2c6125e15a3e3536196c9a7cd806d50ebfb37b375/hidapi-0.14.0.post4-cp313-cp313-win_amd64.whl", hash = "sha256:87218eeba366c871adcc273407aacbabab781d6a964919712d5583eded5ca50f", size = 69749 },
]
[[package]]
name = "setuptools"
version = "75.6.0"
source = { registry = "https://pypi.org/simple" }
sdist = { url = "https://files.pythonhosted.org/packages/43/54/292f26c208734e9a7f067aea4a7e282c080750c4546559b58e2e45413ca0/setuptools-75.6.0.tar.gz", hash = "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6", size = 1337429 }
wheels = [
{ url = "https://files.pythonhosted.org/packages/55/21/47d163f615df1d30c094f6c8bbb353619274edccf0327b185cc2493c2c33/setuptools-75.6.0-py3-none-any.whl", hash = "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d", size = 1224032 },
]
[[package]]
@ -15,8 +36,8 @@ name = "valconomy"
version = "0.1.0"
source = { virtual = "." }
dependencies = [
{ name = "pyusb" },
{ name = "hidapi" },
]
[package.metadata]
requires-dist = [{ name = "pyusb", specifier = ">=1.2.1" }]
requires-dist = [{ name = "hidapi", specifier = ">=0.14.0.post4" }]

View File

@ -1,8 +1,17 @@
#!/usr/bin/env python3
import usb.core
import hid
USB_VID = 0x6969
USB_PID = 0x0004
def main():
print(usb.core.find(idVendor=0x6969, idProduct=0x0004))
hid_handle = hid.device()
hid_handle.open(vendor_id=USB_VID, product_id=USB_PID)
try:
hid_handle.write(b'\x00test')
finally:
hid_handle.close()
if __name__ == '__main__':
main()

View File

@ -9,7 +9,7 @@
#include "common.h"
#include "usb.h"
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + CFG_TUD_HID * TUD_HID_DESC_LEN)
#define TUSB_DESC_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_HID_INOUT_DESC_LEN)
static const char *TAG = "valconomy-usb";
@ -38,13 +38,9 @@ const tusb_desc_device_t val_usb_dev_descriptor = {
.bNumConfigurations = 0x01,
};
const uint8_t val_hid_report_descriptor[] = {
TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(HID_ITF_PROTOCOL_KEYBOARD)),
};
char val_dev_serial[13];
const char* val_hid_string_descriptor[5] = {
// 0: is supported language is English (0x0409)
const char* val_usb_string_descriptor[5] = {
// 0: supported language is English (0x0409)
(char[]){0x09, 0x04},
// 1: Manufacturer
"/dev/player0",
@ -56,12 +52,18 @@ const char* val_hid_string_descriptor[5] = {
"Valconomy HID interface",
};
static const uint8_t val_hid_conf_descriptor[] = {
const uint8_t val_hid_report_descriptor[] = {
TUD_HID_REPORT_DESC_GENERIC_INOUT(USB_EP_BUFSIZE),
};
const uint8_t val_hid_conf_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, false, sizeof(val_hid_report_descriptor), 0x81, 16, 10),
// HID requires an IN endpoint even if we don't care about it
// Interface number, string index, protocol, report descriptor len, EP Out & In address, size & polling interval (ms)
// 0x80 in endpoint address indicates IN
TUD_HID_INOUT_DESCRIPTOR(0, 4, HID_ITF_PROTOCOL_NONE, sizeof(val_hid_report_descriptor), EPNUM_HID, 0x80 | EPNUM_HID, USB_EP_BUFSIZE, 100)
};
// TinyUSB callbacks
@ -88,7 +90,13 @@ uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_t
// 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) {}
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) {
assert(report_id == 0 && report_type == HID_REPORT_TYPE_OUTPUT);
ESP_LOGI(TAG, "Got %hu bytes report %hhu", bufsize, report_id);
for (uint16_t i = 0; i < bufsize; i++) {
ESP_LOGI(TAG, "b: %02hhx", buffer[i]);
}
}
void val_usb_init(void) {
ESP_LOGI(TAG, "Initializing USB");
@ -102,8 +110,8 @@ void val_usb_init(void) {
const tinyusb_config_t cfg = {
.device_descriptor = &val_usb_dev_descriptor,
.string_descriptor = val_hid_string_descriptor,
.string_descriptor_count = sizeof(val_hid_string_descriptor) / sizeof(char *),
.string_descriptor = val_usb_string_descriptor,
.string_descriptor_count = sizeof(val_usb_string_descriptor) / sizeof(char *),
.external_phy = false,
#if (TUD_OPT_HIGH_SPEED)

View File

@ -2,4 +2,7 @@
#include "tinyusb_types.h"
#define EPNUM_HID 0x01
#define USB_EP_BUFSIZE 64
void val_usb_init(void);