Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
a1e1ff70fc
|
|||
|
5b3a5beb32
|
|||
|
8a8ec23d87
|
+1
-1
@@ -1 +1 @@
|
|||||||
/build/**/*
|
/*/**/*
|
||||||
|
|||||||
@@ -4,14 +4,19 @@ This project uses a Raspberry Pi Pico W as a Bluetooth Low Energy adapter for
|
|||||||
a wired USB HID input peripheral, allowing it to connect to a host device
|
a wired USB HID input peripheral, allowing it to connect to a host device
|
||||||
over BLE using HID over GATT Profile.
|
over BLE using HID over GATT Profile.
|
||||||
|
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
|
[YouTube Video](https://youtu.be/YuHbTrccshw)
|
||||||
|
|
||||||
### Hardware
|
### Hardware
|
||||||
|
|
||||||
You will need the following hardware to make the device:
|
You will need the following hardware to make the device:
|
||||||
- Raspberry Pi Pico W
|
- Raspberry Pi Pico W
|
||||||
- USB extension cable
|
- USB extension cable
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
You will need to cut the USB extension in half and connect the wires from the
|
You will need to cut the USB extension in half and connect the wires from the
|
||||||
female end to the Raspberry Pi Pico W. The default configuration is to attach
|
female end to the Raspberry Pi Pico W. The default configuration is to attach
|
||||||
the USB's green wire to pin 1/GP0 and USB's white wire to pin 2/GP1. You will
|
the USB's green wire to pin 1/GP0 and USB's white wire to pin 2/GP1. You will
|
||||||
|
|||||||
+33
-24
@@ -26,6 +26,7 @@ static btstack_packet_callback_registration_t l2cap_event_callback_registration;
|
|||||||
static btstack_packet_callback_registration_t sm_event_callback_registration;
|
static btstack_packet_callback_registration_t sm_event_callback_registration;
|
||||||
static uint8_t battery = 100;
|
static uint8_t battery = 100;
|
||||||
hci_con_handle_t con_handle = HCI_CON_HANDLE_INVALID;
|
hci_con_handle_t con_handle = HCI_CON_HANDLE_INVALID;
|
||||||
|
uint16_t conn_interval=1000;
|
||||||
static uint8_t protocol_mode = 1;
|
static uint8_t protocol_mode = 1;
|
||||||
|
|
||||||
static hids_device_report_t *dev_report_storage;
|
static hids_device_report_t *dev_report_storage;
|
||||||
@@ -45,9 +46,6 @@ const uint8_t adv_data_len = sizeof(adv_data);
|
|||||||
static void bt_hid_setup(void);
|
static void bt_hid_setup(void);
|
||||||
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *packet, uint16_t size);
|
||||||
|
|
||||||
//extern uint8_t desc_hid_report[];
|
|
||||||
//extern uint16_t desc_hid_report_len;
|
|
||||||
|
|
||||||
// start BTstack
|
// start BTstack
|
||||||
void btstack_main(void){
|
void btstack_main(void){
|
||||||
bt_hid_setup();
|
bt_hid_setup();
|
||||||
@@ -79,7 +77,7 @@ static void bt_hid_setup(void) {
|
|||||||
|
|
||||||
// setup HID Device service
|
// setup HID Device service
|
||||||
dev_report_storage = (hids_device_report_t *)malloc(sizeof(hids_device_report_t)*NUM_REPORT_IDS);
|
dev_report_storage = (hids_device_report_t *)malloc(sizeof(hids_device_report_t)*NUM_REPORT_IDS);
|
||||||
hids_device_init_with_storage(0, get_desc_hid_report(), get_desc_hid_report_len(), NUM_REPORT_IDS, dev_report_storage);
|
hids_device_init_with_storage(0, desc_hid_report, desc_hid_report_len, NUM_REPORT_IDS, dev_report_storage);
|
||||||
|
|
||||||
// setup advertisements
|
// setup advertisements
|
||||||
uint16_t adv_int_min = 0x0030;
|
uint16_t adv_int_min = 0x0030;
|
||||||
@@ -112,48 +110,56 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
|||||||
(void) channel;
|
(void) channel;
|
||||||
(void) size;
|
(void) size;
|
||||||
|
|
||||||
uint16_t conn_interval;
|
|
||||||
|
|
||||||
if (packet_type != HCI_EVENT_PACKET) return;
|
if (packet_type != HCI_EVENT_PACKET) return;
|
||||||
|
|
||||||
switch (hci_event_packet_get_type(packet)) {
|
switch (hci_event_packet_get_type(packet)) {
|
||||||
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
case HCI_EVENT_DISCONNECTION_COMPLETE:
|
||||||
con_handle = HCI_CON_HANDLE_INVALID;
|
con_handle = HCI_CON_HANDLE_INVALID;
|
||||||
printf("Disconnected\n");
|
cdc_print_msg("Disconnected\n");
|
||||||
|
|
||||||
set_host_state(HOST_STOP_LISTEN);
|
host_state=HOST_STOP_LISTEN;
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
||||||
break;
|
break;
|
||||||
case SM_EVENT_JUST_WORKS_REQUEST:
|
case SM_EVENT_JUST_WORKS_REQUEST:
|
||||||
printf("Just Works requested\n");
|
cdc_print_msg("Just Works requested\n");
|
||||||
sm_just_works_confirm(sm_event_just_works_request_get_handle(packet));
|
sm_just_works_confirm(sm_event_just_works_request_get_handle(packet));
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
||||||
break;
|
break;
|
||||||
case SM_EVENT_NUMERIC_COMPARISON_REQUEST:
|
case SM_EVENT_NUMERIC_COMPARISON_REQUEST:
|
||||||
printf("Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet));
|
cdc_count = sprintf(cdc_buf, "Confirming numeric comparison: %"PRIu32"\n", sm_event_numeric_comparison_request_get_passkey(packet));
|
||||||
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
sm_numeric_comparison_confirm(sm_event_passkey_display_number_get_handle(packet));
|
sm_numeric_comparison_confirm(sm_event_passkey_display_number_get_handle(packet));
|
||||||
break;
|
break;
|
||||||
case SM_EVENT_PASSKEY_DISPLAY_NUMBER:
|
case SM_EVENT_PASSKEY_DISPLAY_NUMBER:
|
||||||
printf("Display Passkey: %"PRIu32"\n", sm_event_passkey_display_number_get_passkey(packet));
|
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;
|
break;
|
||||||
case L2CAP_EVENT_CONNECTION_PARAMETER_UPDATE_RESPONSE:
|
case L2CAP_EVENT_CONNECTION_PARAMETER_UPDATE_RESPONSE:
|
||||||
printf("L2CAP Connection Parameter Update Complete, response: %x\n", l2cap_event_connection_parameter_update_response_get_result(packet));
|
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);
|
||||||
break;
|
break;
|
||||||
case HCI_EVENT_LE_META:
|
case HCI_EVENT_LE_META:
|
||||||
switch (hci_event_le_meta_get_subevent_code(packet)) {
|
switch (hci_event_le_meta_get_subevent_code(packet)) {
|
||||||
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
|
case HCI_SUBEVENT_LE_CONNECTION_COMPLETE:
|
||||||
// print connection parameters (without using float operations)
|
// print connection parameters (without using float operations)
|
||||||
conn_interval = hci_subevent_le_connection_complete_get_conn_interval(packet);
|
conn_interval = hci_subevent_le_connection_complete_get_conn_interval(packet);
|
||||||
printf("LE Connection Complete:\n");
|
set_host_poll_interval(conn_interval);
|
||||||
printf("- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3));
|
cdc_print_msg("LE Connection Complete:\n");
|
||||||
printf("- Connection Latency: %u\n", hci_subevent_le_connection_complete_get_conn_latency(packet));
|
cdc_count = sprintf(cdc_buf, "- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3));
|
||||||
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
|
cdc_count = sprintf(cdc_buf, "- Connection Latency: %u\n", hci_subevent_le_connection_complete_get_conn_latency(packet));
|
||||||
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
break;
|
break;
|
||||||
case HCI_SUBEVENT_LE_CONNECTION_UPDATE_COMPLETE:
|
case HCI_SUBEVENT_LE_CONNECTION_UPDATE_COMPLETE:
|
||||||
// print connection parameters (without using float operations)
|
// print connection parameters (without using float operations)
|
||||||
conn_interval = hci_subevent_le_connection_update_complete_get_conn_interval(packet);
|
conn_interval = hci_subevent_le_connection_update_complete_get_conn_interval(packet);
|
||||||
printf("LE Connection Update:\n");
|
set_host_poll_interval(conn_interval);
|
||||||
printf("- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3));
|
cdc_print_msg("LE Connection Update:\n");
|
||||||
printf("- Connection Latency: %u\n", hci_subevent_le_connection_update_complete_get_conn_latency(packet));
|
cdc_count = sprintf(cdc_buf, "- Connection Interval: %u.%02u ms\n", conn_interval * 125 / 100, 25 * (conn_interval & 3));
|
||||||
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
|
cdc_count = sprintf(cdc_buf, "- Connection Latency: %u\n", hci_subevent_le_connection_update_complete_get_conn_latency(packet));
|
||||||
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -163,9 +169,10 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
|||||||
switch (hci_event_hids_meta_get_subevent_code(packet)){
|
switch (hci_event_hids_meta_get_subevent_code(packet)){
|
||||||
case HIDS_SUBEVENT_INPUT_REPORT_ENABLE:
|
case HIDS_SUBEVENT_INPUT_REPORT_ENABLE:
|
||||||
con_handle = hids_subevent_input_report_enable_get_con_handle(packet);
|
con_handle = hids_subevent_input_report_enable_get_con_handle(packet);
|
||||||
printf("Report Characteristic Subscribed %u\n", hids_subevent_input_report_enable_get_enable(packet));
|
cdc_count = sprintf(cdc_buf, "Report Characteristic Subscribed %u\n", hids_subevent_input_report_enable_get_enable(packet));
|
||||||
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
|
|
||||||
set_host_state(HOST_START_LISTEN);
|
host_state=HOST_START_LISTEN;
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
|
||||||
// request connection param update via L2CAP following Apple Bluetooth Design Guidelines
|
// 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
|
// gap_request_connection_parameter_update(con_handle, 12, 12, 4, 100); // 15 ms, 4, 1s
|
||||||
@@ -176,10 +183,11 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
|||||||
break;
|
break;
|
||||||
case HIDS_SUBEVENT_PROTOCOL_MODE:
|
case HIDS_SUBEVENT_PROTOCOL_MODE:
|
||||||
protocol_mode = hids_subevent_protocol_mode_get_protocol_mode(packet);
|
protocol_mode = hids_subevent_protocol_mode_get_protocol_mode(packet);
|
||||||
printf("Protocol Mode: %s mode\n", hids_subevent_protocol_mode_get_protocol_mode(packet) ? "Report" : "Boot");
|
cdc_count = sprintf(cdc_buf, "Protocol Mode: %s mode\n", hids_subevent_protocol_mode_get_protocol_mode(packet) ? "Report" : "Boot");
|
||||||
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
break;
|
break;
|
||||||
case HIDS_SUBEVENT_CAN_SEND_NOW:
|
case HIDS_SUBEVENT_CAN_SEND_NOW:
|
||||||
printf("HIDS_SUBEVENT_CAN_SEND_NOW\n");
|
//cdc_print_msg("HIDS_SUBEVENT_CAN_SEND_NOW\n");
|
||||||
send_report();
|
send_report();
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1-cyw43_arch_gpio_get(CYW43_WL_GPIO_LED_PIN));
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1-cyw43_arch_gpio_get(CYW43_WL_GPIO_LED_PIN));
|
||||||
break;
|
break;
|
||||||
@@ -197,9 +205,10 @@ static void packet_handler (uint8_t packet_type, uint16_t channel, uint8_t *pack
|
|||||||
void update_desc_hid_report(void) {
|
void update_desc_hid_report(void) {
|
||||||
hci_power_control(HCI_POWER_OFF);
|
hci_power_control(HCI_POWER_OFF);
|
||||||
|
|
||||||
uint16_t len = get_desc_hid_report_len();
|
if (desc_hid_report_len>0) {
|
||||||
if (len>0) {
|
//cdc_print_msg("Update HID report descriptor: ");
|
||||||
hids_device_init_with_storage(0, get_desc_hid_report(), len, NUM_REPORT_IDS, dev_report_storage);
|
//cdc_print_hex(desc_hid_report, desc_hid_report_len);
|
||||||
|
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);
|
hci_power_control(HCI_POWER_ON);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef BT_DEVICE_H_
|
#ifndef BT_DEVICE_H_
|
||||||
#define BT_DEVICE_H_
|
#define BT_DEVICE_H_
|
||||||
|
|
||||||
|
extern uint16_t conn_interval;
|
||||||
|
|
||||||
void btstack_main(void);
|
void btstack_main(void);
|
||||||
void update_desc_hid_report(void);
|
void update_desc_hid_report(void);
|
||||||
|
|
||||||
|
|||||||
@@ -86,7 +86,4 @@
|
|||||||
// To get the audio demos working even with HCI dump at 115200, this truncates long ACL packets
|
// To get the audio demos working even with HCI dump at 115200, this truncates long ACL packets
|
||||||
//#define HCI_DUMP_STDOUT_MAX_SIZE_ACL 100
|
//#define HCI_DUMP_STDOUT_MAX_SIZE_ACL 100
|
||||||
|
|
||||||
// enable larger HID descriptor
|
|
||||||
#define MAX_ATTRIBUTE_VALUE_SIZE 512
|
|
||||||
|
|
||||||
#endif // _PICO_BTSTACK_BTSTACK_CONFIG_H
|
#endif // _PICO_BTSTACK_BTSTACK_CONFIG_H
|
||||||
|
|||||||
BIN
Binary file not shown.
|
After Width: | Height: | Size: 511 KiB |
+43
-37
@@ -11,14 +11,19 @@
|
|||||||
|
|
||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
#include "usb_host.h"
|
#include "usb_host.h"
|
||||||
|
#include "bt_device.h"
|
||||||
|
|
||||||
#include "hid_report.h"
|
#include "hid_report.h"
|
||||||
|
|
||||||
|
extern hci_con_handle_t con_handle;
|
||||||
|
|
||||||
|
uint8_t desc_hid_report[HID_DESCRIPTOR_SIZE];
|
||||||
|
uint16_t desc_hid_report_len=0;
|
||||||
|
|
||||||
static uint8_t buffer_storage[REPORT_BUF_SIZE];
|
static uint8_t buffer_storage[REPORT_BUF_SIZE];
|
||||||
static btstack_ring_buffer_t report_buf;
|
static btstack_ring_buffer_t report_buf;
|
||||||
|
|
||||||
static uint8_t desc_hid_report[HID_DESCRIPTOR_SIZE];
|
static struct report_data *report;
|
||||||
static uint16_t desc_hid_report_len=0;
|
|
||||||
static struct report_desc *descriptors;
|
static struct report_desc *descriptors;
|
||||||
|
|
||||||
static struct report_desc* report_desc_alloc(void);
|
static struct report_desc* report_desc_alloc(void);
|
||||||
@@ -30,8 +35,6 @@ static void report_dict_init(struct report_dict *mapping);
|
|||||||
static void report_dict_free(struct report_dict *mapping, struct report_desc *descriptor);
|
static void report_dict_free(struct report_dict *mapping, struct report_desc *descriptor);
|
||||||
static struct report_dict* find_mapping(uint8_t dev_addr, uint8_t instance, uint8_t report_id);
|
static struct report_dict* find_mapping(uint8_t dev_addr, uint8_t instance, uint8_t report_id);
|
||||||
|
|
||||||
extern hci_con_handle_t con_handle;
|
|
||||||
|
|
||||||
// start listening to HID input reports on all mounted devices
|
// start listening to HID input reports on all mounted devices
|
||||||
bool request_hid_reports_all(void) {
|
bool request_hid_reports_all(void) {
|
||||||
// send request to receive reports on all mounted devices
|
// send request to receive reports on all mounted devices
|
||||||
@@ -39,15 +42,18 @@ bool request_hid_reports_all(void) {
|
|||||||
for (current=descriptors; current != NULL; current=current->next) {
|
for (current=descriptors; current != NULL; current=current->next) {
|
||||||
if (! current->listening) {
|
if (! current->listening) {
|
||||||
if(request_hid_report(current->dev_addr, current->instance)) {
|
if(request_hid_report(current->dev_addr, current->instance)) {
|
||||||
char tempbuf[40];
|
cdc_count = sprintf(cdc_buf, "Listening to input reports on [%u:%u]\n", current->dev_addr, current->instance);
|
||||||
size_t count = sprintf(tempbuf, "Listening to input reports on [%u:%u]\n", current->dev_addr, current->instance);
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
cdc_print_str(tempbuf, count);
|
|
||||||
current->listening = true;
|
current->listening = true;
|
||||||
} else {
|
} else {
|
||||||
|
cdc_print_msg("Error listening to input report(s)\n");
|
||||||
|
stop_hid_reports_all();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
host_state = HOST_LISTENING;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,15 +64,17 @@ bool stop_hid_reports_all(void) {
|
|||||||
for (current=descriptors; current != NULL; current=current->next) {
|
for (current=descriptors; current != NULL; current=current->next) {
|
||||||
if (current->listening) {
|
if (current->listening) {
|
||||||
if(stop_hid_report(current->dev_addr, current->instance)) {
|
if(stop_hid_report(current->dev_addr, current->instance)) {
|
||||||
char tempbuf[40];
|
cdc_count = sprintf(cdc_buf, "Stopping input reports on [%u:%u]\n", current->dev_addr, current->instance);
|
||||||
size_t count = sprintf(tempbuf, "Stopping input reports on [%u:%u]\n", current->dev_addr, current->instance);
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
cdc_print_str(tempbuf, count);
|
|
||||||
current->listening = false;
|
current->listening = false;
|
||||||
} else {
|
} else {
|
||||||
|
cdc_print_msg("Error stopping input report(s)\n");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
host_state = HOST_INACTIVE;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,48 +82,49 @@ bool stop_hid_reports_all(void) {
|
|||||||
void send_report(){
|
void send_report(){
|
||||||
// process queue and send next report
|
// process queue and send next report
|
||||||
if (btstack_ring_buffer_bytes_available(&report_buf)) {
|
if (btstack_ring_buffer_bytes_available(&report_buf)) {
|
||||||
uint8_t dev_addr;
|
|
||||||
uint8_t instance;
|
|
||||||
uint8_t len8[2];
|
uint8_t len8[2];
|
||||||
uint16_t len;
|
|
||||||
uint32_t num_bytes_read;
|
uint32_t num_bytes_read;
|
||||||
|
|
||||||
// retrieve dev_addr from ring_buffer
|
// retrieve dev_addr from ring_buffer
|
||||||
btstack_ring_buffer_read(&report_buf, &dev_addr, 1, &num_bytes_read);
|
btstack_ring_buffer_read(&report_buf, &report->dev_addr, 1, &num_bytes_read);
|
||||||
|
|
||||||
// retrieve instance from ring buffer
|
// retrieve instance from ring buffer
|
||||||
btstack_ring_buffer_read(&report_buf, &instance, 1, &num_bytes_read);
|
btstack_ring_buffer_read(&report_buf, &report->instance, 1, &num_bytes_read);
|
||||||
|
|
||||||
// retrieve length as two uint8_t and turn into uint16_t
|
// retrieve length as two uint8_t and turn into uint16_t
|
||||||
btstack_ring_buffer_read(&report_buf, len8, 2, &num_bytes_read);
|
btstack_ring_buffer_read(&report_buf, len8, 2, &num_bytes_read);
|
||||||
memcpy(&len, len8, 2);
|
memcpy(&report->len, len8, 2);
|
||||||
|
|
||||||
// retrieve report from ring buffer
|
// retrieve report from ring buffer
|
||||||
uint8_t report[len];
|
btstack_ring_buffer_read(&report_buf, report->report, report->len, &num_bytes_read);
|
||||||
btstack_ring_buffer_read(&report_buf, report, len, &num_bytes_read);
|
|
||||||
|
|
||||||
// find report id mapping
|
// find report id mapping
|
||||||
struct report_dict * mapping = find_mapping(dev_addr, instance, report[0]);
|
struct report_dict * mapping = find_mapping(report->dev_addr, report->instance, report->report[0]);
|
||||||
|
|
||||||
char tempbuf[16];
|
cdc_count=sprintf(cdc_buf, "[%04x](%u)> ", con_handle, mapping->ble_id);
|
||||||
size_t count=sprintf(tempbuf, "[%04x](%u) ", con_handle, mapping->ble_id);
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
cdc_print_str(tempbuf, count);
|
|
||||||
|
|
||||||
// send hid report to ble interface
|
// send hid report to ble interface
|
||||||
if (mapping != NULL) {
|
if (mapping != NULL) {
|
||||||
if (mapping->report_id==0) {
|
if (mapping->report_id==0) {
|
||||||
hids_device_send_input_report_for_id(con_handle, mapping->ble_id, report, len);
|
hids_device_send_input_report_for_id(con_handle, mapping->ble_id, report->report, report->len);
|
||||||
cdc_print_hex(report, len);
|
cdc_print_hex(report->report, report->len);
|
||||||
} else {
|
} else {
|
||||||
// replace report ID in original report before sending
|
// replace report ID in original report before sending
|
||||||
hids_device_send_input_report_for_id(con_handle, mapping->ble_id, &report[1], len-1);
|
hids_device_send_input_report_for_id(con_handle, mapping->ble_id, &report->report[1], report->len-1);
|
||||||
cdc_print_hex(&report[1], len-1);
|
cdc_print_hex(&report->report[1], report->len-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// request send of next report
|
// 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);
|
hids_device_request_can_send_now_event(con_handle);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add report to the BTstack ring buffer for sending
|
// add report to the BTstack ring buffer for sending
|
||||||
@@ -125,7 +134,7 @@ void queue_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uin
|
|||||||
uint8_t len8[2];
|
uint8_t len8[2];
|
||||||
memcpy(len8, &len, 2);
|
memcpy(len8, &len, 2);
|
||||||
|
|
||||||
if (btstack_ring_buffer_bytes_free(&report_buf) >= len+4) {
|
if (btstack_ring_buffer_bytes_free(&report_buf) >= len+5) {
|
||||||
// put instance, length, and report into ring buffer if space available
|
// put instance, length, and report into ring buffer if space available
|
||||||
btstack_ring_buffer_write(&report_buf, &dev_addr, 1);
|
btstack_ring_buffer_write(&report_buf, &dev_addr, 1);
|
||||||
btstack_ring_buffer_write(&report_buf, &instance, 1);
|
btstack_ring_buffer_write(&report_buf, &instance, 1);
|
||||||
@@ -136,11 +145,17 @@ void queue_report(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uin
|
|||||||
// request send on BLE HID interface
|
// request send on BLE HID interface
|
||||||
hids_device_request_can_send_now_event(con_handle);
|
hids_device_request_can_send_now_event(con_handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HID report on device has not been requested, flag so it can be polled
|
||||||
|
struct report_desc * descriptor;
|
||||||
|
descriptor = report_desc_find(dev_addr, instance);
|
||||||
|
descriptor->listening = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate memory for HID report ring buffer
|
// allocate memory for HID report ring buffer
|
||||||
void init_report_buf(void) {
|
void init_report_buf(void) {
|
||||||
btstack_ring_buffer_init(&report_buf, buffer_storage, sizeof(buffer_storage));
|
btstack_ring_buffer_init(&report_buf, buffer_storage, sizeof(buffer_storage));
|
||||||
|
report = REPORT_DATA_ALLOC();
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate memory for USB interface report descriptor
|
// allocate memory for USB interface report descriptor
|
||||||
@@ -358,12 +373,3 @@ static struct report_dict * find_mapping(uint8_t dev_addr, uint8_t instance, uin
|
|||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t get_desc_hid_report_len(void) {
|
|
||||||
return desc_hid_report_len;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
uint8_t const* get_desc_hid_report(void) {
|
|
||||||
return desc_hid_report;
|
|
||||||
}
|
|
||||||
|
|||||||
+14
-4
@@ -1,6 +1,7 @@
|
|||||||
#ifndef HID_REPORT_H_
|
#ifndef HID_REPORT_H_
|
||||||
#define HID_REPORT_H_
|
#define HID_REPORT_H_
|
||||||
|
|
||||||
|
#define REPORT_MAX_SIZE 64
|
||||||
#define NUM_REPORT_IDS 16
|
#define NUM_REPORT_IDS 16
|
||||||
#define REPORT_BUF_SIZE 256
|
#define REPORT_BUF_SIZE 256
|
||||||
#define DESCRIPTOR_BUF_SIZE 256
|
#define DESCRIPTOR_BUF_SIZE 256
|
||||||
@@ -22,8 +23,19 @@ struct report_dict {
|
|||||||
struct report_dict *next;
|
struct report_dict *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
# define REPORT_DESC_ALLOC() (struct report_desc *)malloc(sizeof(struct report_desc))
|
struct report_data {
|
||||||
# define REPORT_DICT_ALLOC() (struct report_dict *)malloc(sizeof(struct report_dict))
|
uint8_t dev_addr;
|
||||||
|
uint8_t instance;
|
||||||
|
uint8_t report[REPORT_MAX_SIZE];
|
||||||
|
uint16_t len;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define REPORT_DESC_ALLOC() (struct report_desc *)malloc(sizeof(struct report_desc))
|
||||||
|
#define REPORT_DICT_ALLOC() (struct report_dict *)malloc(sizeof(struct report_dict))
|
||||||
|
#define REPORT_DATA_ALLOC() (struct report_data *)malloc(sizeof(struct report_data))
|
||||||
|
|
||||||
|
extern uint8_t desc_hid_report[HID_DESCRIPTOR_SIZE];
|
||||||
|
extern uint16_t desc_hid_report_len;
|
||||||
|
|
||||||
bool request_hid_reports_all(void);
|
bool request_hid_reports_all(void);
|
||||||
bool stop_hid_reports_all(void);
|
bool stop_hid_reports_all(void);
|
||||||
@@ -33,7 +45,5 @@ void init_report_buf(void);
|
|||||||
bool add_descriptor(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len);
|
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);
|
void remove_instance(uint8_t dev_addr, uint8_t instance);
|
||||||
bool generate_report_descriptor(void);
|
bool generate_report_descriptor(void);
|
||||||
uint16_t get_desc_hid_report_len(void);
|
|
||||||
uint8_t const* get_desc_hid_report(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -12,17 +12,26 @@
|
|||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
#include "usb_host.h"
|
#include "usb_host.h"
|
||||||
|
|
||||||
|
static void usb_main(void);
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
|
||||||
set_sys_clock_khz(192000, true);
|
set_sys_clock_khz(144000, true);
|
||||||
|
|
||||||
sleep_ms(10);
|
sleep_ms(10);
|
||||||
|
|
||||||
// setup BLE on core 1
|
// run BLE on core 1
|
||||||
multicore_reset_core1();
|
multicore_reset_core1();
|
||||||
multicore_launch_core1(btstack_main);
|
multicore_launch_core1(btstack_main);
|
||||||
|
|
||||||
|
// run usb on core 0
|
||||||
|
usb_main();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void usb_main(void) {
|
||||||
// init and run usb host
|
// init and run usb host
|
||||||
usb_host_init();
|
usb_host_init();
|
||||||
|
|
||||||
@@ -30,35 +39,18 @@ int main(void) {
|
|||||||
usb_device_init();
|
usb_device_init();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
switch ( get_host_state() ) {
|
switch ( host_state ) {
|
||||||
case HOST_NEW_DESCRIPTOR:
|
case HOST_NEW_DESCRIPTOR:
|
||||||
if ( host_ready() ) {
|
host_ready();
|
||||||
if(generate_report_descriptor()) {
|
|
||||||
if ( get_desc_hid_report_len() > 0 ) {
|
|
||||||
set_host_state(HOST_MOUNTED);
|
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 1);
|
|
||||||
} else {
|
|
||||||
set_host_state(HOST_INACTIVE);
|
|
||||||
}
|
|
||||||
cdc_print_msg("Updating HID report map\n");
|
|
||||||
update_desc_hid_report();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case HOST_START_LISTEN:
|
case HOST_START_LISTEN:
|
||||||
if (request_hid_reports_all()) {
|
request_hid_reports_all();
|
||||||
set_host_state(HOST_LISTENING);
|
|
||||||
} else {
|
|
||||||
cdc_print_msg("Error listening to input report(s)\n");
|
|
||||||
set_host_state(HOST_INACTIVE);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case HOST_STOP_LISTEN:
|
case HOST_STOP_LISTEN:
|
||||||
if (stop_hid_reports_all()) {
|
stop_hid_reports_all();
|
||||||
set_host_state(HOST_INACTIVE);
|
break;
|
||||||
} else {
|
case HOST_POLL:
|
||||||
cdc_print_msg("Error stopping input report(s)\n");
|
poll_devices();
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -67,6 +59,4 @@ int main(void) {
|
|||||||
tud_task(); // tinyusb device task
|
tud_task(); // tinyusb device task
|
||||||
tud_cdc_write_flush();
|
tud_cdc_write_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -88,10 +88,10 @@
|
|||||||
|
|
||||||
// CDC FIFO size of TX and RX
|
// CDC FIFO size of TX and RX
|
||||||
#define CFG_TUD_CDC_RX_BUFSIZE 32
|
#define CFG_TUD_CDC_RX_BUFSIZE 32
|
||||||
#define CFG_TUD_CDC_TX_BUFSIZE 64
|
#define CFG_TUD_CDC_TX_BUFSIZE 128
|
||||||
|
|
||||||
// CDC Endpoint transfer buffer size, more is faster
|
// CDC Endpoint transfer buffer size, more is faster
|
||||||
#define CFG_TUD_CDC_EP_BUFSIZE 64
|
#define CFG_TUD_CDC_EP_BUFSIZE 128
|
||||||
|
|
||||||
//--------------------------------------------------------------------
|
//--------------------------------------------------------------------
|
||||||
// HOST CONFIGURATION
|
// HOST CONFIGURATION
|
||||||
@@ -121,8 +121,8 @@
|
|||||||
#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB*3+1) // hub typically has 4 ports
|
#define CFG_TUH_DEVICE_MAX (CFG_TUH_HUB*3+1) // hub typically has 4 ports
|
||||||
|
|
||||||
#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX+1)
|
#define CFG_TUH_HID (3*CFG_TUH_DEVICE_MAX+1)
|
||||||
#define CFG_TUH_HID_EPIN_BUFSIZE 64
|
#define CFG_TUH_HID_EPIN_BUFSIZE 128
|
||||||
#define CFG_TUH_HID_EPOUT_BUFSIZE 64
|
#define CFG_TUH_HID_EPOUT_BUFSIZE 128
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,6 +100,7 @@ char const* string_desc_arr [] =
|
|||||||
"Raspberry Pi", // 1: Manufacturer
|
"Raspberry Pi", // 1: Manufacturer
|
||||||
"Pico BLE HID", // 2: Product
|
"Pico BLE HID", // 2: Product
|
||||||
NULL, // 3: Serials, should use chip ID
|
NULL, // 3: Serials, should use chip ID
|
||||||
|
"Pico BLE HID CDC", // 4: Product
|
||||||
};
|
};
|
||||||
|
|
||||||
static uint16_t _desc_str[32+1];
|
static uint16_t _desc_str[32+1];
|
||||||
|
|||||||
+12
-6
@@ -9,6 +9,10 @@
|
|||||||
|
|
||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
|
|
||||||
|
char cdc_buf[64];
|
||||||
|
uint16_t cdc_len;
|
||||||
|
size_t cdc_count;
|
||||||
|
|
||||||
void usb_device_init(void) {
|
void usb_device_init(void) {
|
||||||
// run TinyUSB device
|
// run TinyUSB device
|
||||||
tusb_rhport_init_t dev_init = {
|
tusb_rhport_init_t dev_init = {
|
||||||
@@ -44,21 +48,23 @@ uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_t
|
|||||||
|
|
||||||
// print message to CDC in raw hex
|
// print message to CDC in raw hex
|
||||||
void cdc_print_hex(uint8_t const* msg, uint16_t msg_len) {
|
void cdc_print_hex(uint8_t const* msg, uint16_t msg_len) {
|
||||||
char tempbuf[8];
|
(void) msg;
|
||||||
size_t count;
|
(void) msg_len;
|
||||||
for (int i=0; i<msg_len; i++) {
|
for (int i=0; i<msg_len; i++) {
|
||||||
count=sprintf(tempbuf, "%02X ", msg[i]);
|
cdc_count=sprintf(cdc_buf, "%02X ", msg[i]);
|
||||||
tud_cdc_write(tempbuf, count);
|
tud_cdc_write(cdc_buf, cdc_count);
|
||||||
}
|
}
|
||||||
tud_cdc_write_str("\n");
|
tud_cdc_write_str("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// print text message to CDC
|
// print text message to CDC
|
||||||
void cdc_print_str(char const* msg, uint16_t msg_len) {
|
void cdc_print_str(char const* msg, uint16_t msg_len) {
|
||||||
|
(void) msg;
|
||||||
|
(void) msg_len;
|
||||||
tud_cdc_write(msg, msg_len);
|
tud_cdc_write(msg, msg_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdc_print_msg(char const* msg) {
|
void cdc_print_msg(char const* msg) {
|
||||||
uint16_t msg_len = strlen(msg);
|
cdc_len = strlen(msg);
|
||||||
cdc_print_str(msg, msg_len);
|
cdc_print_str(msg, cdc_len);
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-2
@@ -1,5 +1,9 @@
|
|||||||
#ifndef MAIN_DEVICE_H_
|
#ifndef USB_DEVICE_H_
|
||||||
#define MAIN_DEVICE_H_
|
#define USB_DEVICE_H_
|
||||||
|
|
||||||
|
extern char cdc_buf[64];
|
||||||
|
extern uint16_t cdc_len;
|
||||||
|
extern size_t cdc_count;
|
||||||
|
|
||||||
void usb_device_init(void);
|
void usb_device_init(void);
|
||||||
void cdc_print_hex(uint8_t const* msg, uint16_t msg_len);
|
void cdc_print_hex(uint8_t const* msg, uint16_t msg_len);
|
||||||
|
|||||||
+47
-31
@@ -11,11 +11,14 @@
|
|||||||
|
|
||||||
#include "hid_report.h"
|
#include "hid_report.h"
|
||||||
#include "usb_device.h"
|
#include "usb_device.h"
|
||||||
|
#include "bt_device.h"
|
||||||
|
|
||||||
#include "usb_host.h"
|
#include "usb_host.h"
|
||||||
|
|
||||||
static host_state_t host_state;
|
host_state_t host_state;
|
||||||
static absolute_time_t request_time;
|
static absolute_time_t request_time;
|
||||||
|
static absolute_time_t last_report;
|
||||||
|
static uint16_t host_poll_interval=8000;
|
||||||
|
|
||||||
// initialize usb host
|
// initialize usb host
|
||||||
void usb_host_init(void) {
|
void usb_host_init(void) {
|
||||||
@@ -32,7 +35,7 @@ void usb_host_init(void) {
|
|||||||
tuh_hid_set_default_protocol(HID_PROTOCOL_REPORT);
|
tuh_hid_set_default_protocol(HID_PROTOCOL_REPORT);
|
||||||
tusb_init(BOARD_TUH_RHPORT, &host_init);
|
tusb_init(BOARD_TUH_RHPORT, &host_init);
|
||||||
|
|
||||||
set_host_state(HOST_INACTIVE);
|
host_state=HOST_INACTIVE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -44,16 +47,12 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
|
|||||||
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
|
uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
|
||||||
|
|
||||||
/// send device vid:pid information to CDC for debugging
|
/// send device vid:pid information to CDC for debugging
|
||||||
char tempbuf[CFG_TUD_CDC_TX_BUFSIZE];
|
cdc_count = sprintf(cdc_buf, "Mount: [%04x:%04x][%u:%u] Protocol = %u\n", vid, pid, dev_addr, instance, itf_protocol);
|
||||||
size_t count = sprintf(tempbuf, "Mount: [%04x:%04x][%u:%u] Protocol = %u\n", vid, pid, dev_addr, instance, itf_protocol);
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
cdc_print_str(tempbuf, count);
|
|
||||||
|
|
||||||
// print descriptor
|
|
||||||
//cdc_print_hex(desc_report, desc_len);
|
|
||||||
|
|
||||||
// add to HID report descriptor
|
// add to HID report descriptor
|
||||||
if ( add_descriptor(dev_addr, instance, desc_report, desc_len)) {
|
if ( add_descriptor(dev_addr, instance, desc_report, desc_len)) {
|
||||||
set_host_state(HOST_NEW_DESCRIPTOR);
|
host_state=HOST_NEW_DESCRIPTOR;
|
||||||
request_time=get_absolute_time();
|
request_time=get_absolute_time();
|
||||||
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
cyw43_arch_gpio_put(CYW43_WL_GPIO_LED_PIN, 0);
|
||||||
}
|
}
|
||||||
@@ -63,58 +62,75 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
|
|||||||
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
|
void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
|
||||||
{
|
{
|
||||||
// send device address:instance to CDC for debugging
|
// send device address:instance to CDC for debugging
|
||||||
char tempbuf[CFG_TUD_CDC_TX_BUFSIZE];
|
cdc_count = sprintf(cdc_buf, "Unmount: [%u:%u]\n", dev_addr, instance);
|
||||||
size_t count = sprintf(tempbuf, "Unmount: [%u:%u]\n", dev_addr, instance);
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
cdc_print_str(tempbuf, count);
|
|
||||||
|
|
||||||
if (stop_hid_report(dev_addr, instance)) {
|
if (stop_hid_report(dev_addr, instance)) {
|
||||||
cdc_print_msg("Successfully stopped receiving reports\n");
|
cdc_print_msg("Successfully stopped receiving reports\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
remove_instance(dev_addr, instance);
|
remove_instance(dev_addr, instance);
|
||||||
set_host_state(HOST_NEW_DESCRIPTOR);
|
host_state=HOST_NEW_DESCRIPTOR;
|
||||||
request_time=get_absolute_time();
|
request_time=get_absolute_time();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invoked when received report from device via interrupt endpoint
|
// Invoked when received report from device via interrupt endpoint
|
||||||
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
|
void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
|
||||||
{
|
{
|
||||||
char tempbuf[32];
|
cdc_count = sprintf(cdc_buf, "[%u:%u](%u)< ", dev_addr, instance, len);
|
||||||
size_t count = sprintf(tempbuf, "[%04x:%04x](%u) ", dev_addr, instance, len);
|
cdc_print_str(cdc_buf,cdc_count);
|
||||||
cdc_print_str(tempbuf,count);
|
|
||||||
cdc_print_hex(report, len);
|
cdc_print_hex(report, len);
|
||||||
|
|
||||||
|
last_report = get_absolute_time();
|
||||||
|
host_state = HOST_WAIT_POLL;
|
||||||
queue_report(dev_addr, instance, report, len);
|
queue_report(dev_addr, instance, report, len);
|
||||||
|
|
||||||
// continue to request to receive report
|
// continue to request to receive report
|
||||||
if ( !tuh_hid_receive_report(dev_addr, instance) )
|
/*if ( !tuh_hid_receive_report(dev_addr, instance) )
|
||||||
{
|
{
|
||||||
cdc_print_msg("Error: cannot request report\r\n");
|
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 ) {
|
||||||
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the state of the host
|
// set devices to listening once polling interval has passed
|
||||||
void set_host_state(host_state_t new_host_state) {
|
void poll_devices(void) {
|
||||||
host_state = new_host_state;
|
if (absolute_time_diff_us(last_report, get_absolute_time()) >= host_poll_interval) {
|
||||||
|
request_hid_reports_all();
|
||||||
|
host_state = HOST_LISTENING;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the current state of the host
|
// set the USB host polling interval based on the BT connection interval
|
||||||
host_state_t get_host_state(void) {
|
void set_host_poll_interval(uint16_t bt_conn_interval) {
|
||||||
return host_state;
|
if (bt_conn_interval*1250 > HOST_POLL_INTERVAL) {
|
||||||
}
|
host_poll_interval = bt_conn_interval*1250;
|
||||||
|
} else {
|
||||||
// indicate whether host is ready for updating descriptors
|
host_poll_interval = HOST_POLL_INTERVAL;
|
||||||
bool host_ready(void) {
|
}
|
||||||
return (absolute_time_diff_us(request_time, get_absolute_time()) > 1000000);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// request HID input reports on specified device address and instance
|
// request HID input reports on specified device address and instance
|
||||||
bool request_hid_report(uint8_t dev_addr, uint8_t instance) {
|
bool request_hid_report(uint8_t dev_addr, uint8_t instance) {
|
||||||
// request to receive reports HID devices
|
// request to receive reports HID devices
|
||||||
if ( !tuh_hid_receive_report(dev_addr, instance) ) {
|
if ( !tuh_hid_receive_report(dev_addr, instance) ) {
|
||||||
char tempbuf[CFG_TUD_CDC_TX_BUFSIZE];
|
cdc_count = sprintf(cdc_buf, "Error: cannot request report on [%u:%u]\n", dev_addr, instance);
|
||||||
size_t count = sprintf(tempbuf, "Error: cannot request report on [%u:%u]\n", dev_addr, instance);
|
cdc_print_str(cdc_buf, cdc_count);
|
||||||
cdc_print_str(tempbuf, count);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+10
-5
@@ -1,5 +1,7 @@
|
|||||||
#ifndef MAIN_HOST_H_
|
#ifndef USB_HOST_H_
|
||||||
#define MAIN_HOST_H_
|
#define USB_HOST_H_
|
||||||
|
|
||||||
|
#define HOST_POLL_INTERVAL 25000
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
HOST_INACTIVE=0,
|
HOST_INACTIVE=0,
|
||||||
@@ -7,14 +9,17 @@ typedef enum {
|
|||||||
HOST_MOUNTED,
|
HOST_MOUNTED,
|
||||||
HOST_START_LISTEN,
|
HOST_START_LISTEN,
|
||||||
HOST_LISTENING,
|
HOST_LISTENING,
|
||||||
|
HOST_WAIT_POLL,
|
||||||
|
HOST_POLL,
|
||||||
HOST_STOP_LISTEN,
|
HOST_STOP_LISTEN,
|
||||||
} host_state_t;
|
} host_state_t;
|
||||||
|
|
||||||
|
extern host_state_t host_state;
|
||||||
|
|
||||||
void usb_host_init(void);
|
void usb_host_init(void);
|
||||||
void set_host_state(host_state_t new_host_state);
|
void host_ready(void);
|
||||||
host_state_t get_host_state(void);
|
void poll_devices(void);
|
||||||
bool host_ready(void);
|
void set_host_poll_interval(uint16_t bt_conn_interval);
|
||||||
bool request_hid_report(uint8_t dev_addr, uint8_t instance);
|
bool request_hid_report(uint8_t dev_addr, uint8_t instance);
|
||||||
bool stop_hid_report(uint8_t dev_addr, uint8_t instance);
|
bool stop_hid_report(uint8_t dev_addr, uint8_t instance);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user