From a42eee7a0735ebd87c0b931a7302b9431631c5b5 Mon Sep 17 00:00:00 2001 From: Joshua Rubin Date: Fri, 8 May 2020 00:36:20 -0600 Subject: [PATCH] organize and refactor bluetooth support Signed-off-by: Joshua Rubin --- keyboards/bioi/g60ble/config.h | 1 - keyboards/bioi/g60ble/g60ble.h | 2 + keyboards/bioi/g60ble/rules.mk | 1 + quantum/quantum.c | 7 + quantum/quantum.h | 4 + quantum/quantum_keycodes.h | 4 + tmk_core/common.mk | 6 + tmk_core/protocol/bluefruit.mk | 11 -- tmk_core/protocol/bluefruit/bluefruit.c | 168 ------------------ tmk_core/protocol/bluefruit/bluefruit.h | 24 --- tmk_core/protocol/bluefruit/main.c | 87 --------- tmk_core/protocol/bluefruit_le/qmk.h | 18 -- tmk_core/protocol/lufa.mk | 41 +++-- tmk_core/protocol/lufa/adafruit_ble.h | 48 ++--- .../adafruit_ble}/ATParser.cpp | 0 .../adafruit_ble}/ATParser.h | 0 .../adafruit_ble}/BLE.cpp | 0 .../{bluefruit_le => lufa/adafruit_ble}/BLE.h | 2 +- .../adafruit_ble}/BLEBattery.cpp | 0 .../adafruit_ble}/BLEBattery.h | 0 .../adafruit_ble}/BluefruitLE_UART.cpp | 17 +- .../adafruit_ble}/BluefruitLE_UART.h | 0 .../adafruit_ble}/HardwareSerial.cpp | 0 .../adafruit_ble}/HardwareSerial.h | 0 .../adafruit_ble}/HardwareSerial_private.h | 0 .../adafruit_ble}/Print.cpp | 0 .../adafruit_ble}/Print.h | 0 .../adafruit_ble}/Stream.cpp | 0 .../adafruit_ble}/Stream.h | 0 .../adafruit_ble}/new.cpp | 0 .../adafruit_ble}/qmk.cpp | 102 +++++++---- .../adafruit_ble}/sdep.h | 0 ...{adafruit_ble.cpp => adafruit_ble_spi.cpp} | 28 ++- tmk_core/protocol/lufa/bluetooth.c | 97 ++++++---- tmk_core/protocol/lufa/bluetooth.h | 65 ++++--- tmk_core/protocol/lufa/bluetooth_classic.c | 114 ++++++++++++ tmk_core/protocol/lufa/bluetooth_classic.h | 13 ++ tmk_core/protocol/lufa/lufa.c | 79 +------- tmk_core/protocol/lufa/outputselect.c | 17 +- tmk_core/protocol/lufa/outputselect.h | 13 +- 40 files changed, 423 insertions(+), 546 deletions(-) delete mode 100644 tmk_core/protocol/bluefruit.mk delete mode 100644 tmk_core/protocol/bluefruit/bluefruit.c delete mode 100644 tmk_core/protocol/bluefruit/bluefruit.h delete mode 100644 tmk_core/protocol/bluefruit/main.c delete mode 100644 tmk_core/protocol/bluefruit_le/qmk.h rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/ATParser.cpp (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/ATParser.h (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/BLE.cpp (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/BLE.h (99%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/BLEBattery.cpp (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/BLEBattery.h (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/BluefruitLE_UART.cpp (92%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/BluefruitLE_UART.h (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/HardwareSerial.cpp (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/HardwareSerial.h (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/HardwareSerial_private.h (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/Print.cpp (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/Print.h (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/Stream.cpp (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/Stream.h (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/new.cpp (100%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/qmk.cpp (57%) rename tmk_core/protocol/{bluefruit_le => lufa/adafruit_ble}/sdep.h (100%) rename tmk_core/protocol/lufa/{adafruit_ble.cpp => adafruit_ble_spi.cpp} (96%) create mode 100644 tmk_core/protocol/lufa/bluetooth_classic.c create mode 100644 tmk_core/protocol/lufa/bluetooth_classic.h diff --git a/keyboards/bioi/g60ble/config.h b/keyboards/bioi/g60ble/config.h index a1b25cc64f10..647820e1b420 100644 --- a/keyboards/bioi/g60ble/config.h +++ b/keyboards/bioi/g60ble/config.h @@ -49,5 +49,4 @@ #define KEYBOARD_LOCK_ENABLE #define MAGIC_KEY_LOCK L #define AdafruitBleBaud 76800 -// #define AdafruitBleBattery #define OUTPUT_AUTO_ENABLE diff --git a/keyboards/bioi/g60ble/g60ble.h b/keyboards/bioi/g60ble/g60ble.h index f1e1699ddcf9..14d208c7e2d8 100644 --- a/keyboards/bioi/g60ble/g60ble.h +++ b/keyboards/bioi/g60ble/g60ble.h @@ -4,6 +4,7 @@ #define XXX KC_NO +// clang-format off #define LAYOUT_all( \ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K49, \ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, \ @@ -87,3 +88,4 @@ { K30, XXX, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3C, K3D }, \ { K40, K41, K42, XXX, XXX, K45, XXX, XXX, XXX, K49, XXX, K4B, K4C, K4D } \ } +// clang-format on diff --git a/keyboards/bioi/g60ble/rules.mk b/keyboards/bioi/g60ble/rules.mk index 6a300a9e9566..37f38b89b06c 100644 --- a/keyboards/bioi/g60ble/rules.mk +++ b/keyboards/bioi/g60ble/rules.mk @@ -26,5 +26,6 @@ BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes LTO_ENABLE = yes BLUETOOTH = AdafruitBLEUART +# BLUETOOTH_BATTERY_ENABLE = yes LAYOUTS = 60_ansi 60_iso 60_hhkb 60_ansi_split_bs_rshift 60_tsangan_hhkb diff --git a/quantum/quantum.c b/quantum/quantum.c index 2053a1a5f479..250c5b25d089 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -21,6 +21,10 @@ # include "outputselect.h" #endif +#ifdef BLUETOOTH_ENABLE +# include "bluetooth.h" +#endif + #ifdef BACKLIGHT_ENABLE # include "backlight.h" extern backlight_config_t backlight_config; @@ -331,6 +335,9 @@ bool process_record_quantum(keyrecord_t *record) { case OUT_BT: set_output(OUTPUT_BLUETOOTH); return false; + case BT_UNPAIR: + bluetooth_unpair(); + return false; #endif } } diff --git a/quantum/quantum.h b/quantum/quantum.h index 17d1d41cc9a2..a510e2c4e3d6 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -182,6 +182,10 @@ extern layer_state_t layer_state; # include "wpm.h" #endif +#ifdef BLUETOOTH_BATTERY_ENABLE +# include "bluetooth.h" +#endif + // Function substitutions to ease GPIO manipulation #if defined(__AVR__) typedef uint8_t pin_t; diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index 0958c4f4eb00..57217c3dbb0b 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -512,6 +512,10 @@ enum quantum_keycodes { DYN_MACRO_PLAY1, DYN_MACRO_PLAY2, +#ifdef BLUETOOTH_ENABLE + BT_UNPAIR, +#endif + // always leave at the end SAFE_RANGE }; diff --git a/tmk_core/common.mk b/tmk_core/common.mk index 8f2ef40b770b..c008247adb94 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -120,12 +120,14 @@ endif ifeq ($(strip $(BLUETOOTH)), AdafruitBLE) TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE + TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE_SPI TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK endif ifeq ($(strip $(BLUETOOTH)), AdafruitBLEUART) TMK_COMMON_DEFS += -DBLUETOOTH_ENABLE + TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE TMK_COMMON_DEFS += -DMODULE_ADAFRUIT_BLE_UART TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK endif @@ -142,6 +144,10 @@ ifeq ($(strip $(BLUETOOTH)), RN42) TMK_COMMON_DEFS += -DNO_USB_STARTUP_CHECK endif +ifeq ($(strip $(BLUETOOTH_BATTERY_ENABLE)), yes) + TMK_COMMON_DEFS += -DBLUETOOTH_BATTERY_ENABLE +endif + ifeq ($(strip $(ONEHAND_ENABLE)), yes) SWAP_HANDS_ENABLE = yes # backwards compatibility endif diff --git a/tmk_core/protocol/bluefruit.mk b/tmk_core/protocol/bluefruit.mk deleted file mode 100644 index 13a0693c5725..000000000000 --- a/tmk_core/protocol/bluefruit.mk +++ /dev/null @@ -1,11 +0,0 @@ -BLUEFRUIT_DIR = protocol/bluefruit - -SRC += $(BLUEFRUIT_DIR)/main.c \ - $(BLUEFRUIT_DIR)/bluefruit.c \ - serial_uart.c - -# Search Path -VPATH += $(TMK_DIR)/$(BLUEFRUIT_DIR) -#VPATH += $(TMK_DIR)/$(BLUEFRUIT_DIR)/usb_debug_only - -OPT_DEFS += -DPROTOCOL_BLUEFRUIT diff --git a/tmk_core/protocol/bluefruit/bluefruit.c b/tmk_core/protocol/bluefruit/bluefruit.c deleted file mode 100644 index fb001855ea4a..000000000000 --- a/tmk_core/protocol/bluefruit/bluefruit.c +++ /dev/null @@ -1,168 +0,0 @@ -/* -Bluefruit Protocol for TMK firmware -Author: Benjamin Gould, 2013 -Based on code Copyright 2011 Jun Wako -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include -#include "host.h" -#include "report.h" -#include "print.h" -#include "debug.h" -#include "host_driver.h" -#include "serial.h" -#include "bluefruit.h" - -#define BLUEFRUIT_TRACE_SERIAL 1 - -static uint8_t bluefruit_keyboard_leds = 0; - -static void bluefruit_serial_send(uint8_t); - -void bluefruit_keyboard_print_report(report_keyboard_t *report) { - if (!debug_keyboard) return; - dprintf("keys: "); - for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) { - debug_hex8(report->keys[i]); - dprintf(" "); - } - dprintf(" mods: "); - debug_hex8(report->mods); - dprintf(" reserved: "); - debug_hex8(report->reserved); - dprintf("\n"); -} - -#ifdef BLUEFRUIT_TRACE_SERIAL -static void bluefruit_trace_header() { - dprintf("+------------------------------------+\n"); - dprintf("| HID report to Bluefruit via serial |\n"); - dprintf("+------------------------------------+\n|"); -} - -static void bluefruit_trace_footer() { dprintf("|\n+------------------------------------+\n\n"); } -#endif - -static void bluefruit_serial_send(uint8_t data) { -#ifdef BLUEFRUIT_TRACE_SERIAL - dprintf(" "); - debug_hex8(data); - dprintf(" "); -#endif - serial_send(data); -} - -/*------------------------------------------------------------------* - * Host driver - *------------------------------------------------------------------*/ - -static uint8_t keyboard_leds(void); -static void send_keyboard(report_keyboard_t *report); -static void send_mouse(report_mouse_t *report); -static void send_system(uint16_t data); -static void send_consumer(uint16_t data); - -void sendString(char string[], int length) { - for (int i = 0; i < length; i++) { - serial_send(string[i]); - } -} - -static host_driver_t driver = {keyboard_leds, send_keyboard, send_mouse, send_system, send_consumer}; - -host_driver_t *bluefruit_driver(void) { return &driver; } - -static uint8_t keyboard_leds(void) { return bluefruit_keyboard_leds; } - -static void send_keyboard(report_keyboard_t *report) { -#ifdef BLUEFRUIT_TRACE_SERIAL - bluefruit_trace_header(); -#endif - bluefruit_serial_send(0xFD); - for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) { - bluefruit_serial_send(report->raw[i]); - } -#ifdef BLUEFRUIT_TRACE_SERIAL - bluefruit_trace_footer(); -#endif -} - -static void send_mouse(report_mouse_t *report) { -#ifdef BLUEFRUIT_TRACE_SERIAL - bluefruit_trace_header(); -#endif - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x03); - bluefruit_serial_send(report->buttons); - bluefruit_serial_send(report->x); - bluefruit_serial_send(report->y); - bluefruit_serial_send(report->v); // should try sending the wheel v here - bluefruit_serial_send(report->h); // should try sending the wheel h here - bluefruit_serial_send(0x00); -#ifdef BLUEFRUIT_TRACE_SERIAL - bluefruit_trace_footer(); -#endif -} - -static void send_system(uint16_t data) {} - -/* -+-----------------+-------------------+-------+ -| Consumer Key | Bit Map | Hex | -+-----------------+-------------------+-------+ -| Home | 00000001 00000000 | 01 00 | -| KeyboardLayout | 00000010 00000000 | 02 00 | -| Search | 00000100 00000000 | 04 00 | -| Snapshot | 00001000 00000000 | 08 00 | -| VolumeUp | 00010000 00000000 | 10 00 | -| VolumeDown | 00100000 00000000 | 20 00 | -| Play/Pause | 01000000 00000000 | 40 00 | -| Fast Forward | 10000000 00000000 | 80 00 | -| Rewind | 00000000 00000001 | 00 01 | -| Scan Next Track | 00000000 00000010 | 00 02 | -| Scan Prev Track | 00000000 00000100 | 00 04 | -| Random Play | 00000000 00001000 | 00 08 | -| Stop | 00000000 00010000 | 00 10 | -+-------------------------------------+-------+ -*/ -#define CONSUMER2BLUEFRUIT(usage) (usage == AUDIO_MUTE ? 0x0000 : (usage == AUDIO_VOL_UP ? 0x1000 : (usage == AUDIO_VOL_DOWN ? 0x2000 : (usage == TRANSPORT_NEXT_TRACK ? 0x0002 : (usage == TRANSPORT_PREV_TRACK ? 0x0004 : (usage == TRANSPORT_STOP ? 0x0010 : (usage == TRANSPORT_STOP_EJECT ? 0x0000 : (usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : (usage == AL_CC_CONFIG ? 0x0000 : (usage == AL_EMAIL ? 0x0000 : (usage == AL_CALCULATOR ? 0x0000 : (usage == AL_LOCAL_BROWSER ? 0x0000 : (usage == AC_SEARCH ? 0x0400 : (usage == AC_HOME ? 0x0100 : (usage == AC_BACK ? 0x0000 : (usage == AC_FORWARD ? 0x0000 : (usage == AC_STOP ? 0x0000 : (usage == AC_REFRESH ? 0x0000 : (usage == AC_BOOKMARKS ? 0x0000 : 0))))))))))))))))))) - -static void send_consumer(uint16_t data) { - static uint16_t last_data = 0; - if (data == last_data) return; - last_data = data; - - uint16_t bitmap = CONSUMER2BLUEFRUIT(data); - -#ifdef BLUEFRUIT_TRACE_SERIAL - dprintf("\nData: "); - debug_hex16(data); - dprintf("; bitmap: "); - debug_hex16(bitmap); - dprintf("\n"); - bluefruit_trace_header(); -#endif - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x02); - bluefruit_serial_send((bitmap >> 8) & 0xFF); - bluefruit_serial_send(bitmap & 0xFF); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x00); -#ifdef BLUEFRUIT_TRACE_SERIAL - bluefruit_trace_footer(); -#endif -} \ No newline at end of file diff --git a/tmk_core/protocol/bluefruit/bluefruit.h b/tmk_core/protocol/bluefruit/bluefruit.h deleted file mode 100644 index 7b636abb955b..000000000000 --- a/tmk_core/protocol/bluefruit/bluefruit.h +++ /dev/null @@ -1,24 +0,0 @@ -/* -Bluefruit Protocol for TMK firmware -Author: Benjamin Gould, 2013 -Based on code Copyright 2011 Jun Wako -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#ifndef VUSB_H -#define VUSB_H - -#include "host_driver.h" - -host_driver_t *bluefruit_driver(void); - -#endif \ No newline at end of file diff --git a/tmk_core/protocol/bluefruit/main.c b/tmk_core/protocol/bluefruit/main.c deleted file mode 100644 index aca46206d5af..000000000000 --- a/tmk_core/protocol/bluefruit/main.c +++ /dev/null @@ -1,87 +0,0 @@ -/* -Bluefruit Protocol for TMK firmware -Author: Benjamin Gould, 2013 -Based on code Copyright 2011 Jun Wako - -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include -#include -#include -#include -#include -#include "../serial.h" -#include "keyboard.h" -#include "host.h" -#include "timer.h" -#include "print.h" -#include "debug.h" -#include "sendchar.h" -#include "suspend.h" -#include "bluefruit.h" - -#define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n)) - -int main(void) { - CPU_PRESCALE(0); - - // DDRD = _BV(PD5); - // DDRB = _BV(PB0); - - // PORTD = _BV(PD5); - // PORTB = _BV(PB0); - - print_set_sendchar(sendchar); - - keyboard_setup(); - - dprintf("Initializing keyboard...\n"); - keyboard_init(); - - dprintf("Setting host driver to bluefruit...\n"); - host_set_driver(bluefruit_driver()); - - dprintf("Initializing serial...\n"); - serial_init(); - - // char swpa[] = "+++\r\n"; - // for (int i = 0; i < 5; i++) { - // serial_send(swpa[i]); - // } - - // char ble_enable[] = "AT+BLEKEYBOARDEN=1\r\n"; - // for (int i = 0; i < 20; i++) { - // serial_send(ble_enable[i]); - // } - - // char reset[] = "ATZ\r\n"; - // for (int i = 0; i < 5; i++) { - // serial_send(reset[i]); - // } - - // for (int i = 0; i < 5; i++) { - // serial_send(swpa[i]); - // } - - // wait an extra second for the PC's operating system - // to load drivers and do whatever it does to actually - // be ready for input - _delay_ms(1000); - // PORTD = ~_BV(PD5); - dprintf("Starting main loop"); - while (1) { - keyboard_task(); - } -} diff --git a/tmk_core/protocol/bluefruit_le/qmk.h b/tmk_core/protocol/bluefruit_le/qmk.h deleted file mode 100644 index 4a13451b8098..000000000000 --- a/tmk_core/protocol/bluefruit_le/qmk.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -extern void adafruit_ble_task(void); -extern bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys); -extern bool adafruit_ble_is_connected(void); -extern bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration); - -#ifdef MOUSE_ENABLE -extern bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons); -#endif - -#ifdef __cplusplus -} -#endif diff --git a/tmk_core/protocol/lufa.mk b/tmk_core/protocol/lufa.mk index 61723d6d1786..cef3c9f010af 100644 --- a/tmk_core/protocol/lufa.mk +++ b/tmk_core/protocol/lufa.mk @@ -25,37 +25,42 @@ endif ifeq ($(strip $(BLUETOOTH_ENABLE)), yes) LUFA_SRC += $(LUFA_DIR)/bluetooth.c \ + $(LUFA_DIR)/bluetooth_classic.c \ $(TMK_DIR)/protocol/serial_uart.c endif -ifeq ($(strip $(BLUETOOTH)), AdafruitBLE) - LUFA_SRC += spi_master.c - LUFA_SRC += analog.c - LUFA_SRC += $(LUFA_DIR)/adafruit_ble.cpp -endif - -ifeq ($(strip $(BLUETOOTH)), AdafruitBLEUART) - LUFA_SRC += $(TMK_DIR)/protocol/bluefruit_le/new.cpp - LUFA_SRC += $(TMK_DIR)/protocol/bluefruit_le/HardwareSerial.cpp - LUFA_SRC += $(TMK_DIR)/protocol/bluefruit_le/Print.cpp - LUFA_SRC += $(TMK_DIR)/protocol/bluefruit_le/Stream.cpp - LUFA_SRC += $(TMK_DIR)/protocol/bluefruit_le/ATParser.cpp - LUFA_SRC += $(TMK_DIR)/protocol/bluefruit_le/BLE.cpp - LUFA_SRC += $(TMK_DIR)/protocol/bluefruit_le/BluefruitLE_UART.cpp - LUFA_SRC += $(TMK_DIR)/protocol/bluefruit_le/BLEBattery.cpp - LUFA_SRC += $(TMK_DIR)/protocol/bluefruit_le/qmk.cpp -endif - ifeq ($(strip $(BLUETOOTH)), AdafruitEZKey) LUFA_SRC += $(LUFA_DIR)/bluetooth.c \ + $(LUFA_DIR)/bluetooth_classic.c \ $(TMK_DIR)/protocol/serial_uart.c endif ifeq ($(strip $(BLUETOOTH)), RN42) LUFA_SRC += $(LUFA_DIR)/bluetooth.c \ + $(LUFA_DIR)/bluetooth_classic.c \ $(TMK_DIR)/protocol/serial_uart.c endif +ifeq ($(strip $(BLUETOOTH)), AdafruitBLE) + LUFA_SRC += spi_master.c + LUFA_SRC += analog.c + LUFA_SRC += $(LUFA_DIR)/bluetooth.c + LUFA_SRC += $(LUFA_DIR)/adafruit_ble_spi.cpp +endif + +ifeq ($(strip $(BLUETOOTH)), AdafruitBLEUART) + LUFA_SRC += $(LUFA_DIR)/bluetooth.c + LUFA_SRC += $(LUFA_DIR)/adafruit_ble/new.cpp + LUFA_SRC += $(LUFA_DIR)/adafruit_ble/HardwareSerial.cpp + LUFA_SRC += $(LUFA_DIR)/adafruit_ble/Print.cpp + LUFA_SRC += $(LUFA_DIR)/adafruit_ble/Stream.cpp + LUFA_SRC += $(LUFA_DIR)/adafruit_ble/ATParser.cpp + LUFA_SRC += $(LUFA_DIR)/adafruit_ble/BLE.cpp + LUFA_SRC += $(LUFA_DIR)/adafruit_ble/BluefruitLE_UART.cpp + LUFA_SRC += $(LUFA_DIR)/adafruit_ble/BLEBattery.cpp + LUFA_SRC += $(LUFA_DIR)/adafruit_ble/qmk.cpp +endif + ifeq ($(strip $(VIRTSER_ENABLE)), yes) LUFA_SRC += $(LUFA_ROOT_PATH)/Drivers/USB/Class/Device/CDCClassDevice.c endif diff --git a/tmk_core/protocol/lufa/adafruit_ble.h b/tmk_core/protocol/lufa/adafruit_ble.h index 3cfe3a6c55c9..f8487cbf520a 100644 --- a/tmk_core/protocol/lufa/adafruit_ble.h +++ b/tmk_core/protocol/lufa/adafruit_ble.h @@ -3,23 +3,18 @@ * Supports the Adafruit BLE board built around the nRF51822 chip. */ #pragma once -#ifdef MODULE_ADAFRUIT_BLE_SPI -# include -# include -# include -# include "config_common.h" -# include "progmem.h" +#include +#include +#include -# ifdef __cplusplus -extern "C" { -# endif - -/* Instruct the module to enable HID keyboard support and reset */ -extern bool adafruit_ble_enable_keyboard(void); +#include "config_common.h" +#include "progmem.h" +#include "report.h" -/* Query to see if the BLE module is connected */ -extern bool adafruit_ble_query_is_connected(void); +#ifdef __cplusplus +extern "C" { +#endif /* Returns true if we believe that the BLE module is connected. * This uses our cached understanding that is maintained by @@ -34,28 +29,21 @@ extern void adafruit_ble_task(void); * this set of keys. * Also sends a key release indicator, so that the keys do not remain * held down. */ -extern bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys); +extern bool adafruit_ble_send_keyboard(report_keyboard_t *report); /* Send a consumer keycode, holding it down for the specified duration * (milliseconds) */ -extern bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration); +extern bool adafruit_ble_send_consumer(uint16_t keycode, int hold_duration); + +extern bool adafruit_ble_unpair(void); -# ifdef MOUSE_ENABLE +#ifdef MOUSE_ENABLE /* Send a mouse/wheel movement report. * The parameters are signed and indicate positive of negative direction * change. */ -extern bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons); -# endif +extern bool adafruit_ble_send_mouse(report_mouse_t *report); +#endif -/* Compute battery voltage by reading an analog pin. - * Returns the integer number of millivolts */ -extern uint32_t adafruit_ble_read_battery_voltage(void); - -extern bool adafruit_ble_set_mode_leds(bool on); -extern bool adafruit_ble_set_power_level(int8_t level); - -# ifdef __cplusplus +#ifdef __cplusplus } -# endif - -#endif // MODULE_ADAFRUIT_BLE_SPI +#endif diff --git a/tmk_core/protocol/bluefruit_le/ATParser.cpp b/tmk_core/protocol/lufa/adafruit_ble/ATParser.cpp similarity index 100% rename from tmk_core/protocol/bluefruit_le/ATParser.cpp rename to tmk_core/protocol/lufa/adafruit_ble/ATParser.cpp diff --git a/tmk_core/protocol/bluefruit_le/ATParser.h b/tmk_core/protocol/lufa/adafruit_ble/ATParser.h similarity index 100% rename from tmk_core/protocol/bluefruit_le/ATParser.h rename to tmk_core/protocol/lufa/adafruit_ble/ATParser.h diff --git a/tmk_core/protocol/bluefruit_le/BLE.cpp b/tmk_core/protocol/lufa/adafruit_ble/BLE.cpp similarity index 100% rename from tmk_core/protocol/bluefruit_le/BLE.cpp rename to tmk_core/protocol/lufa/adafruit_ble/BLE.cpp diff --git a/tmk_core/protocol/bluefruit_le/BLE.h b/tmk_core/protocol/lufa/adafruit_ble/BLE.h similarity index 99% rename from tmk_core/protocol/bluefruit_le/BLE.h rename to tmk_core/protocol/lufa/adafruit_ble/BLE.h index 273918ad3dc0..f246f7701121 100644 --- a/tmk_core/protocol/bluefruit_le/BLE.h +++ b/tmk_core/protocol/lufa/adafruit_ble/BLE.h @@ -35,7 +35,7 @@ #pragma once -#include "qmk.h" +#include "adafruit_ble.h" #ifdef __cplusplus # include "ATParser.h" diff --git a/tmk_core/protocol/bluefruit_le/BLEBattery.cpp b/tmk_core/protocol/lufa/adafruit_ble/BLEBattery.cpp similarity index 100% rename from tmk_core/protocol/bluefruit_le/BLEBattery.cpp rename to tmk_core/protocol/lufa/adafruit_ble/BLEBattery.cpp diff --git a/tmk_core/protocol/bluefruit_le/BLEBattery.h b/tmk_core/protocol/lufa/adafruit_ble/BLEBattery.h similarity index 100% rename from tmk_core/protocol/bluefruit_le/BLEBattery.h rename to tmk_core/protocol/lufa/adafruit_ble/BLEBattery.h diff --git a/tmk_core/protocol/bluefruit_le/BluefruitLE_UART.cpp b/tmk_core/protocol/lufa/adafruit_ble/BluefruitLE_UART.cpp similarity index 92% rename from tmk_core/protocol/bluefruit_le/BluefruitLE_UART.cpp rename to tmk_core/protocol/lufa/adafruit_ble/BluefruitLE_UART.cpp index 0803827ff314..5550053b6f93 100644 --- a/tmk_core/protocol/bluefruit_le/BluefruitLE_UART.cpp +++ b/tmk_core/protocol/lufa/adafruit_ble/BluefruitLE_UART.cpp @@ -68,7 +68,22 @@ bool BluefruitLE_UART::begin(uint32_t baud, bool debug, bool blocking) { Serial.setTimeout(_timeout); // reset Bluefruit module upon connect - return reset(blocking); + bool isOK = reset(blocking); + + if (!isOK && baud != 9600) { + // sometimes the modules get reset and the baud goes to default (9600) + // so if there was an issue, let's retry at the default rate + if (begin(9600, debug, blocking)) { + // since this worked, let's reset the baud rate to where it's + // supposed to be + if (atcommand(F("AT+BAUDRATE"), baud)) { + // and now we try one more time at the correct rate + return begin(baud, debug, blocking); + } + } + } + + return isOK; } /******************************************************************************/ diff --git a/tmk_core/protocol/bluefruit_le/BluefruitLE_UART.h b/tmk_core/protocol/lufa/adafruit_ble/BluefruitLE_UART.h similarity index 100% rename from tmk_core/protocol/bluefruit_le/BluefruitLE_UART.h rename to tmk_core/protocol/lufa/adafruit_ble/BluefruitLE_UART.h diff --git a/tmk_core/protocol/bluefruit_le/HardwareSerial.cpp b/tmk_core/protocol/lufa/adafruit_ble/HardwareSerial.cpp similarity index 100% rename from tmk_core/protocol/bluefruit_le/HardwareSerial.cpp rename to tmk_core/protocol/lufa/adafruit_ble/HardwareSerial.cpp diff --git a/tmk_core/protocol/bluefruit_le/HardwareSerial.h b/tmk_core/protocol/lufa/adafruit_ble/HardwareSerial.h similarity index 100% rename from tmk_core/protocol/bluefruit_le/HardwareSerial.h rename to tmk_core/protocol/lufa/adafruit_ble/HardwareSerial.h diff --git a/tmk_core/protocol/bluefruit_le/HardwareSerial_private.h b/tmk_core/protocol/lufa/adafruit_ble/HardwareSerial_private.h similarity index 100% rename from tmk_core/protocol/bluefruit_le/HardwareSerial_private.h rename to tmk_core/protocol/lufa/adafruit_ble/HardwareSerial_private.h diff --git a/tmk_core/protocol/bluefruit_le/Print.cpp b/tmk_core/protocol/lufa/adafruit_ble/Print.cpp similarity index 100% rename from tmk_core/protocol/bluefruit_le/Print.cpp rename to tmk_core/protocol/lufa/adafruit_ble/Print.cpp diff --git a/tmk_core/protocol/bluefruit_le/Print.h b/tmk_core/protocol/lufa/adafruit_ble/Print.h similarity index 100% rename from tmk_core/protocol/bluefruit_le/Print.h rename to tmk_core/protocol/lufa/adafruit_ble/Print.h diff --git a/tmk_core/protocol/bluefruit_le/Stream.cpp b/tmk_core/protocol/lufa/adafruit_ble/Stream.cpp similarity index 100% rename from tmk_core/protocol/bluefruit_le/Stream.cpp rename to tmk_core/protocol/lufa/adafruit_ble/Stream.cpp diff --git a/tmk_core/protocol/bluefruit_le/Stream.h b/tmk_core/protocol/lufa/adafruit_ble/Stream.h similarity index 100% rename from tmk_core/protocol/bluefruit_le/Stream.h rename to tmk_core/protocol/lufa/adafruit_ble/Stream.h diff --git a/tmk_core/protocol/bluefruit_le/new.cpp b/tmk_core/protocol/lufa/adafruit_ble/new.cpp similarity index 100% rename from tmk_core/protocol/bluefruit_le/new.cpp rename to tmk_core/protocol/lufa/adafruit_ble/new.cpp diff --git a/tmk_core/protocol/bluefruit_le/qmk.cpp b/tmk_core/protocol/lufa/adafruit_ble/qmk.cpp similarity index 57% rename from tmk_core/protocol/bluefruit_le/qmk.cpp rename to tmk_core/protocol/lufa/adafruit_ble/qmk.cpp index 2bf042eeed12..2c464c3dc621 100644 --- a/tmk_core/protocol/bluefruit_le/qmk.cpp +++ b/tmk_core/protocol/lufa/adafruit_ble/qmk.cpp @@ -1,11 +1,13 @@ #include "BLE.h" #include "lufa.h" #include "print.h" +#include "debug.h" +#include "bluetooth.h" +#include "outputselect.h" #ifdef MODULE_ADAFRUIT_BLE_UART # include "BluefruitLE_UART.h" #elif MODULE_ADAFRUIT_BLE_SPI -// TODO #endif #ifdef RGBLIGHT_ENABLE @@ -16,17 +18,16 @@ # include "report.h" #endif -#ifdef AdafruitBleBattery +#ifdef BLUETOOTH_BATTERY_ENABLE # include "BLEBattery.h" #endif #ifdef MODULE_ADAFRUIT_BLE_UART static BluefruitLE_UART ble; #elif MODULE_ADAFRUIT_BLE_SPI -// TODO #endif -#ifdef AdafruitBleBattery +#ifdef BLUETOOTH_BATTERY_ENABLE BLEBattery battery(ble); #endif @@ -37,12 +38,27 @@ static struct { uint8_t USB_DeviceState; } state; -void connected(void) { state.is_connected = true; } +void connected(void) { + dprintf("adafruit ble connected\n"); + state.is_connected = true; +} -void disconnected(void) { state.is_connected = false; } +void disconnected(void) { + dprintf("adafruit ble disconnected\n"); + state.is_connected = false; +} bool adafruit_ble_is_connected(void) { return state.is_connected; } +bool reset() { + if (!ble.reset(true)) return false; + + ble.setConnectCallback(connected); + ble.setDisconnectCallback(disconnected); + + return true; +} + // we don't want bt enabled if we're using usb output. this is super annoying on // phones, for example, when they will not show the on screen keyboard if a bt // keyboard is connected. @@ -63,28 +79,24 @@ bool ble_init() { return false; } #elif MODULE_ADAFRUIT_BLE_SPI -// TODO #endif if (!ble.echo(false)) return false; - if (!ble.atcommand(F("AT+GAPINTERVALS"), "10,30,,")) return false; + ble.atcommand(F("AT+GAPINTERVALS"), "10,30,,"); if (!ble.atcommand(F("AT+GAPDEVNAME"), STR(PRODUCT))) return false; if (!ble.atcommand(F("AT+BLEHIDEN"), 1)) return false; - if (!ble.atcommand(F("AT+BLEPOWERLEVEL"), -12)) return false; + ble.atcommand(F("AT+BLEPOWERLEVEL"), -12); -#ifdef AdafruitBleBattery +#ifdef BLUETOOTH_BATTERY_ENABLE if (!battery.begin(false)) return false; #else // this setting persists across resets, so if we had the battery service - // enabled, it will stay enabled even ifndef AdafruitBleBattery, so we + // enabled, it will stay enabled even ifndef BLUETOOTH_BATTERY_ENABLE, so we // forcibly disable it here. - if (!ble.atcommand(F("AT+BLEBATTEN=0"))) return false; + ble.atcommand(F("AT+BLEBATTEN=0")); #endif - if (!ble.reset()) return false; - - ble.setConnectCallback(connected); - ble.setDisconnectCallback(disconnected); + if (!reset()) return false; state.configured = true; return true; @@ -115,8 +127,26 @@ void rgb_update() { void adafruit_ble_task() { if (!state.configured && !ble_init()) return; - // ensure bt is only available when not connected to usb - set_connectable(USB_DeviceState != DEVICE_STATE_Configured); + switch (where_to_send()) { + case OUTPUT_NONE: + if (output_auto()) { + // if bluetooth is disconnected, where_to_send returns + // OUTPUT_NONE but if the desired output is OUTPUT_AUTO then we + // must make it possible to connect if usb is not connected + set_connectable(USB_DeviceState != DEVICE_STATE_Configured); + break; + } + + set_connectable(false); + break; + case OUTPUT_USB: + set_connectable(false); + break; + case OUTPUT_BLUETOOTH: + case OUTPUT_USB_AND_BT: + set_connectable(true); + break; + } #ifdef RGBLIGHT_ENABLE rgb_update(); @@ -124,28 +154,26 @@ void adafruit_ble_task() { ble.update(200); -#ifdef AdafruitBleBattery - // if you have a way of reading the battery level using analog inputs, you - // can use that value as a percentage (uint8_t) here to update the bt - // battery service value - // - // uint8_t percent = 50; - // battery.update(percent); +#ifdef BLUETOOTH_BATTERY_ENABLE + battery.update(bluetooth_get_battery_level()); #endif } -bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t* keys, uint8_t nkeys) { +bool adafruit_ble_send_keyboard(report_keyboard_t *report) { char cmdbuf[48]; char fmtbuf[64]; + uint8_t * keys = report->keys; + const uint8_t nkeys = sizeof(keys); + strcpy_P(fmtbuf, PSTR("AT+BLEKEYBOARDCODE=%02x-00-%02x-%02x-%02x-%02x-%02x-%02x")); - snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, hid_modifier_mask, keys[0], nkeys >= 1 ? keys[1] : 0, nkeys >= 2 ? keys[2] : 0, nkeys >= 3 ? keys[3] : 0, nkeys >= 4 ? keys[4] : 0, nkeys >= 5 ? keys[5] : 0); + snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, report->mods, keys[0], nkeys >= 1 ? keys[1] : 0, nkeys >= 2 ? keys[2] : 0, nkeys >= 3 ? keys[3] : 0, nkeys >= 4 ? keys[4] : 0, nkeys >= 5 ? keys[5] : 0); return ble.atcommand(cmdbuf); } -bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration) { +bool adafruit_ble_send_consumer(uint16_t keycode, int hold_duration) { char cmdbuf[48]; char fmtbuf[64]; @@ -155,21 +183,27 @@ bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration) { } #ifdef MOUSE_ENABLE -bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons) { +bool adafruit_ble_send_mouse(report_mouse_t *report) { char cmdbuf[48]; char fmtbuf[64]; strcpy_P(fmtbuf, PSTR("AT+BLEHIDMOUSEMOVE=%d,%d,%d,%d")); - snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, x, y, scroll, pan); + snprintf(cmdbuf, sizeof(cmdbuf), fmtbuf, report->x, report->y, report->v, report->h); if (!ble.atcommand(cmdbuf)) { return false; } strcpy_P(cmdbuf, PSTR("AT+BLEHIDMOUSEBUTTON=")); - if (buttons & MOUSE_BTN1) strcat(cmdbuf, "L"); - if (buttons & MOUSE_BTN2) strcat(cmdbuf, "R"); - if (buttons & MOUSE_BTN3) strcat(cmdbuf, "M"); - if (buttons == 0) strcat(cmdbuf, "0"); + if (report->buttons & MOUSE_BTN1) strcat(cmdbuf, "L"); + if (report->buttons & MOUSE_BTN2) strcat(cmdbuf, "R"); + if (report->buttons & MOUSE_BTN3) strcat(cmdbuf, "M"); + if (report->buttons == 0) strcat(cmdbuf, "0"); return ble.atcommand(cmdbuf); } #endif + +bool adafruit_ble_unpair(void) { + set_connectable(false); + if (!ble.atcommand(F("AT+GAPDELBONDS"))) return false; + return reset(); // trigger a reset and reconfigure callbacks +} diff --git a/tmk_core/protocol/bluefruit_le/sdep.h b/tmk_core/protocol/lufa/adafruit_ble/sdep.h similarity index 100% rename from tmk_core/protocol/bluefruit_le/sdep.h rename to tmk_core/protocol/lufa/adafruit_ble/sdep.h diff --git a/tmk_core/protocol/lufa/adafruit_ble.cpp b/tmk_core/protocol/lufa/adafruit_ble_spi.cpp similarity index 96% rename from tmk_core/protocol/lufa/adafruit_ble.cpp rename to tmk_core/protocol/lufa/adafruit_ble_spi.cpp index b07407f38775..3c11c7fec76d 100644 --- a/tmk_core/protocol/lufa/adafruit_ble.cpp +++ b/tmk_core/protocol/lufa/adafruit_ble_spi.cpp @@ -612,14 +612,17 @@ static bool process_queue_item(struct queue_item *item, uint16_t timeout) { } } -bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nkeys) { +bool adafruit_ble_send_keyboard(report_keyboard_t *report) { struct queue_item item; bool didWait = false; item.queue_type = QTKeyReport; - item.key.modifier = hid_modifier_mask; + item.key.modifier = report->mods; item.added = timer_read(); + uint8_t *keys = report->keys; + uint8_t nkeys = sizeof(keys); + while (nkeys >= 0) { item.key.keys[0] = keys[0]; item.key.keys[1] = nkeys >= 1 ? keys[1] : 0; @@ -648,7 +651,7 @@ bool adafruit_ble_send_keys(uint8_t hid_modifier_mask, uint8_t *keys, uint8_t nk return true; } -bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration) { +bool adafruit_ble_send_consumer(uint16_t keycode, int hold_duration) { struct queue_item item; item.queue_type = QTConsumer; @@ -661,15 +664,15 @@ bool adafruit_ble_send_consumer_key(uint16_t keycode, int hold_duration) { } #ifdef MOUSE_ENABLE -bool adafruit_ble_send_mouse_move(int8_t x, int8_t y, int8_t scroll, int8_t pan, uint8_t buttons) { +bool adafruit_ble_send_mouse(report_mouse_t *report) { struct queue_item item; item.queue_type = QTMouseMove; - item.mousemove.x = x; - item.mousemove.y = y; - item.mousemove.scroll = scroll; - item.mousemove.pan = pan; - item.mousemove.buttons = buttons; + item.mousemove.x = report->x; + item.mousemove.y = report->y; + item.mousemove.scroll = report->v; + item.mousemove.pan = report->h; + item.mousemove.buttons = report->buttons; while (!send_buf.enqueue(item)) { send_buf_send_one(); @@ -704,3 +707,10 @@ bool adafruit_ble_set_power_level(int8_t level) { snprintf(cmd, sizeof(cmd), "AT+BLEPOWERLEVEL=%d", level); return at_command(cmd, NULL, 0, false); } + +bool adafruit_ble_unpair(void) { + if (!at_command_P(PSTR("AT+GAPDELBONDS"), NULL, 0)) { + return false; + } + return adafruit_ble_enable_keyboard(); +} diff --git a/tmk_core/protocol/lufa/bluetooth.c b/tmk_core/protocol/lufa/bluetooth.c index 5eb52860b14a..126f9f921ea6 100644 --- a/tmk_core/protocol/lufa/bluetooth.c +++ b/tmk_core/protocol/lufa/bluetooth.c @@ -1,38 +1,67 @@ -/* -Bluefruit Protocol for TMK firmware -Author: Benjamin Gould, 2013 - Jack Humbert, 2015 -Based on code Copyright 2011 Jun Wako -This program is free software: you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or -(at your option) any later version. -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. -You should have received a copy of the GNU General Public License -along with this program. If not, see . -*/ - -#include -#include "report.h" -#include "print.h" -#include "debug.h" #include "bluetooth.h" -void bluefruit_keyboard_print_report(report_keyboard_t *report) { - if (!debug_keyboard) return; - dprintf("keys: "); - for (int i = 0; i < KEYBOARD_REPORT_KEYS; i++) { - debug_hex8(report->keys[i]); - dprintf(" "); - } - dprintf(" mods: "); - debug_hex8(report->mods); - dprintf(" reserved: "); - debug_hex8(report->reserved); - dprintf("\n"); +#ifdef MODULE_ADAFRUIT_BLE +# include "adafruit_ble.h" +#else +# include "bluetooth_classic.h" +#endif + +bool bluetooth_is_connected(void) { +#ifdef MODULE_ADAFRUIT_BLE + return adafruit_ble_is_connected(); +#endif + + return true; // should check if BT is connected here +} + +void bluetooth_unpair() { +#ifdef MODULE_ADAFRUIT_BLE + adafruit_ble_unpair(); +#endif +} + +void bluetooth_task(void) { +#ifdef MODULE_ADAFRUIT_BLE + adafruit_ble_task(); +#else + bluetooth_classic_task(); +#endif +} + +void bluetooth_send_keyboard(report_keyboard_t *report) { + if (!bluetooth_is_connected()) return; + +#ifdef MODULE_ADAFRUIT_BLE + adafruit_ble_send_keyboard(report); +#else + bluetooth_classic_send_keyboard(report); +#endif +} + +void bluetooth_send_consumer(uint16_t data, int hold_duration) { + if (!bluetooth_is_connected()) return; + +#ifdef MODULE_ADAFRUIT_BLE + adafruit_ble_send_consumer(data, 0); +#elif MODULE_RN42 + bluetooth_classic_send_consumer(data, 0); +#endif } -void bluefruit_serial_send(uint8_t data) { serial_send(data); } \ No newline at end of file +#ifdef MOUSE_ENABLE +void bluetooth_send_mouse(report_mouse_t *report) { + if (!bluetooth_is_connected()) return; + +# ifdef MODULE_ADAFRUIT_BLE + adafruit_ble_send_mouse(report); +# else + bluetooth_classic_send_mouse(report); +# endif +} +#endif + +#ifdef BLUETOOTH_BATTERY_ENABLE +uint8_t bluetooth_get_battery_level(void) { return bluetooth_get_battery_level_user(); } + +__attribute__((weak)) uint8_t bluetooth_get_battery_level_user() { return 100; } +#endif diff --git a/tmk_core/protocol/lufa/bluetooth.h b/tmk_core/protocol/lufa/bluetooth.h index 081271a4e646..e2f7de2d5681 100644 --- a/tmk_core/protocol/lufa/bluetooth.h +++ b/tmk_core/protocol/lufa/bluetooth.h @@ -2,6 +2,7 @@ Bluefruit Protocol for TMK firmware Author: Benjamin Gould, 2013 Jack Humbert, 2015 + Joshua Rubin, 2020 Based on code Copyright 2011 Jun Wako This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -15,34 +16,48 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#ifndef BLUETOOTH_H -#define BLUETOOTH_H +#pragma once -#include "../serial.h" +#ifdef __cplusplus +extern "C" { +#endif -void bluefruit_serial_send(uint8_t data); +#include +#include -/* -+-----------------+-------------------+-------+ -| Consumer Key | Bit Map | Hex | -+-----------------+-------------------+-------+ -| Home | 00000001 00000000 | 01 00 | -| KeyboardLayout | 00000010 00000000 | 02 00 | -| Search | 00000100 00000000 | 04 00 | -| Snapshot | 00001000 00000000 | 08 00 | -| VolumeUp | 00010000 00000000 | 10 00 | -| VolumeDown | 00100000 00000000 | 20 00 | -| Play/Pause | 01000000 00000000 | 40 00 | -| Fast Forward | 10000000 00000000 | 80 00 | -| Rewind | 00000000 00000001 | 00 01 | -| Scan Next Track | 00000000 00000010 | 00 02 | -| Scan Prev Track | 00000000 00000100 | 00 04 | -| Random Play | 00000000 00001000 | 00 08 | -| Stop | 00000000 00010000 | 00 10 | -+-------------------------------------+-------+ -*/ -#define CONSUMER2BLUEFRUIT(usage) (usage == AUDIO_MUTE ? 0x0000 : (usage == AUDIO_VOL_UP ? 0x1000 : (usage == AUDIO_VOL_DOWN ? 0x2000 : (usage == TRANSPORT_NEXT_TRACK ? 0x0002 : (usage == TRANSPORT_PREV_TRACK ? 0x0004 : (usage == TRANSPORT_STOP ? 0x0010 : (usage == TRANSPORT_STOP_EJECT ? 0x0000 : (usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : (usage == AL_CC_CONFIG ? 0x0000 : (usage == AL_EMAIL ? 0x0000 : (usage == AL_CALCULATOR ? 0x0000 : (usage == AL_LOCAL_BROWSER ? 0x0000 : (usage == AC_SEARCH ? 0x0400 : (usage == AC_HOME ? 0x0100 : (usage == AC_BACK ? 0x0000 : (usage == AC_FORWARD ? 0x0000 : (usage == AC_STOP ? 0x0000 : (usage == AC_REFRESH ? 0x0000 : (usage == AC_BOOKMARKS ? 0x0000 : 0))))))))))))))))))) +#include "report.h" + +/* Returns true if we believe that the BLE module is connected. This uses our + * cached understanding that is maintained by calling bluetooth_task() + * periodically. */ +bool bluetooth_is_connected(void); + +/* Clears bluetooth bonding information allowing it to connnect to a new host */ +void bluetooth_unpair(void); + +/* Call this periodically to process bluetooth-originated things */ +void bluetooth_task(void); -#define CONSUMER2RN42(usage) (usage == AUDIO_MUTE ? 0x0040 : (usage == AUDIO_VOL_UP ? 0x0010 : (usage == AUDIO_VOL_DOWN ? 0x0020 : (usage == TRANSPORT_NEXT_TRACK ? 0x0100 : (usage == TRANSPORT_PREV_TRACK ? 0x0200 : (usage == TRANSPORT_STOP ? 0x0400 : (usage == TRANSPORT_STOP_EJECT ? 0x0800 : (usage == TRANSPORT_PLAY_PAUSE ? 0x0080 : (usage == AL_EMAIL ? 0x0200 : (usage == AL_LOCAL_BROWSER ? 0x8000 : (usage == AC_SEARCH ? 0x0400 : (usage == AC_HOME ? 0x0100 : 0)))))))))))) +/* Generates keypress events for a set of keys. The hid modifier mask specifies + * the state of the modifier keys for this set of keys. Also sends a key release + * indicator, so that the keys do not remain held down. */ +void bluetooth_send_keyboard(report_keyboard_t *report); + +/* Send a consumer keycode, holding it down for the specified duration + * (milliseconds) */ +void bluetooth_send_consumer(uint16_t keycode, int hold_duration); + +#ifdef MOUSE_ENABLE +/* Send a mouse/wheel movement report. The parameters are signed and indicate + * positive of negative direction change. */ +void bluetooth_send_mouse(report_mouse_t *report); +#endif + +#ifdef BLUETOOTH_BATTERY_ENABLE +uint8_t bluetooth_get_battery_level(void); +uint8_t bluetooth_get_battery_level_user(void); +#endif +#ifdef __cplusplus +} #endif diff --git a/tmk_core/protocol/lufa/bluetooth_classic.c b/tmk_core/protocol/lufa/bluetooth_classic.c new file mode 100644 index 000000000000..66c0ea8bd51b --- /dev/null +++ b/tmk_core/protocol/lufa/bluetooth_classic.c @@ -0,0 +1,114 @@ +/* +Bluefruit Protocol for TMK firmware +Author: Benjamin Gould, 2013 + Jack Humbert, 2015 +Based on code Copyright 2011 Jun Wako +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +#include +#include "bluetooth_classic.h" +#include "../serial.h" + +/* ++-----------------+-------------------+-------+ +| Consumer Key | Bit Map | Hex | ++-----------------+-------------------+-------+ +| Home | 00000001 00000000 | 01 00 | +| KeyboardLayout | 00000010 00000000 | 02 00 | +| Search | 00000100 00000000 | 04 00 | +| Snapshot | 00001000 00000000 | 08 00 | +| VolumeUp | 00010000 00000000 | 10 00 | +| VolumeDown | 00100000 00000000 | 20 00 | +| Play/Pause | 01000000 00000000 | 40 00 | +| Fast Forward | 10000000 00000000 | 80 00 | +| Rewind | 00000000 00000001 | 00 01 | +| Scan Next Track | 00000000 00000010 | 00 02 | +| Scan Prev Track | 00000000 00000100 | 00 04 | +| Random Play | 00000000 00001000 | 00 08 | +| Stop | 00000000 00010000 | 00 10 | ++-------------------------------------+-------+ +*/ +#define CONSUMER2BLUEFRUIT(usage) (usage == AUDIO_MUTE ? 0x0000 : (usage == AUDIO_VOL_UP ? 0x1000 : (usage == AUDIO_VOL_DOWN ? 0x2000 : (usage == TRANSPORT_NEXT_TRACK ? 0x0002 : (usage == TRANSPORT_PREV_TRACK ? 0x0004 : (usage == TRANSPORT_STOP ? 0x0010 : (usage == TRANSPORT_STOP_EJECT ? 0x0000 : (usage == TRANSPORT_PLAY_PAUSE ? 0x4000 : (usage == AL_CC_CONFIG ? 0x0000 : (usage == AL_EMAIL ? 0x0000 : (usage == AL_CALCULATOR ? 0x0000 : (usage == AL_LOCAL_BROWSER ? 0x0000 : (usage == AC_SEARCH ? 0x0400 : (usage == AC_HOME ? 0x0100 : (usage == AC_BACK ? 0x0000 : (usage == AC_FORWARD ? 0x0000 : (usage == AC_STOP ? 0x0000 : (usage == AC_REFRESH ? 0x0000 : (usage == AC_BOOKMARKS ? 0x0000 : 0))))))))))))))))))) + +#define CONSUMER2RN42(usage) (usage == AUDIO_MUTE ? 0x0040 : (usage == AUDIO_VOL_UP ? 0x0010 : (usage == AUDIO_VOL_DOWN ? 0x0020 : (usage == TRANSPORT_NEXT_TRACK ? 0x0100 : (usage == TRANSPORT_PREV_TRACK ? 0x0200 : (usage == TRANSPORT_STOP ? 0x0400 : (usage == TRANSPORT_STOP_EJECT ? 0x0800 : (usage == TRANSPORT_PLAY_PAUSE ? 0x0080 : (usage == AL_EMAIL ? 0x0200 : (usage == AL_LOCAL_BROWSER ? 0x8000 : (usage == AC_SEARCH ? 0x0400 : (usage == AC_HOME ? 0x0100 : 0)))))))))))) + +static struct { bool initialized; } state; + +void bluetooth_classic_task() { + if (!state.initialized) { + serial_init(); + state.initialized = true; + } +} + +void bluetooth_classic_send_keyboard(report_keyboard_t *report) { +#ifdef MODULE_RN42 + serial_send(0xFD); + serial_send(0x09); + serial_send(0x01); + serial_send(report->mods); + serial_send(report->reserved); + for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { + serial_send(report->keys[i]); + } +#else + serial_send(0xFD); + serial_send(report->mods); + serial_send(report->reserved); + for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { + serial_send(report->keys[i]); + } +#endif +} + +void bluetooth_classic_send_consumer(uint16_t data, int hold_duration) { +#ifdef MODULE_RN42 + static uint16_t last_data = 0; + if (data == last_data) return; + last_data = data; + uint16_t bitmap = CONSUMER2RN42(data); + serial_send(0xFD); + serial_send(0x03); + serial_send(0x03); + serial_send(bitmap & 0xFF); + serial_send((bitmap >> 8) & 0xFF); +#else + static uint16_t last_data = 0; + if (data == last_data) return; + last_data = data; + uint16_t bitmap = CONSUMER2BLUEFRUIT(data); + serial_send(0xFD); + serial_send(0x00); + serial_send(0x02); + serial_send((bitmap >> 8) & 0xFF); + serial_send(bitmap & 0xFF); + serial_send(0x00); + serial_send(0x00); + serial_send(0x00); + serial_send(0x00); +#endif +} + +#ifdef MOUSE_ENABLE +void bluetooth_classic_send_mouse(report_mouse_t *report) { + serial_send(0xFD); + serial_send(0x00); + serial_send(0x03); + serial_send(report->buttons); + serial_send(report->x); + serial_send(report->y); + serial_send(report->v); // should try sending the wheel v here + serial_send(report->h); // should try sending the wheel h here + serial_send(0x00); +} +#endif diff --git a/tmk_core/protocol/lufa/bluetooth_classic.h b/tmk_core/protocol/lufa/bluetooth_classic.h new file mode 100644 index 000000000000..e8d5a0547780 --- /dev/null +++ b/tmk_core/protocol/lufa/bluetooth_classic.h @@ -0,0 +1,13 @@ +#pragma once + +#include "report.h" + +void bluetooth_classic_task(void); + +void bluetooth_classic_send_keyboard(report_keyboard_t *report); + +void bluetooth_classic_send_consumer(uint16_t data, int hold_duration); + +#ifdef MOUSE_ENABLE +void bluetooth_classic_send_mouse(report_mouse_t *report); +#endif diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c index 9cd1c946c012..f9b73229f801 100644 --- a/tmk_core/protocol/lufa/lufa.c +++ b/tmk_core/protocol/lufa/lufa.c @@ -66,13 +66,7 @@ extern keymap_config_t keymap_config; #endif #ifdef BLUETOOTH_ENABLE -# ifdef MODULE_ADAFRUIT_BLE_SPI -# include "adafruit_ble.h" -# elif MODULE_ADAFRUIT_BLE_UART -# include "bluefruit_le/BluefruitLE_UART.h" -# else -# include "bluetooth.h" -# endif +# include "bluetooth.h" #endif #ifdef VIRTSER_ENABLE @@ -559,25 +553,7 @@ static void send_keyboard(report_keyboard_t *report) { #ifdef BLUETOOTH_ENABLE if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { -# if defined(MODULE_ADAFRUIT_BLE_SPI) || defined(MODULE_ADAFRUIT_BLE_UART) - adafruit_ble_send_keys(report->mods, report->keys, sizeof(report->keys)); -# elif defined(MODULE_RN42) - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x09); - bluefruit_serial_send(0x01); - bluefruit_serial_send(report->mods); - bluefruit_serial_send(report->reserved); - for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { - bluefruit_serial_send(report->keys[i]); - } -# else - bluefruit_serial_send(0xFD); - bluefruit_serial_send(report->mods); - bluefruit_serial_send(report->reserved); - for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { - bluefruit_serial_send(report->keys[i]); - } -# endif + bluetooth_send_keyboard(report); } #endif @@ -623,20 +599,7 @@ static void send_mouse(report_mouse_t *report) { # ifdef BLUETOOTH_ENABLE if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { -# if defined(MODULE_ADAFRUIT_BLE_SPI) || defined(MODULE_ADAFRUIT_BLE_UART) - // FIXME: mouse buttons - adafruit_ble_send_mouse_move(report->x, report->y, report->v, report->h, report->buttons); -# else - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x03); - bluefruit_serial_send(report->buttons); - bluefruit_serial_send(report->x); - bluefruit_serial_send(report->y); - bluefruit_serial_send(report->v); // should try sending the wheel v here - bluefruit_serial_send(report->h); // should try sending the wheel h here - bluefruit_serial_send(0x00); -# endif + bluetooth_send_mouse(report); } # endif @@ -701,33 +664,7 @@ static void send_consumer(uint16_t data) { # ifdef BLUETOOTH_ENABLE if (where == OUTPUT_BLUETOOTH || where == OUTPUT_USB_AND_BT) { -# if defined(MODULE_ADAFRUIT_BLE_SPI) || defined(MODULE_ADAFRUIT_BLE_UART) - adafruit_ble_send_consumer_key(data, 0); -# elif defined(MODULE_RN42) - static uint16_t last_data = 0; - if (data == last_data) return; - last_data = data; - uint16_t bitmap = CONSUMER2RN42(data); - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x03); - bluefruit_serial_send(0x03); - bluefruit_serial_send(bitmap & 0xFF); - bluefruit_serial_send((bitmap >> 8) & 0xFF); -# else - static uint16_t last_data = 0; - if (data == last_data) return; - last_data = data; - uint16_t bitmap = CONSUMER2BLUEFRUIT(data); - bluefruit_serial_send(0xFD); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x02); - bluefruit_serial_send((bitmap >> 8) & 0xFF); - bluefruit_serial_send(bitmap & 0xFF); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x00); - bluefruit_serial_send(0x00); -# endif + bluetooth_send_consumer(data, 0); } # endif @@ -949,10 +886,6 @@ int main(void) { setup_usb(); sei(); -#if defined(MODULE_ADAFRUIT_EZKEY) || defined(MODULE_RN42) - serial_init(); -#endif - /* wait for USB startup & debug output */ #ifdef WAIT_FOR_USB @@ -996,8 +929,8 @@ int main(void) { MIDI_Device_USBTask(&USB_MIDI_Interface); #endif -#if defined(MODULE_ADAFRUIT_BLE_SPI) || defined(MODULE_ADAFRUIT_BLE_UART) - adafruit_ble_task(); +#ifdef BLUETOOTH_ENABLE + bluetooth_task(); #endif #ifdef VIRTSER_ENABLE diff --git a/tmk_core/protocol/lufa/outputselect.c b/tmk_core/protocol/lufa/outputselect.c index 28690b7f3a9c..a3508f2f97fd 100644 --- a/tmk_core/protocol/lufa/outputselect.c +++ b/tmk_core/protocol/lufa/outputselect.c @@ -14,11 +14,8 @@ along with this program. If not, see . #include "lufa.h" #include "outputselect.h" -#ifdef MODULE_ADAFRUIT_BLE_SPI -# include "adafruit_ble.h" -#endif -#ifdef MODULE_ADAFRUIT_BLE_UART -# include "bluefruit_le/BluefruitLE_UART.h" +#ifdef BLUETOOTH_ENABLE +# include "bluetooth.h" #endif uint8_t desired_output = OUTPUT_DEFAULT; @@ -47,16 +44,12 @@ uint8_t auto_detect_output(void) { return OUTPUT_USB; } -#if defined(MODULE_ADAFRUIT_BLE_SPI) || defined(MODULE_ADAFRUIT_BLE_UART) - if (adafruit_ble_is_connected()) { +#ifdef BLUETOOTH_ENABLE + if (bluetooth_is_connected()) { return OUTPUT_BLUETOOTH; } #endif -#ifdef BLUETOOTH_ENABLE - return OUTPUT_BLUETOOTH; // should check if BT is connected here -#endif - return OUTPUT_NONE; } @@ -70,3 +63,5 @@ uint8_t where_to_send(void) { } return desired_output; } + +bool output_auto() { return (desired_output == OUTPUT_AUTO); } diff --git a/tmk_core/protocol/lufa/outputselect.h b/tmk_core/protocol/lufa/outputselect.h index 24fe4daa24fe..a82c38eea7dd 100644 --- a/tmk_core/protocol/lufa/outputselect.h +++ b/tmk_core/protocol/lufa/outputselect.h @@ -12,6 +12,12 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + enum outputs { OUTPUT_AUTO, @@ -37,4 +43,9 @@ enum outputs { void set_output(uint8_t output); void set_output_user(uint8_t output); uint8_t auto_detect_output(void); -uint8_t where_to_send(void); \ No newline at end of file +uint8_t where_to_send(void); +bool output_auto(void); + +#ifdef __cplusplus +} +#endif