diff --git a/external/btstack b/external/btstack index b8a544c9..6d708481 160000 --- a/external/btstack +++ b/external/btstack @@ -1 +1 @@ -Subproject commit b8a544c92eb55ee634ab6e302d5c73c5ea2db1b7 +Subproject commit 6d7084813262308410501e1cf0c602a6ec2b0471 diff --git a/src/components/bluepad32/CMakeLists.txt b/src/components/bluepad32/CMakeLists.txt index 69a2d27e..0e8e031f 100644 --- a/src/components/bluepad32/CMakeLists.txt +++ b/src/components/bluepad32/CMakeLists.txt @@ -20,6 +20,7 @@ set(srcs "uni_balance_board.c" "uni_hid_parser_ds5.c" "uni_hid_parser_generic.c" "uni_hid_parser_icade.c" + "uni_hid_parser_keyboard.c" "uni_hid_parser_mouse.c" "uni_hid_parser_nimbus.c" "uni_hid_parser_ouya.c" @@ -30,6 +31,7 @@ set(srcs "uni_balance_board.c" "uni_hid_parser_wii.c" "uni_hid_parser_xboxone.c" "uni_joystick.c" + "uni_keyboard.c" "uni_log.c" "uni_main.c" "uni_mouse.c" @@ -97,4 +99,4 @@ if(DEFINED ENV{BLUEPAD32_ARDUINO}) endif() string(REPLACE ";" " " ext_symbols "${ext_symbols}") -target_link_libraries(${COMPONENT_LIB} INTERFACE ${ext_symbols}) \ No newline at end of file +target_link_libraries(${COMPONENT_LIB} INTERFACE ${ext_symbols}) diff --git a/src/components/bluepad32/include/uni_bt_defines.h b/src/components/bluepad32/include/uni_bt_defines.h index c4c8ba95..79f9b682 100644 --- a/src/components/bluepad32/include/uni_bt_defines.h +++ b/src/components/bluepad32/include/uni_bt_defines.h @@ -45,6 +45,7 @@ limitations under the License. // Taken from Bluetooth Appearance Values: // https://specificationrefs.bluetooth.com/assigned-values/Appearance%20Values.pdf // clang-format off +#define UNI_BT_HID_APPEARANCE_KEYBOARD 0x3c1 #define UNI_BT_HID_APPEARANCE_MOUSE 0x3c2 #define UNI_BT_HID_APPEARANCE_JOYSTICK 0x3c3 #define UNI_BT_HID_APPEARANCE_GAMEPAD 0x3c4 diff --git a/src/components/bluepad32/include/uni_controller.h b/src/components/bluepad32/include/uni_controller.h index 2d687405..3f0c3fc7 100644 --- a/src/components/bluepad32/include/uni_controller.h +++ b/src/components/bluepad32/include/uni_controller.h @@ -28,6 +28,7 @@ extern "C" { #include "uni_balance_board.h" #include "uni_common.h" #include "uni_gamepad.h" +#include "uni_keyboard.h" #include "uni_mouse.h" typedef enum { @@ -56,6 +57,7 @@ typedef struct { uni_gamepad_t gamepad; uni_mouse_t mouse; uni_balance_board_t balance_board; + uni_keyboard_t keyboard; }; uint8_t battery; // 0=emtpy, 254=full, 255=battery report not available } uni_controller_t; diff --git a/src/components/bluepad32/include/uni_hid_parser_keyboard.h b/src/components/bluepad32/include/uni_hid_parser_keyboard.h new file mode 100644 index 00000000..522b78f4 --- /dev/null +++ b/src/components/bluepad32/include/uni_hid_parser_keyboard.h @@ -0,0 +1,37 @@ +/**************************************************************************** +http://retro.moe/unijoysticle2 + +Copyright 2023 Ricardo Quesada + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +****************************************************************************/ + +#ifndef UNI_HID_PARSER_KEYBOARD_H +#define UNI_HID_PARSER_KEYBOARD_H + +#include + +#include "uni_hid_parser.h" + +// Mouse devices +void uni_hid_parser_keyboard_setup(struct uni_hid_device_s* d); +void uni_hid_parser_keyboard_parse_input_report(struct uni_hid_device_s* d, const uint8_t* report, uint16_t len); +void uni_hid_parser_keyboard_init_report(struct uni_hid_device_s* d); +void uni_hid_parser_keyboard_parse_usage(struct uni_hid_device_s* d, + hid_globals_t* globals, + uint16_t usage_page, + uint16_t usage, + int32_t value); +void uni_hid_parser_keyboard_device_dump(struct uni_hid_device_s* d); + +#endif // UNI_HID_PARSER_KEYBOARD_H \ No newline at end of file diff --git a/src/components/bluepad32/include/uni_keyboard.h b/src/components/bluepad32/include/uni_keyboard.h new file mode 100644 index 00000000..1ffc544a --- /dev/null +++ b/src/components/bluepad32/include/uni_keyboard.h @@ -0,0 +1,41 @@ +/**************************************************************************** +http://retro.moe/unijoysticle2 + +Copyright 2023 Ricardo Quesada + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +****************************************************************************/ + +#ifndef UNI_KEYBOARD_H +#define UNI_KEYBOARD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "uni_common.h" + +typedef struct { + uint8_t modifiers; + uint8_t pressed_keys[16]; +} uni_keyboard_t; + +void uni_keyboard_dump(const uni_keyboard_t* kb); + +#ifdef __cplusplus +} +#endif + +#endif // UNI_KEYBOARD_H diff --git a/src/components/bluepad32/uni_bt_le.c b/src/components/bluepad32/uni_bt_le.c index b5eeece2..535a7476 100644 --- a/src/components/bluepad32/uni_bt_le.c +++ b/src/components/bluepad32/uni_bt_le.c @@ -226,8 +226,7 @@ static void parse_report(uint8_t* packet, uint16_t size) { descriptor_data = hids_client_descriptor_storage_get_descriptor_data(hids_cid, service_index); descriptor_len = hids_client_descriptor_storage_get_descriptor_len(hids_cid, service_index); - device->hid_descriptor_len = descriptor_len; - memcpy(device->hid_descriptor, descriptor_data, sizeof(device->hid_descriptor)); + uni_hid_device_set_hid_descriptor(device, descriptor_data, descriptor_len); } report_data = gattservice_subevent_hid_report_get_report(packet); report_len = gattservice_subevent_hid_report_get_report_len(packet); @@ -278,7 +277,6 @@ static void hids_client_packet_handler(uint8_t packet_type, uint16_t channel, ui loge("Hids Cid: Could not find valid device for hids_cid=%d\n", hids_cid); break; } - uni_hid_device_set_hid_descriptor(device, hid_descriptor_storage, sizeof(hid_descriptor_storage)); uni_hid_device_guess_controller_type_from_pid_vid(device); uni_hid_device_connect(device); uni_hid_device_set_ready(device); @@ -740,7 +738,7 @@ void uni_bt_le_on_gap_event_advertising_report(const uint8_t* packet, uint16_t s adv_event_get_data(packet, &appearance, name); if (appearance != UNI_BT_HID_APPEARANCE_GAMEPAD && appearance != UNI_BT_HID_APPEARANCE_JOYSTICK && - appearance != UNI_BT_HID_APPEARANCE_MOUSE) { + appearance != UNI_BT_HID_APPEARANCE_MOUSE && appearance != UNI_BT_HID_APPEARANCE_KEYBOARD) { // Don't log it. There too many devices advertising themselves. return; } @@ -780,6 +778,10 @@ void uni_bt_le_on_gap_event_advertising_report(const uint8_t* packet, uint16_t s uni_hid_device_set_cod(d, UNI_BT_COD_MAJOR_PERIPHERAL | UNI_BT_COD_MINOR_GAMEPAD); logi("Device '%s' identified as Gamepad\n", name); break; + case UNI_BT_HID_APPEARANCE_KEYBOARD: + uni_hid_device_set_cod(d, UNI_BT_COD_MAJOR_PERIPHERAL | UNI_BT_COD_MINOR_KEYBOARD); + logi("Device '%s' identified as Keyboard\n", name); + break; default: loge("Unsupported appearance: %#x\n", appearance); break; diff --git a/src/components/bluepad32/uni_controller.c b/src/components/bluepad32/uni_controller.c index 1453ea61..321b5825 100644 --- a/src/components/bluepad32/uni_controller.c +++ b/src/components/bluepad32/uni_controller.c @@ -30,6 +30,9 @@ void uni_controller_dump(const uni_controller_t* ctl) { case UNI_CONTROLLER_CLASS_MOUSE: uni_mouse_dump(&ctl->mouse); break; + case UNI_CONTROLLER_CLASS_KEYBOARD: + uni_keyboard_dump(&ctl->keyboard); + break; default: logi("uni_controller_dump: Unsupported controller class: %d\n", ctl->klass); break; diff --git a/src/components/bluepad32/uni_hid_device.c b/src/components/bluepad32/uni_hid_device.c index 4adaa059..156cc2f1 100644 --- a/src/components/bluepad32/uni_hid_device.c +++ b/src/components/bluepad32/uni_hid_device.c @@ -38,6 +38,7 @@ limitations under the License. #include "uni_hid_parser_ds5.h" #include "uni_hid_parser_generic.h" #include "uni_hid_parser_icade.h" +#include "uni_hid_parser_keyboard.h" #include "uni_hid_parser_mouse.h" #include "uni_hid_parser_nimbus.h" #include "uni_hid_parser_ouya.h" @@ -704,6 +705,14 @@ void uni_hid_device_guess_controller_type_from_pid_vid(uni_hid_device_t* d) { d->report_parser.device_dump = uni_hid_parser_mouse_device_dump; logi("Device detected as Mouse: 0x%02x\n", type); break; + case CONTROLLER_TYPE_GenericKeyboard: + d->report_parser.setup = uni_hid_parser_keyboard_setup; + d->report_parser.parse_input_report = uni_hid_parser_keyboard_parse_input_report; + d->report_parser.init_report = uni_hid_parser_keyboard_init_report; + d->report_parser.parse_usage = uni_hid_parser_keyboard_parse_usage; + d->report_parser.device_dump = uni_hid_parser_keyboard_device_dump; + logi("Device detected as Keyboard: 0x%02x\n", type); + break; default: d->report_parser.init_report = uni_hid_parser_generic_init_report; d->report_parser.parse_usage = uni_hid_parser_generic_parse_usage; diff --git a/src/components/bluepad32/uni_hid_parser_keyboard.c b/src/components/bluepad32/uni_hid_parser_keyboard.c new file mode 100644 index 00000000..6e938966 --- /dev/null +++ b/src/components/bluepad32/uni_hid_parser_keyboard.c @@ -0,0 +1,75 @@ +/**************************************************************************** +http://retro.moe/unijoysticle2 + +Copyright 2023 Ricardo Quesada + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +****************************************************************************/ + +#include "uni_hid_parser_keyboard.h" + +#include +#include + +#include "hid_usage.h" +#include "uni_common.h" +#include "uni_controller.h" +#include "uni_hid_device.h" +#include "uni_hid_parser.h" +#include "uni_log.h" + +void uni_hid_parser_keyboard_setup(uni_hid_device_t* d) { + uni_hid_device_set_ready_complete(d); +} + +void uni_hid_parser_keyboard_parse_input_report(struct uni_hid_device_s* d, const uint8_t* report, uint16_t len) { + ARG_UNUSED(d); + printf_hexdump(report, len); +} + +void uni_hid_parser_keyboard_init_report(uni_hid_device_t* d) { + // Reset old state. Each report contains a full-state. + uni_controller_t* ctl = &d->controller; + memset(ctl, 0, sizeof(*ctl)); + ctl->klass = UNI_CONTROLLER_CLASS_KEYBOARD; +} + +void uni_hid_parser_keyboard_parse_usage(uni_hid_device_t* d, + hid_globals_t* globals, + uint16_t usage_page, + uint16_t usage, + int32_t value) { + ARG_UNUSED(globals); + ARG_UNUSED(d); + + switch (usage_page) { + case HID_USAGE_PAGE_KEYBOARD_KEYPAD: + logi("page:%d, usage:%d, value:%d\n", usage_page, usage, value); + break; + + case HID_USAGE_PAGE_CONSUMER: + logi("page:%d, usage:%d, value:%d\n", usage_page, usage, value); + break; + + // unknown usage page + default: + logi("Keyboard: Unsupported page: 0x%04x, usage: 0x%04x, value=0x%x\n", usage_page, usage, value); + break; + } +} + +void uni_hid_parser_keyboard_device_dump(struct uni_hid_device_s* d) { + ARG_UNUSED(d); + + logi("\tuni_hid_parser_keyboard_device_dump: implement me: \n"); +} diff --git a/src/components/bluepad32/uni_hid_parser_mouse.c b/src/components/bluepad32/uni_hid_parser_mouse.c index 36f5fdaa..162e506d 100644 --- a/src/components/bluepad32/uni_hid_parser_mouse.c +++ b/src/components/bluepad32/uni_hid_parser_mouse.c @@ -151,6 +151,7 @@ void uni_hid_parser_mouse_setup(uni_hid_device_t* d) { } void uni_hid_parser_mouse_parse_input_report(struct uni_hid_device_s* d, const uint8_t* report, uint16_t len) { + ARG_UNUSED(len); // Quick hack to support Bluetooth Tank Mouse, which for some reason // it is not parsing the delta X/Y correctly. if (d->vendor_id != TANK_MOUSE_VID || d->product_id != TANK_MOUSE_PID) diff --git a/src/components/bluepad32/uni_keyboard.c b/src/components/bluepad32/uni_keyboard.c new file mode 100644 index 00000000..f2af1bdf --- /dev/null +++ b/src/components/bluepad32/uni_keyboard.c @@ -0,0 +1,26 @@ +/**************************************************************************** +http://retro.moe/unijoysticle2 + +Copyright 2022 Ricardo Quesada + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +****************************************************************************/ + +#include "uni_keyboard.h" +#include "uni_log.h" + +void uni_keyboard_dump(const uni_keyboard_t* kb) { + ARG_UNUSED(kb); + // Don't add "\n" + logi("uni_keyboard_dump: implement me"); +} diff --git a/src/components/bluepad32/uni_platform_pc_debug.c b/src/components/bluepad32/uni_platform_pc_debug.c index 0194ab6d..20e961eb 100644 --- a/src/components/bluepad32/uni_platform_pc_debug.c +++ b/src/components/bluepad32/uni_platform_pc_debug.c @@ -26,6 +26,7 @@ limitations under the License. #include "uni_bt.h" #include "uni_gamepad.h" #include "uni_hid_device.h" +#include "uni_hid_parser_mouse.h" #include "uni_log.h" // @@ -145,6 +146,9 @@ static void pc_debug_on_controller_data(uni_hid_device_t* d, uni_controller_t* c enabled = true; } break; + case UNI_CONTROLLER_CLASS_MOUSE: + uni_hid_parser_mouse_device_dump(d); + break; default: break; } diff --git a/tools/pc_debug/Makefile b/tools/pc_debug/Makefile index 1a220cb0..614d0b8f 100644 --- a/tools/pc_debug/Makefile +++ b/tools/pc_debug/Makefile @@ -91,6 +91,7 @@ bluepad32: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} btstack_ring_b ${BLUEPAD32_ROOT}/uni_hid_parser_ds5.o \ ${BLUEPAD32_ROOT}/uni_hid_parser_generic.o \ ${BLUEPAD32_ROOT}/uni_hid_parser_icade.o \ + ${BLUEPAD32_ROOT}/uni_hid_parser_keyboard.o \ ${BLUEPAD32_ROOT}/uni_hid_parser_mouse.o \ ${BLUEPAD32_ROOT}/uni_hid_parser_nimbus.o \ ${BLUEPAD32_ROOT}/uni_hid_parser_ouya.o \ @@ -101,6 +102,7 @@ bluepad32: ${CORE_OBJ} ${COMMON_OBJ} ${CLASSIC_OBJ} ${SDP_CLIENT} btstack_ring_b ${BLUEPAD32_ROOT}/uni_hid_parser_wii.o \ ${BLUEPAD32_ROOT}/uni_hid_parser_xboxone.o \ ${BLUEPAD32_ROOT}/uni_joystick.o \ + ${BLUEPAD32_ROOT}/uni_keyboard.o \ ${BLUEPAD32_ROOT}/uni_log.o \ ${BLUEPAD32_ROOT}/uni_main.o \ ${BLUEPAD32_ROOT}/uni_mouse.o \