add toggle button for USB and improve BLE polling rate

This commit is contained in:
2025-10-18 22:38:23 -04:00
parent a1a0723e89
commit cb7421eab7
14 changed files with 323 additions and 121 deletions
+8
View File
@@ -14,6 +14,7 @@ over BLE using HID over GATT Profile.
You will need the following hardware to make the device:
- Raspberry Pi Pico W
- USB extension cable
- (Optional) Momentary push button
![Wiring schematic](schematic.svg)
@@ -35,6 +36,8 @@ and the green cable to TP3.
![Wiring of USB connectors to Raspberry Pi Pico W](diagram.png)
Optionally, a momentary push button can be wired to GP5 and GND to switch between Bluetooth and USB passthrough mode.
The individual wires on the USB can be fragile, so hot glue or other strain
relief is a good idea.
@@ -64,6 +67,11 @@ with many LEDs, the sudden power draw when plugging in can cause issues, so it
is recommended to turn off the LEDs before connecting to the Raspberry Pi Pico
W.
If you connected a push button to GP5, then pressing the button will switch
between Bluetooth connection mode and USB passthrough mode. In USB passthrough
mode, the inputs will be passed through from the host to the USB connection made
through the test points or the Micro USB port.
In principle, the Pico BLE HID will work with peripherals plugged into
a USB hub, but compatibility will vary with the specific hardware used,
including the peripherals, USB hub, and operating system. This is because the
+8
View File
@@ -0,0 +1,8 @@
#ifndef BLEHID_CONFIG_H_
#define BLEHID_CONFIG_H_
#define BUTTON_PIN 5
#define BUTTON_DEBOUNCE 20000
#define BUTTON_LONG_PRESS 3000000
#endif
+21 -10
View File
@@ -28,6 +28,8 @@ static uint8_t battery = 100;
hci_con_handle_t con_handle = HCI_CON_HANDLE_INVALID;
uint16_t conn_interval=1000;
static uint8_t protocol_mode = 1;
bt_state_t bt_state;
bt_device_command_t bt_device_command;
static hids_device_report_t *dev_report_storage;
@@ -109,14 +111,20 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
(void) size;
if (packet_type != HCI_EVENT_PACKET) return;
if (packet_type != HCI_EVENT_PACKET) {
cdc_count = sprintf(cdc_buf, "Unexpected packet type %02X\n", packet_type);
cdc_print_str(cdc_buf, cdc_count);
return;
}
switch (hci_event_packet_get_type(packet)) {
case HCI_EVENT_DISCONNECTION_COMPLETE:
con_handle = HCI_CON_HANDLE_INVALID;
cdc_print_msg("Disconnected\n");
if ( device_state == DEVICE_INACTIVE) {
host_state = HOST_STOP_LISTEN;
}
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
break;
case SM_EVENT_JUST_WORKS_REQUEST:
@@ -133,6 +141,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
cdc_count = sprintf(cdc_buf, "Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet));
cdc_print_str(cdc_buf, cdc_count);
break;
case SM_EVENT_IDENTITY_RESOLVING_STARTED:
break;
case L2CAP_EVENT_CONNECTION_PARAMETER_UPDATE_RESPONSE:
cdc_count = sprintf(cdc_buf, "L2CAP Connection Parameter Update Complete, response: %x\n", l2cap_event_connection_parameter_update_response_get_result(packet));
cdc_print_str(cdc_buf, cdc_count);
@@ -160,6 +170,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
cdc_print_str(cdc_buf, cdc_count);
break;
default:
//cdc_count = sprintf(cdc_buf,"LE packet unknown %02X\n", hci_event_le_meta_get_subevent_code(packet));
//cdc_print_str(cdc_buf, cdc_count);
break;
}
break;
@@ -172,11 +184,8 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
host_state = HOST_START_LISTEN;
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
// request connection param update via L2CAP following Apple Bluetooth Design Guidelines
// gap_request_connection_parameter_update(con_handle, 12, 12, 4, 100); // 15 ms, 4, 1s
// directly update connection params via HCI following Apple Bluetooth Design Guidelines
// gap_update_connection_parameters(con_handle, 12, 12, 4, 100); // 60-75 ms, 4, 1s
// request update to max 125Hz polling
gap_request_connection_parameter_update(con_handle, 6,6,0,100);
break;
case HIDS_SUBEVENT_PROTOCOL_MODE:
@@ -185,27 +194,29 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
cdc_print_str(cdc_buf, cdc_count);
break;
case HIDS_SUBEVENT_CAN_SEND_NOW:
//cdc_print_msg("HIDS_SUBEVENT_CAN_SEND_NOW\n");
send_report();
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1-cyw43_arch_gpio_get(CYW43_WL_GPIO_LED_PIN));
break;
default:
//cdc_count = sprintf(cdc_buf, "Unknown HID event %02X\n", hci_event_hids_meta_get_subevent_code(packet));
//cdc_print_str(cdc_buf, cdc_count);
break;
}
break;
default:
//cdc_count = sprintf(cdc_buf, "Unknown HCI event %02X\n", hci_event_packet_get_type(packet));
//cdc_print_str(cdc_buf, cdc_count);
break;
}
}
// called to update the report map aka HID report descriptor on the BT interface
void update_desc_hid_report(void) {
con_handle = HCI_CON_HANDLE_INVALID;
hci_power_control(HCI_POWER_OFF);
if (desc_hid_report_len>0) {
//cdc_print_msg("Update HID report descriptor: ");
//cdc_print_hex(desc_hid_report, desc_hid_report_len);
if (bt_state == BT_STATE_ACTIVE && desc_hid_report_len>0) {
hids_device_init_with_storage(0, desc_hid_report, desc_hid_report_len, NUM_REPORT_IDS, dev_report_storage);
hci_power_control(HCI_POWER_ON);
}
+18
View File
@@ -1,6 +1,24 @@
#ifndef BT_DEVICE_H_
#define BT_DEVICE_H_
#define BT_LOOP_POLL_INTERVAL 100
typedef enum {
BT_STATE_INACTIVE=0,
BT_STATE_STOP,
BT_STATE_START,
BT_STATE_ACTIVE
} bt_state_t;
typedef enum {
BT_DEVICE_COMMAND_NONE=0,
BT_DEVICE_COMMAND_SWITCH,
BT_DEVICE_COMMAND_UNPAIR,
BT_DEVICE_COMMAND_UPDATE,
} bt_device_command_t;
extern bt_state_t bt_state;
extern bt_device_command_t bt_device_command;
extern uint16_t conn_interval;
void btstack_main(void);
+57 -13
View File
@@ -19,6 +19,7 @@ extern hci_con_handle_t con_handle;
uint8_t desc_hid_report[HID_DESCRIPTOR_SIZE];
uint16_t desc_hid_report_len=0;
uint8_t num_mounted=0;
static uint8_t buffer_storage[REPORT_BUF_SIZE];
static btstack_ring_buffer_t report_buf;
@@ -74,7 +75,11 @@ bool stop_hid_reports_all(void) {
}
}
if (num_mounted > 0) {
host_state = HOST_MOUNTED;
} else {
host_state = HOST_INACTIVE;
}
return true;
}
@@ -98,6 +103,8 @@ void send_report(){
// retrieve report from ring buffer
btstack_ring_buffer_read(&report_buf, report->report, report->len, &num_bytes_read);
// send over BLE if connected
if (con_handle != HCI_CON_HANDLE_INVALID) {
// find report id mapping
struct report_dict * mapping = find_mapping(report->dev_addr, report->instance, report->report[0]);
@@ -115,21 +122,32 @@ void send_report(){
cdc_print_hex(&report->report[1], report->len-1);
}
}
// request sending of next report
if (btstack_ring_buffer_bytes_available(&report_buf)) {
hids_device_request_can_send_now_event(con_handle);
}
}
// send over USB if enabled
if ( device_state == DEVICE_ACTIVE ) {
struct report_desc *descriptor = report_desc_find(report->dev_addr, report->instance);
cdc_count=sprintf(cdc_buf, "[%u]> ", descriptor->dev_instance);
cdc_print_str(cdc_buf, cdc_count);
forward_report(descriptor->dev_instance, report->report, report->len);
cdc_print_hex(report->report, report->len);
}
// set host to poll USB
if (host_state == HOST_WAIT_POLL) {
host_state = HOST_POLL;
}
// request sending of next report
if (btstack_ring_buffer_bytes_available(&report_buf)) {
hids_device_request_can_send_now_event(con_handle);
}
}
}
// add report to the BTstack ring buffer for sending
void queue_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len) {
if (con_handle != HCI_CON_HANDLE_INVALID) {
if (con_handle != HCI_CON_HANDLE_INVALID || device_state == DEVICE_ACTIVE ) {
// convert len to array of two uint8_t from single uint16_t
uint8_t len8[2];
memcpy(len8, &len, 2);
@@ -142,8 +160,13 @@ void queue_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uin
btstack_ring_buffer_write(&report_buf, report, len);
}
if (con_handle != HCI_CON_HANDLE_INVALID) {
// request send on BLE HID interface
hids_device_request_can_send_now_event(con_handle);
} else {
// BLE is not active, send over USB
send_report();
}
}
// HID report on device has not been requested, flag so it can be polled
@@ -215,6 +238,7 @@ bool add_descriptor(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_repo
descriptor->desc_len = desc_len;
descriptor->dev_addr = dev_addr;
descriptor->instance = instance;
descriptor->dev_instance = instance;
descriptor->listening = false;
return true;
@@ -226,7 +250,8 @@ bool generate_report_descriptor(void) {
memset(desc_hid_report, 0, sizeof(desc_hid_report));
desc_hid_report_len=0;
uint8_t num_mounted = 0;
uint8_t id_counter = 0;
uint8_t instance_counter = 0;
struct report_desc * current;
for (current=descriptors; current != NULL; current=current->next) {
@@ -251,11 +276,11 @@ bool generate_report_descriptor(void) {
if (report_map == NULL) {
return false;
}
num_mounted++;
id_counter++;
report_map->report_id = current->descriptor[i];
report_map->ble_id = num_mounted;
report_map->ble_id = id_counter;
desc_hid_report[desc_hid_report_len+i]=num_mounted;
desc_hid_report[desc_hid_report_len+i]=id_counter;
}
}
@@ -270,30 +295,49 @@ bool generate_report_descriptor(void) {
}
}
desc_hid_report[desc_hid_report_len+col_pos+2] = 0x85;
desc_hid_report[desc_hid_report_len+col_pos+3] = num_mounted+1;
desc_hid_report[desc_hid_report_len+col_pos+3] = id_counter+1;
memcpy(&desc_hid_report[desc_hid_report_len+col_pos+4], &current->descriptor[col_pos+2], current->desc_len-col_pos);
desc_hid_report_len += current->desc_len+2;
// store mapping with report ID of 0
struct report_dict * report_map = report_dict_alloc(current);
num_mounted++;
id_counter++;
report_map->report_id = 0;
report_map->ble_id = num_mounted;
report_map->ble_id = id_counter;
} else {
desc_hid_report_len += current->desc_len;
}
// store mapping for host instance to device instance
current->dev_instance = instance_counter;
instance_counter++;
}
if (num_mounted > NUM_REPORT_IDS) {
if (id_counter > NUM_REPORT_IDS) {
cdc_print_msg("Error: too many report IDs\n");
return false;
}
// update number of instances mounted
num_mounted = instance_counter;
btstack_ring_buffer_reset(&report_buf);
return true;
}
// find a return the report descriptor by dvice address and device instance
struct report_desc * get_report_desc(uint8_t dev_instance) {
struct report_desc *descriptor;
for (descriptor = descriptors; descriptor != NULL; descriptor = descriptor->next) {
if (descriptor->dev_instance==dev_instance) {
break;
}
}
return descriptor;
}
// remove report descriptor for HID interface
void remove_instance(uint8_t dev_addr, uint8_t instance) {
struct report_desc *descriptor = report_desc_find(dev_addr, instance);
+3
View File
@@ -12,6 +12,7 @@ struct report_desc {
uint8_t instance;
uint8_t descriptor[DESCRIPTOR_BUF_SIZE];
uint16_t desc_len;
uint8_t dev_instance;
struct report_desc *next;
struct report_dict *mappings;
bool listening;
@@ -36,6 +37,7 @@ struct report_data {
extern uint8_t desc_hid_report[HID_DESCRIPTOR_SIZE];
extern uint16_t desc_hid_report_len;
extern uint8_t num_mounted;
bool request_hid_reports_all(void);
bool stop_hid_reports_all(void);
@@ -45,5 +47,6 @@ void init_report_buf(void);
bool add_descriptor(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len);
void remove_instance(uint8_t dev_addr, uint8_t instance);
bool generate_report_descriptor(void);
struct report_desc * get_report_desc(uint8_t dev_instance);
#endif
+90
View File
@@ -2,6 +2,7 @@
#include "pico/multicore.h"
#include "pico/bootrom.h"
#include "hardware/clocks.h"
#include "hardware/gpio.h"
#include "pio_usb.h"
#include "tusb.h"
@@ -12,8 +13,16 @@
#include "usb_device.h"
#include "usb_host.h"
#include "blehid_config.h"
static void usb_main(void);
#ifdef BUTTON_PIN
static absolute_time_t last_button_time;
static uint32_t last_button_event;
static void gpio_callback(uint pin, uint32_t events);
#endif
// main loop
int main(void) {
// for PIO USB, we want clock speed to be multiple of 12MHz
@@ -35,12 +44,24 @@ int main(void) {
}
static void usb_main(void) {
// setup GPIO button for pair selection
#ifdef BUTTON_PIN
gpio_init(BUTTON_PIN);
gpio_pull_up(BUTTON_PIN);
gpio_set_irq_enabled_with_callback(BUTTON_PIN, GPIO_IRQ_EDGE_RISE | GPIO_IRQ_EDGE_FALL, true, &gpio_callback);
#endif
// init and run usb host
usb_host_init();
// init and run usb device
usb_device_init();
// set initial state
bt_state = BT_STATE_ACTIVE;
device_state = DEVICE_INACTIVE;
while (true) {
switch ( host_state ) {
case HOST_NEW_DESCRIPTOR:
@@ -58,8 +79,77 @@ static void usb_main(void) {
default:
break;
}
switch ( device_state ) {
case DEVICE_STOP:
case DEVICE_START:
if ( tud_disconnect() ) {
sleep_ms(10);
tud_connect();
}
if ( device_state == DEVICE_STOP ) {
device_state = DEVICE_INACTIVE;
host_state = HOST_STOP_LISTEN;
} else if (device_state == DEVICE_START ) {
device_state = DEVICE_ACTIVE;
if ( num_mounted > 0 ) {
set_host_poll_interval(1);
host_state = HOST_START_LISTEN;
}
}
break;
default:
break;
}
switch ( bt_state ) {
case BT_STATE_STOP:
bt_state = BT_STATE_INACTIVE;
update_desc_hid_report();
break;
case BT_STATE_START:
bt_state = BT_STATE_ACTIVE;
update_desc_hid_report();
break;
default:
break;
}
tuh_task(); // tinyusb host task
tud_task(); // tinyusb device task
tud_cdc_write_flush();
}
}
#ifdef BUTTON_PIN
static void gpio_callback(uint pin, uint32_t events) {
uint64_t diff = absolute_time_diff_us(last_button_time, get_absolute_time());
if (pin == BUTTON_PIN && diff >= BUTTON_DEBOUNCE) {
if (events & GPIO_IRQ_EDGE_FALL) {
// button pressed
last_button_time = get_absolute_time();
} else if (events & GPIO_IRQ_EDGE_RISE) {
// button released
if (diff >= BUTTON_LONG_PRESS) {
//bt_device_command = BT_DEVICE_COMMAND_UNPAIR;
} else {
if ( bt_state == BT_STATE_ACTIVE ) {
bt_state = BT_STATE_STOP;
} else if ( bt_state == BT_STATE_INACTIVE ) {
bt_state = BT_STATE_START;
}
if ( device_state == DEVICE_ACTIVE ) {
device_state = DEVICE_STOP;
} else if ( device_state == DEVICE_INACTIVE ) {
device_state = DEVICE_START;
}
//bt_device_command = BT_DEVICE_COMMAND_SWITCH;
}
last_button_time = get_absolute_time();
}
}
}
#endif
+1
View File
@@ -85,6 +85,7 @@
//------------- Driver configuration -------------//
#define CFG_TUD_CDC 1
#define CFG_TUD_HID 8
// CDC FIFO size of TX and RX
#define CFG_TUD_CDC_RX_BUFSIZE 32
+62 -59
View File
@@ -1,37 +1,16 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2019 Ha Thach (tinyusb.org)
* sekigon-gonnoc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*/
#include "tusb.h"
#include "bsp/board_api.h"
#include "hid_report.h"
#include "usb_device.h"
#include "usb_descriptors.h"
//--------------------------------------------------------------------+
// Device Descriptors
//--------------------------------------------------------------------+
// reserve space for HID descriptor
static uint8_t desc_configuration[DESC_CFG_MAX];
static uint16_t _desc_str[32+1];
// USB device descriptor
tusb_desc_device_t const desc_device =
{
.bLength = sizeof(tusb_desc_device_t),
@@ -57,6 +36,17 @@ tusb_desc_device_t const desc_device =
.bNumConfigurations = 0x01
};
// string labels for device
char const* string_desc_arr [] =
{
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
"Raspberry Pi", // 1: Manufacturer
"Pico BLE HID", // 2: Product
NULL, // 3: Serials, should use chip ID
"Pico BLE HID CDC", // 4: CDC
"Pico USB HID", // 5: USB HID Device
};
// Invoked when received GET DEVICE DESCRIPTOR
// Application return pointer to descriptor
uint8_t const * tud_descriptor_device_cb(void)
@@ -64,46 +54,45 @@ uint8_t const * tud_descriptor_device_cb(void)
return (uint8_t const *) &desc_device;
}
//--------------------------------------------------------------------+
// Configuration Descriptor
//--------------------------------------------------------------------+
// full speed configuration
uint8_t const desc_fs_configuration[] =
{
// Config number, interface count, string index, total length, attribute, power in mA
TUD_CONFIG_DESCRIPTOR(1, ITF_NUM_TOTAL, 0, CONFIG_TOTAL_LEN, 0x00, 100),
// Interface number, string index, protocol, report descriptor len, EP In address, size & polling interval
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
};
// Invoked when received GET CONFIGURATION DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_descriptor_configuration_cb(uint8_t index)
{
(void) index; // for multiple configurations
return desc_fs_configuration;
// set configuration descriptor and CDC descriptor
memset(desc_configuration, 0, sizeof(desc_configuration));
if ( device_state == DEVICE_ACTIVE ) {
uint8_t desc_initial[TUD_CONFIG_DESC_LEN+TUD_CDC_DESC_LEN+1] = {
TUD_CONFIG_DESCRIPTOR(1, 4+num_mounted, 0, TUD_CONFIG_DESC_LEN+TUD_CDC_DESC_LEN+num_mounted*TUD_HID_DESC_LEN, 0x00, 100),
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
};
memcpy(desc_configuration, desc_initial, TUD_CONFIG_DESC_LEN+TUD_CDC_DESC_LEN);
} else {
uint8_t desc_initial[TUD_CONFIG_DESC_LEN+TUD_CDC_DESC_LEN+1] = {
TUD_CONFIG_DESCRIPTOR(1, 4, 0, TUD_CONFIG_DESC_LEN+TUD_CDC_DESC_LEN, 0x00, 100),
TUD_CDC_DESCRIPTOR(ITF_NUM_CDC, 4, EPNUM_CDC_NOTIF, 8, EPNUM_CDC_OUT, EPNUM_CDC_IN, 64),
};
memcpy(desc_configuration, desc_initial, TUD_CONFIG_DESC_LEN+TUD_CDC_DESC_LEN);
}
//--------------------------------------------------------------------+
// String Descriptors
//--------------------------------------------------------------------+
// array of pointer to string descriptors
char const* string_desc_arr [] =
{
(const char[]) { 0x09, 0x04 }, // 0: is supported language is English (0x0409)
"Raspberry Pi", // 1: Manufacturer
"Pico BLE HID", // 2: Product
NULL, // 3: Serials, should use chip ID
"Pico BLE HID CDC", // 4: Product
// add a HID descriptor for each interface mounted on host
if ( device_state == DEVICE_ACTIVE ) {
struct report_desc * descriptor;
for (uint8_t i=0; i<num_mounted;i++) {
descriptor = get_report_desc(i);
if ( descriptor != NULL ) {
uint8_t hid_desc[TUD_HID_DESC_LEN+1] = {
TUD_HID_DESCRIPTOR(ITF_NUM_HID+i, 5, HID_ITF_PROTOCOL_NONE, descriptor->desc_len, EPNUM_HID+i, CFG_TUD_HID_EP_BUFSIZE, 1)
};
memcpy(&desc_configuration[TUD_CONFIG_DESC_LEN+TUD_CDC_DESC_LEN+i*TUD_HID_DESC_LEN], hid_desc, TUD_HID_DESC_LEN);
}
}
}
static uint16_t _desc_str[32+1];
return desc_configuration;
}
// Invoked when received GET STRING DESCRIPTOR request
// Application return pointer to descriptor, whose contents must exist long enough for transfer to complete
@@ -145,3 +134,17 @@ uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid)
return _desc_str;
}
// Invoked when received GET HID REPORT DESCRIPTOR
// Application return pointer to descriptor
// Descriptor contents must exist long enough for transfer to complete
uint8_t const * tud_hid_descriptor_report_cb(uint8_t itf)
{
// find HID report descriptor for indicated interface on the host and forward to device
struct report_desc * descriptor = get_report_desc(itf);
if ( descriptor != NULL ) {
return descriptor->descriptor;
}
return NULL;
}
+3 -1
View File
@@ -5,6 +5,7 @@ enum
{
ITF_NUM_CDC=0,
ITF_NUM_CDC_DATA,
ITF_NUM_HID,
ITF_NUM_TOTAL
};
@@ -15,7 +16,8 @@ enum
#define EPNUM_CDC_NOTIF 0x81
#define EPNUM_CDC_OUT 0x02
#define EPNUM_CDC_IN 0x82
#define EPNUM_HID 0x83
#define CONFIG_TOTAL_LEN (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN)
#define DESC_CFG_MAX (TUD_CONFIG_DESC_LEN + TUD_CDC_DESC_LEN + CFG_TUD_HID*TUD_HID_DESC_LEN)
#endif /* USB_DESCRIPTORS_H_ */
+6
View File
@@ -13,6 +13,8 @@ char cdc_buf[64];
uint16_t cdc_len;
size_t cdc_count;
device_state_t device_state;
void usb_device_init(void) {
// run TinyUSB device
tusb_rhport_init_t dev_init = {
@@ -46,6 +48,10 @@ uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_t
return 0;
}
bool forward_report(uint8_t instance, uint8_t const* report, uint16_t len) {
return tud_hid_n_report(instance, 0, report, len);
}
// print message to CDC in raw hex
void cdc_print_hex(uint8_t const* msg, uint16_t msg_len) {
(void) msg;
+9
View File
@@ -1,11 +1,20 @@
#ifndef USB_DEVICE_H_
#define USB_DEVICE_H_
typedef enum {
DEVICE_INACTIVE=0,
DEVICE_START,
DEVICE_STOP,
DEVICE_ACTIVE
} device_state_t;
extern char cdc_buf[64];
extern uint16_t cdc_len;
extern size_t cdc_count;
extern device_state_t device_state;
void usb_device_init(void);
bool forward_report(uint8_t instance, uint8_t const* report, uint16_t len);
void cdc_print_hex(uint8_t const* msg, uint16_t msg_len);
void cdc_print_str(char const* msg, uint16_t msg_len);
void cdc_print_msg(char const* msg);
+6 -7
View File
@@ -84,26 +84,25 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons
last_report = get_absolute_time();
host_state = HOST_WAIT_POLL;
queue_report(dev_addr, instance, report, len);
// continue to request to receive report
/*if ( !tuh_hid_receive_report(dev_addr, instance) )
{
cdc_print_msg("Error: cannot request report\r\n");
}*/
}
// get host ready by updating descriptors
void host_ready(void) {
if (absolute_time_diff_us(request_time, get_absolute_time()) >= 1000000){
if ( generate_report_descriptor() ) {
if ( desc_hid_report_len > 0 ) {
if ( num_mounted > 0 ) {
host_state = HOST_MOUNTED;
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
} else {
host_state = HOST_INACTIVE;
}
cdc_print_msg("Updating HID report map\n");
update_desc_hid_report();
if ( device_state == DEVICE_ACTIVE ) {
device_state = DEVICE_START;
}
}
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
#ifndef USB_HOST_H_
#define USB_HOST_H_
#define HOST_POLL_INTERVAL 8000
#define HOST_POLL_INTERVAL 7500
typedef enum {
HOST_INACTIVE=0,