USB host support (#527)

This commit is contained in:
Shadowtrance
2026-06-04 07:10:37 +10:00
committed by GitHub
parent a59fbf4ed5
commit 3dcc95f6f3
46 changed files with 2409 additions and 121 deletions
@@ -273,6 +273,14 @@ bool device_exists_of_type(const struct DeviceType* type);
*/
struct Device* device_find_by_name(const char* name);
/**
* Find the first started device of the given type.
*
* @param[in] type non-null device type pointer
* @return the first started device of the given type, or NULL if none found
*/
struct Device* device_find_first_active_by_type(const struct DeviceType* type);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,72 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct Device;
struct DeviceType;
typedef void* UsbHidQueueHandle;
/** Key values — numerically identical to lv_key_t so no translation is needed. */
typedef enum {
USB_HID_KEY_UP = 17,
USB_HID_KEY_DOWN = 18,
USB_HID_KEY_RIGHT = 19,
USB_HID_KEY_LEFT = 20,
USB_HID_KEY_ESC = 27,
USB_HID_KEY_DEL = 127,
USB_HID_KEY_BACKSPACE = 8,
USB_HID_KEY_ENTER = 10,
USB_HID_KEY_NEXT = 9,
USB_HID_KEY_PREV = 11,
USB_HID_KEY_HOME = 2,
USB_HID_KEY_END = 3,
} UsbHidKey;
typedef enum {
USB_HID_EVENT_KEY,
USB_HID_EVENT_MOUSE_MOVE,
USB_HID_EVENT_MOUSE_BTN,
USB_HID_EVENT_SCROLL,
USB_HID_EVENT_KEYBOARD_CONNECTED,
USB_HID_EVENT_KEYBOARD_DISCONNECTED,
USB_HID_EVENT_MOUSE_CONNECTED,
USB_HID_EVENT_MOUSE_DISCONNECTED,
} UsbHidEventType;
typedef struct {
UsbHidEventType type;
union {
struct { uint32_t key_code; bool pressed; } key;
struct { int32_t dx; int32_t dy; } mouse_move;
struct { bool button1; bool button2; } mouse_btn;
struct { int32_t delta; } scroll;
};
} UsbHidEvent;
struct UsbHidApi {
bool (*is_connected)(struct Device* device);
bool (*subscribe)(struct Device* device, UsbHidQueueHandle event_queue);
void (*unsubscribe)(struct Device* device, UsbHidQueueHandle event_queue);
};
extern const struct DeviceType USB_HOST_HID_TYPE;
/** Returns true if any HID device (keyboard or mouse) is currently connected. */
bool usb_host_hid_is_connected(struct Device* device);
/** Subscribe a FreeRTOS queue to receive UsbHidEvent items from the HID driver. */
bool usb_host_hid_subscribe(struct Device* device, UsbHidQueueHandle event_queue);
/** Unsubscribe a previously subscribed queue. */
void usb_host_hid_unsubscribe(struct Device* device, UsbHidQueueHandle event_queue);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,53 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <stdbool.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct Device;
struct DeviceType;
/**
* Decoded USB MIDI message.
*
* `status` encodes both message type and channel:
* type = status & 0xF0 (0x80=NoteOff, 0x90=NoteOn, 0xB0=CC, 0xC0=PC, 0xE0=PitchBend, ...)
* channel = status & 0x0F (015)
*/
typedef struct {
uint8_t cable; /**< USB cable number (015, almost always 0) */
uint8_t status; /**< MIDI status byte */
uint8_t data1; /**< First data byte */
uint8_t data2; /**< Second data byte */
} usb_midi_message_t;
typedef void (*usb_midi_message_cb_t)(const usb_midi_message_t* msg, void* user_data);
struct UsbMidiApi {
void (*set_callback)(struct Device* device, usb_midi_message_cb_t callback, void* user_data);
bool (*is_connected)(struct Device* device);
};
extern const struct DeviceType USB_HOST_MIDI_TYPE;
/**
* Register a callback for incoming MIDI messages.
* Replaces any previously registered callback. Pass NULL to disable.
* @param device non-null ready USB MIDI device.
*/
// TODO: Make an interface that takes/releases control
void usb_midi_set_callback(struct Device* device, usb_midi_message_cb_t callback, void* user_data);
/**
* Returns true if a MIDI device is currently connected and streaming.
* @param device non-null ready USB MIDI device.
*/
bool usb_midi_is_connected(struct Device* device);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,31 @@
// SPDX-License-Identifier: Apache-2.0
#pragma once
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
struct Device;
struct DeviceType;
#define USB_MSC_MOUNT_PATH_PREFIX "/usb"
struct UsbMscApi {
bool (*eject)(struct Device* device, const char* mount_path);
};
extern const struct DeviceType USB_HOST_MSC_TYPE;
/**
* Safely eject a mounted USB drive.
* @param device non-null ready USB MSC device (from device_find_first_active_by_type).
* @param mount_path Full mount path (e.g. "/usb0").
* @return true if the drive was found and ejected.
*/
bool usb_msc_eject(struct Device* device, const char* mount_path);
#ifdef __cplusplus
}
#endif