From 1180d0f8407ed8589e0ad6d18931f699eeeccfd7 Mon Sep 17 00:00:00 2001
From: Vino Rodrigues <366673+vinorodrigues@users.noreply.github.com>
Date: Sun, 31 Dec 2023 00:08:43 +1100
Subject: [PATCH 1/6] rename or delete legacy bluetooth files
---
...{bluefruit_le.cpp => bluefruit_le_spi.cpp} | 0
drivers/bluetooth/bluetooth.c | 62 ----------------
drivers/bluetooth/bluetooth_legacy.c | 58 +++++++++++++++
.../{bluetooth.h => bluetooth_legacy.h} | 4 ++
drivers/bluetooth/outputselect.c | 70 -------------------
drivers/bluetooth/outputselect.h | 34 ---------
6 files changed, 62 insertions(+), 166 deletions(-)
rename drivers/bluetooth/{bluefruit_le.cpp => bluefruit_le_spi.cpp} (100%)
delete mode 100644 drivers/bluetooth/bluetooth.c
create mode 100644 drivers/bluetooth/bluetooth_legacy.c
rename drivers/bluetooth/{bluetooth.h => bluetooth_legacy.h} (92%)
delete mode 100644 drivers/bluetooth/outputselect.c
delete mode 100644 drivers/bluetooth/outputselect.h
diff --git a/drivers/bluetooth/bluefruit_le.cpp b/drivers/bluetooth/bluefruit_le_spi.cpp
similarity index 100%
rename from drivers/bluetooth/bluefruit_le.cpp
rename to drivers/bluetooth/bluefruit_le_spi.cpp
diff --git a/drivers/bluetooth/bluetooth.c b/drivers/bluetooth/bluetooth.c
deleted file mode 100644
index d5382401e7e5..000000000000
--- a/drivers/bluetooth/bluetooth.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2022
- *
- * 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 "bluetooth.h"
-
-#if defined(BLUETOOTH_BLUEFRUIT_LE)
-# include "bluefruit_le.h"
-#elif defined(BLUETOOTH_RN42)
-# include "rn42.h"
-#endif
-
-void bluetooth_init(void) {
-#if defined(BLUETOOTH_BLUEFRUIT_LE)
- bluefruit_le_init();
-#elif defined(BLUETOOTH_RN42)
- rn42_init();
-#endif
-}
-
-void bluetooth_task(void) {
-#if defined(BLUETOOTH_BLUEFRUIT_LE)
- bluefruit_le_task();
-#endif
-}
-
-void bluetooth_send_keyboard(report_keyboard_t *report) {
-#if defined(BLUETOOTH_BLUEFRUIT_LE)
- bluefruit_le_send_keyboard(report);
-#elif defined(BLUETOOTH_RN42)
- rn42_send_keyboard(report);
-#endif
-}
-
-void bluetooth_send_mouse(report_mouse_t *report) {
-#if defined(BLUETOOTH_BLUEFRUIT_LE)
- bluefruit_le_send_mouse(report);
-#elif defined(BLUETOOTH_RN42)
- rn42_send_mouse(report);
-#endif
-}
-
-void bluetooth_send_consumer(uint16_t usage) {
-#if defined(BLUETOOTH_BLUEFRUIT_LE)
- bluefruit_le_send_consumer(usage);
-#elif defined(BLUETOOTH_RN42)
- rn42_send_consumer(usage);
-#endif
-}
diff --git a/drivers/bluetooth/bluetooth_legacy.c b/drivers/bluetooth/bluetooth_legacy.c
new file mode 100644
index 000000000000..891ccceecfa9
--- /dev/null
+++ b/drivers/bluetooth/bluetooth_legacy.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2022
+ *
+ * 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 .
+ */
+
+/** DEPRECATED: Provided for backward compatibility */
+
+#include
+#include "bluetooth.h"
+#include "bluetooth_legacy.h"
+
+__attribute__((weak)) void bluetooth_init(void) {
+ bluetooth_driver.init();
+}
+
+__attribute__((weak)) void bluetooth_task(void) {
+ if (NULL != bluetooth_driver.task) {
+ bluetooth_driver.task();
+ }
+}
+
+__attribute__((weak)) void bluetooth_send_keyboard(report_keyboard_t *report) {
+ bluetooth_driver.send_keyboard(report);
+}
+
+#ifdef NKRO_ENABLE
+__attribute__((weak)) void bluetooth_send_nkro(report_keyboard_t *report) {
+ if (NULL != bluetooth_driver.send_nkro) {
+ bluetooth_driver.send_nkro(report);
+ }
+}
+#endif
+
+__attribute__((weak)) void bluetooth_send_mouse(report_mouse_t *report) {
+ bluetooth_driver.send_mouse(report);
+}
+
+__attribute__((weak)) void bluetooth_send_consumer(uint16_t usage) {
+ bluetooth_driver.send_consumer(usage);
+}
+
+__attribute__((weak)) void bluetooth_send_system(uint16_t usage) {
+ if (NULL != bluetooth_driver.send_system) {
+ bluetooth_driver.send_system(usage);
+ }
+}
diff --git a/drivers/bluetooth/bluetooth.h b/drivers/bluetooth/bluetooth_legacy.h
similarity index 92%
rename from drivers/bluetooth/bluetooth.h
rename to drivers/bluetooth/bluetooth_legacy.h
index 2e4d0df5381a..ba5837255278 100644
--- a/drivers/bluetooth/bluetooth.h
+++ b/drivers/bluetooth/bluetooth_legacy.h
@@ -15,8 +15,12 @@
* along with this program. If not, see .
*/
+/** DEPRECATED: Provided for backward compatibility */
+
#pragma once
+#pragma message "`bluetooth.h` is deprecated"
+
#include
#include "report.h"
diff --git a/drivers/bluetooth/outputselect.c b/drivers/bluetooth/outputselect.c
deleted file mode 100644
index b986ba274e9d..000000000000
--- a/drivers/bluetooth/outputselect.c
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-Copyright 2017 Priyadi Iman Nurcahyo
-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 "outputselect.h"
-#include "usb_util.h"
-
-#ifdef BLUETOOTH_BLUEFRUIT_LE
-# include "bluefruit_le.h"
-#endif
-
-uint8_t desired_output = OUTPUT_DEFAULT;
-
-/** \brief Set Output
- *
- * FIXME: Needs doc
- */
-void set_output(uint8_t output) {
- set_output_user(output);
- desired_output = output;
-}
-
-/** \brief Set Output User
- *
- * FIXME: Needs doc
- */
-__attribute__((weak)) void set_output_user(uint8_t output) {}
-
-/** \brief Auto Detect Output
- *
- * FIXME: Needs doc
- */
-uint8_t auto_detect_output(void) {
- if (usb_connected_state()) {
- return OUTPUT_USB;
- }
-
-#ifdef BLUETOOTH_BLUEFRUIT_LE
- if (bluefruit_le_is_connected()) {
- return OUTPUT_BLUETOOTH;
- }
-#endif
-
-#ifdef BLUETOOTH_ENABLE
- return OUTPUT_BLUETOOTH; // should check if BT is connected here
-#endif
-
- return OUTPUT_NONE;
-}
-
-/** \brief Where To Send
- *
- * FIXME: Needs doc
- */
-uint8_t where_to_send(void) {
- if (desired_output == OUTPUT_AUTO) {
- return auto_detect_output();
- }
- return desired_output;
-}
diff --git a/drivers/bluetooth/outputselect.h b/drivers/bluetooth/outputselect.h
deleted file mode 100644
index c4548e1122ad..000000000000
--- a/drivers/bluetooth/outputselect.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
-Copyright 2017 Priyadi Iman Nurcahyo
-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 .
-*/
-
-#pragma once
-
-#include
-
-enum outputs {
- OUTPUT_AUTO,
-
- OUTPUT_NONE,
- OUTPUT_USB,
- OUTPUT_BLUETOOTH
-};
-
-#ifndef OUTPUT_DEFAULT
-# define OUTPUT_DEFAULT OUTPUT_AUTO
-#endif
-
-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);
From 40454a1eb0094695862cd2b9f8a0ea0aa55c40c2 Mon Sep 17 00:00:00 2001
From: Vino Rodrigues <366673+vinorodrigues@users.noreply.github.com>
Date: Sun, 31 Dec 2023 00:10:09 +1100
Subject: [PATCH 2/6] update bluetooth driver
---
builddefs/common_features.mk | 6 +--
drivers/bluetooth/bluetooth.c | 93 +++++++++++++++++++++++++++++++++++
drivers/bluetooth/bluetooth.h | 75 ++++++++++++++++++++++++++++
quantum/keyboard.c | 4 +-
quantum/quantum.c | 8 +--
tmk_core/protocol/host.c | 54 +++++++++++++++-----
6 files changed, 217 insertions(+), 23 deletions(-)
create mode 100644 drivers/bluetooth/bluetooth.c
create mode 100644 drivers/bluetooth/bluetooth.h
diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 5e93480e4d05..18daef1e1ab3 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -884,18 +884,16 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
OPT_DEFS += -DBLUETOOTH_$(strip $(shell echo $(BLUETOOTH_DRIVER) | tr '[:lower:]' '[:upper:]'))
NO_USB_STARTUP_CHECK := yes
COMMON_VPATH += $(DRIVER_PATH)/bluetooth
- SRC += outputselect.c
+ SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
ifeq ($(strip $(BLUETOOTH_DRIVER)), bluefruit_le)
SPI_DRIVER_REQUIRED = yes
ANALOG_DRIVER_REQUIRED = yes
- SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
- SRC += $(DRIVER_PATH)/bluetooth/bluefruit_le.cpp
+ SRC += $(DRIVER_PATH)/bluetooth/bluefruit_le_spi.cpp
endif
ifeq ($(strip $(BLUETOOTH_DRIVER)), rn42)
UART_DRIVER_REQUIRED = yes
- SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
SRC += $(DRIVER_PATH)/bluetooth/rn42.c
endif
endif
diff --git a/drivers/bluetooth/bluetooth.c b/drivers/bluetooth/bluetooth.c
new file mode 100644
index 000000000000..d492baec4c36
--- /dev/null
+++ b/drivers/bluetooth/bluetooth.c
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2024
+ *
+ * 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 "bluetooth.h"
+#include "usb_util.h"
+
+/* Each driver needs to define the struct
+ * const rgb_matrix_driver_t rgb_matrix_driver;
+ * All members (except `task`, `is_connected` and `send_system`) must be provided.
+ * Keyboard custom drivers can define this in their own files, it should only
+ * be here if shared between boards.
+ */
+
+#if defined(BLUETOOTH_BLUEFRUIT_LE)
+const bluetooth_driver_t bluetooth_driver = {
+ .init = bluefruit_le_init,
+ .task = bluefruit_le_task,
+ .is_connected = bluefruit_le_is_connected,
+ .send_keyboard = bluefruit_le_send_keyboard,
+ .send_mouse = bluefruit_le_send_mouse,
+ .send_consumer = bluefruit_le_send_consumer,
+ .send_system = NULL,
+};
+# ifdef ENABLE_NKRO
+# error BlueFruit LE does not support NKRO, do not declare `ENABLE_NKRO`
+# endif
+
+#elif defined(BLUETOOTH_RN42)
+const bluetooth_driver_t bluetooth_driver = {
+ .init = rn42_init,
+ .task = NULL,
+ .is_connected = NULL,
+ .send_keyboard = rn42_send_keyboard,
+ .send_mouse = rn42_send_mouse,
+ .send_consumer = rn42_send_consumer,
+ .send_system = NULL,
+};
+# ifdef ENABLE_NKRO
+# error RN42 does not support NKRO, do not declare `ENABLE_NKRO`
+# endif
+
+#endif
+
+#ifndef SEND_OUTPUT_DEFAULT
+# define SEND_OUTPUT_DEFAULT SEND_OUTPUT_AUTO
+#endif
+
+send_output_t desired_send_output = SEND_OUTPUT_DEFAULT;
+
+send_output_t set_send_output(send_output_t send_output) {
+ desired_send_output = set_send_output_kb(send_output);
+ return desired_send_output;
+}
+
+__attribute__((weak)) send_output_t set_send_output_kb(send_output_t send_output) {
+ return set_send_output_user(send_output);
+}
+
+__attribute__((weak)) send_output_t set_send_output_user(send_output_t send_output) {
+ return send_output;
+}
+
+send_output_t get_send_output(void) {
+ if (desired_send_output == SEND_OUTPUT_AUTO) {
+ // only if USB is **disconnected**
+ if (usb_connected_state()) {
+ return SEND_OUTPUT_USB;
+ }
+ if ((NULL != bluetooth_driver.is_connected) && (bluetooth_driver.is_connected())) {
+ return SEND_OUTPUT_BLUETOOTH;
+ } else {
+ return SEND_OUTPUT_NONE;
+ }
+ } else {
+ return desired_send_output;
+ }
+}
diff --git a/drivers/bluetooth/bluetooth.h b/drivers/bluetooth/bluetooth.h
new file mode 100644
index 000000000000..32d523e9c59a
--- /dev/null
+++ b/drivers/bluetooth/bluetooth.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2024
+ *
+ * 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 .
+ */
+
+#pragma once
+
+#include
+#include
+#include "report.h"
+
+#if defined(BLUETOOTH_BLUEFRUIT_LE)
+# include "bluefruit_le.h"
+#elif defined(BLUETOOTH_RN42)
+# include "rn42.h"
+#endif
+
+// clang-format off
+
+typedef enum send_output_t {
+ SEND_OUTPUT_AUTO,
+ SEND_OUTPUT_NONE,
+ SEND_OUTPUT_USB,
+ SEND_OUTPUT_BLUETOOTH,
+ SEND_OUTPUT_BOTH
+} send_output_t;
+
+// clang-format on
+
+typedef struct {
+ /* Initialize the Bluetooth system. */
+ void (*init)(void);
+
+ /* Perform housekeeping tasks. (Optional) */
+ void (*task)(void);
+
+ /* Detects if BT is connected, also used by `SEND_OUTPUT_AUTO`. (Optional) */
+ bool (*is_connected)(void);
+
+ /* Send a keyboard report. */
+ void (*send_keyboard)(report_keyboard_t *report);
+
+#ifdef NKRO_ENABLE
+ /* Send a NKRO report. (Optional & dependant on `NKRO_ENABLE` ) */
+ void (*send_nkro)(report_keyboard_t *report);
+#endif
+
+ /* Send a mouse report. */
+ void (*send_mouse)(report_mouse_t *report);
+
+ /* Send a consumer usage. */
+ void (*send_consumer)(uint16_t usage);
+
+ /* Send a system usage. (Optional) */
+ void (*send_system)(uint16_t usage);
+} bluetooth_driver_t;
+
+send_output_t set_send_output(send_output_t send_output);
+send_output_t set_send_output_kb(send_output_t send_output);
+send_output_t set_send_output_user(send_output_t send_output);
+send_output_t get_send_output(void);
+
+extern const bluetooth_driver_t bluetooth_driver;
diff --git a/quantum/keyboard.c b/quantum/keyboard.c
index b5fa1a6e2e9c..61aaa2e3878f 100644
--- a/quantum/keyboard.c
+++ b/quantum/keyboard.c
@@ -454,7 +454,7 @@ void keyboard_init(void) {
pointing_device_init();
#endif
#ifdef BLUETOOTH_ENABLE
- bluetooth_init();
+ bluetooth_driver.init();
#endif
#ifdef HAPTIC_ENABLE
haptic_init();
@@ -710,7 +710,7 @@ void keyboard_task(void) {
#endif
#ifdef BLUETOOTH_ENABLE
- bluetooth_task();
+ if (NULL != bluetooth_driver.task) bluetooth_driver.task();
#endif
#ifdef HAPTIC_ENABLE
diff --git a/quantum/quantum.c b/quantum/quantum.c
index 6639dc229109..2749643f1d1c 100644
--- a/quantum/quantum.c
+++ b/quantum/quantum.c
@@ -21,7 +21,7 @@
#endif
#ifdef BLUETOOTH_ENABLE
-# include "outputselect.h"
+# include "bluetooth.h"
#endif
#ifdef GRAVE_ESC_ENABLE
@@ -426,13 +426,13 @@ bool process_record_quantum(keyrecord_t *record) {
#endif
#ifdef BLUETOOTH_ENABLE
case QK_OUTPUT_AUTO:
- set_output(OUTPUT_AUTO);
+ set_send_output(SEND_OUTPUT_AUTO);
return false;
case QK_OUTPUT_USB:
- set_output(OUTPUT_USB);
+ set_send_output(SEND_OUTPUT_USB);
return false;
case QK_OUTPUT_BLUETOOTH:
- set_output(OUTPUT_BLUETOOTH);
+ set_send_output(SEND_OUTPUT_BLUETOOTH);
return false;
#endif
#ifndef NO_ACTION_ONESHOT
diff --git a/tmk_core/protocol/host.c b/tmk_core/protocol/host.c
index 732fbdc37d4d..f90842f1cfc6 100644
--- a/tmk_core/protocol/host.c
+++ b/tmk_core/protocol/host.c
@@ -16,6 +16,7 @@ along with this program. If not, see .
*/
#include
+#include
#include "keyboard.h"
#include "keycode.h"
#include "host.h"
@@ -32,7 +33,6 @@ along with this program. If not, see .
#ifdef BLUETOOTH_ENABLE
# include "bluetooth.h"
-# include "outputselect.h"
#endif
#ifdef NKRO_ENABLE
@@ -74,10 +74,12 @@ led_t host_keyboard_led_state(void) {
/* send report */
void host_keyboard_send(report_keyboard_t *report) {
#ifdef BLUETOOTH_ENABLE
- if (where_to_send() == OUTPUT_BLUETOOTH) {
- bluetooth_send_keyboard(report);
- return;
- }
+ send_output_t where_to_send = get_send_output();
+ if ((where_to_send == SEND_OUTPUT_BLUETOOTH) || (where_to_send == SEND_OUTPUT_BOTH)) {
+ bluetooth_driver.send_keyboard(report);
+ if (where_to_send == SEND_OUTPUT_BLUETOOTH) return; // only BT, jump out
+ } else if ((where_to_send == SEND_OUTPUT_NONE))
+ return; // dont send to USB either, jump out
#endif
if (!driver) return;
@@ -98,6 +100,16 @@ void host_keyboard_send(report_keyboard_t *report) {
void host_nkro_send(report_nkro_t *report) {
if (!driver) return;
report->report_id = REPORT_ID_NKRO;
+
+#if defined(BLUETOOTH_ENABLE) && defined(NKRO_ENABLE)
+ send_output_t where_to_send = get_send_output();
+ if ((where_to_send == SEND_OUTPUT_BLUETOOTH) || (where_to_send == SEND_OUTPUT_BOTH)) {
+ bluetooth_driver.send_nkro(report);
+ if (where_to_send == SEND_OUTPUT_BLUETOOTH) return; // only BT, jump out
+ } else if (where_to_send == SEND_OUTPUT_NONE)
+ return; // dont send to USB either, jump out
+#endif
+
(*driver->send_nkro)(report);
if (debug_keyboard) {
@@ -111,10 +123,12 @@ void host_nkro_send(report_nkro_t *report) {
void host_mouse_send(report_mouse_t *report) {
#ifdef BLUETOOTH_ENABLE
- if (where_to_send() == OUTPUT_BLUETOOTH) {
- bluetooth_send_mouse(report);
- return;
- }
+ send_output_t where_to_send = get_send_output();
+ if ((where_to_send == SEND_OUTPUT_BLUETOOTH) || (where_to_send == SEND_OUTPUT_BOTH)) {
+ bluetooth_driver.send_mouse(report);
+ if (where_to_send == SEND_OUTPUT_BLUETOOTH) return; // only BT, jump out
+ } else if (where_to_send == SEND_OUTPUT_NONE)
+ return; // dont send to USB either, jump out
#endif
if (!driver) return;
@@ -133,6 +147,18 @@ void host_system_send(uint16_t usage) {
if (usage == last_system_usage) return;
last_system_usage = usage;
+#ifdef BLUETOOTH_ENABLE
+ send_output_t where_to_send = get_send_output();
+ if ((where_to_send == SEND_OUTPUT_BLUETOOTH) || (where_to_send == SEND_OUTPUT_BOTH)) {
+ if (NULL != bluetooth_driver.send_system) {
+ bluetooth_driver.send_system(usage);
+ if (where_to_send == SEND_OUTPUT_BLUETOOTH) return; // only BT, jump out
+ } else if (where_to_send == SEND_OUTPUT_BLUETOOTH)
+ return; // only BT, but no `send_system`, jump out
+ } else if (where_to_send == SEND_OUTPUT_NONE)
+ return; // dont send to USB either, jump out
+#endif
+
if (!driver) return;
report_extra_t report = {
@@ -147,10 +173,12 @@ void host_consumer_send(uint16_t usage) {
last_consumer_usage = usage;
#ifdef BLUETOOTH_ENABLE
- if (where_to_send() == OUTPUT_BLUETOOTH) {
- bluetooth_send_consumer(usage);
- return;
- }
+ send_output_t where_to_send = get_send_output();
+ if ((where_to_send == SEND_OUTPUT_BLUETOOTH) || (where_to_send == SEND_OUTPUT_BOTH)) {
+ bluetooth_driver.send_consumer(usage);
+ if (where_to_send == SEND_OUTPUT_BLUETOOTH) return; // only BT, jump out
+ } else if (where_to_send == SEND_OUTPUT_NONE)
+ return; // dont send to USB either, jump out
#endif
if (!driver) return;
From eed3157f182aefb2dae54f96639dfc54f4d5f734 Mon Sep 17 00:00:00 2001
From: Vino Rodrigues <366673+vinorodrigues@users.noreply.github.com>
Date: Sun, 31 Dec 2023 00:10:59 +1100
Subject: [PATCH 3/6] Update bluetooth docs
---
docs/config_options.md | 2 +-
docs/faq_keymap.md | 4 +-
docs/feature_bluetooth.md | 167 +++++++++++++++++++++++++++++++-------
docs/hardware_drivers.md | 4 +
4 files changed, 146 insertions(+), 31 deletions(-)
diff --git a/docs/config_options.md b/docs/config_options.md
index bc28f603faca..bf57c7b0bdf1 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -439,7 +439,7 @@ Use these to enable or disable building certain features. The more you have enab
* `UNICODE_ENABLE`
* Unicode
* `BLUETOOTH_ENABLE`
- * Current options are bluefruit_le, rn42
+ * Enable Bluetooth driver. Also requires `BLUETOOTH_DRIVER`. Set to onr of `bluefruit_le`, `rn42` or `custom`.
* `SPLIT_KEYBOARD`
* Enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common
* `CUSTOM_MATRIX`
diff --git a/docs/faq_keymap.md b/docs/faq_keymap.md
index 864128183508..027b23dc1dd7 100644
--- a/docs/faq_keymap.md
+++ b/docs/faq_keymap.md
@@ -119,9 +119,9 @@ Japanese JIS keyboard specific keys like `無変換(Muhenkan)`, `変換(Henkan)`
https://pqrs.org/osx/karabiner/seil.html
-## RN-42 Bluetooth Doesn't Work with Karabiner
+## RN-42 Bluetooth Doesn't Work with Karabiner on OSX
-Karabiner - Keymapping tool on Mac OSX - ignores inputs from RN-42 module by default. You have to enable this option to make Karabiner working with your keyboard.
+Karabiner - Keymapping tool on Mac OSX - ignores inputs from RN-42 module by default. You have to enable this option to make Karabiner work with your keyboard.
https://github.com/tekezo/Karabiner/issues/403#issuecomment-102559237
See these for the detail of this problem.
diff --git a/docs/feature_bluetooth.md b/docs/feature_bluetooth.md
index 5fac06fba756..a6a8b8bdec73 100644
--- a/docs/feature_bluetooth.md
+++ b/docs/feature_bluetooth.md
@@ -1,46 +1,157 @@
# Bluetooth
-## Bluetooth Known Supported Hardware
+This feature allows you to integrate into a Bluetooth module to create a Bluetooth keyboard for wireless operation.
-Currently Bluetooth support is limited to AVR based chips. For Bluetooth 2.1, QMK has support for RN-42 modules. For more recent BLE protocols, currently only the Adafruit Bluefruit SPI Friend is directly supported. BLE is needed to connect to iOS devices. Note iOS does not support mouse input.
+## Supported Modules
-|Board |Bluetooth Protocol |Connection Type|rules.mk |Bluetooth Chip|
-|----------------------------------------------------------------|--------------------|---------------|---------------------------------|--------------|
-|Roving Networks RN-42 (Sparkfun Bluesmirf) |Bluetooth Classic |UART |`BLUETOOTH_DRIVER = rn42` |RN-42 |
-|[Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633)|Bluetooth Low Energy|SPI |`BLUETOOTH_DRIVER = bluefruit_le`|nRF51822 |
+Currently on the following modules are supported:
-Not Supported Yet but possible:
-* [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479). [Possible tmk implementation found in](https://github.com/tmk/tmk_keyboard/issues/514)
-* HC-05 boards flashed with RN-42 firmware. They apparently both use the CSR BC417 Chip. Flashing it with RN-42 firmware gives it HID capability.
-* Sparkfun Bluetooth Mate
-* HM-13 based boards
+| Board | Module based on | Bluetooth Protocol | Connection Type | rules.mk |Bluetooth Chip |
+|--------------------------------------------------------------------|---------------------|-----------------------------|-----------------|---------------------------------|----------------|
+|[Sparkfun BlueSMiRF Silver](https://www.sparkfun.com/products/12577)|Roving Networks RN-42|Bluetooth 2.1 *"Classic"* |UART |`BLUETOOTH_DRIVER = rn42` |RN421|
+|[Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633) |Raytac MDBT40-256RV3 |Bluettoth 4.1 BLE2|SPI |`BLUETOOTH_DRIVER = bluefruit_le`|nRF51822 |
+
+> 1 RN42 based are modules mostly retired or EOL as the BT2.1 spec is deprecated and withdrawn as of July 2020.
+>
+> 2 BLE is needed to connect to iOS devices.
+
+Not supported yet, but possible:
+
+* [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479).
+* HC-05, HC-06 and HC-08 modules.
+* Modules based on Nordic nRF51*, nRF52* and nRF53* SoC's - however in most cases one will also need to develop firmware for those modules.
+
+> **NOTE:** QMK does not currently support MCU sleep modes, and this may impact the longevity of battery based builds.
+
+## Driver configuration
### Adafruit BLE SPI Friend
-Currently The only bluetooth chipset supported by QMK is the Adafruit Bluefruit SPI Friend. It's a Nordic nRF51822 based chip running Adafruit's custom firmware. Data is transmitted via Adafruit's SDEP over Hardware SPI. The [Feather 32u4 Bluefruit LE](https://www.adafruit.com/product/2829) is supported as it's an AVR mcu connected via SPI to the Nordic BLE chip with Adafruit firmware. If Building a custom board with the SPI friend it would be easiest to just use the pin selection that the 32u4 feather uses but you can change the pins in the config.h options with the following defines:
-* `#define BLUEFRUIT_LE_RST_PIN D4`
-* `#define BLUEFRUIT_LE_CS_PIN B4`
-* `#define BLUEFRUIT_LE_IRQ_PIN E6`
-A Bluefruit UART friend can be converted to an SPI friend, however this [requires](https://github.com/qmk/qmk_firmware/issues/2274) some reflashing and soldering directly to the MDBT40 chip.
+To enable support for the Adafruit Bluefruit LE SPI Friend, add this to your `rules.mk` file:
+
+```make
+NKRO_ENABLE = no # ** Required
+BLUETOOTH_ENABLE = yes
+BLUETOOTH_DRIVER = bluefruit_le
+```
+
+> ** This module does no support [N-Key Rollover (NKRO)](reference_glossary.md#n-key-rollover-nkro);
+
+The Adafruit Bluefruit SPI Friend is a module based on the MDBT30 module, using a Nordic nRF51822 chip, and is flashed with Adafruit's custom firmware that using AT Command sets.
+Data is transmitted via Adafruit's [SDEP](https://learn.adafruit.com/introducing-the-adafruit-bluefruit-spi-breakout/sdep-spi-data-transport) data packets.
+
+#### SPI Configuration
+
+QMK’s `spi_master` must already be correctly configured for the platform you’re building for.
+In addition, you will also need to define the following items in `config.h``:
+
+| Variable | Description | Default |
+|------------------------|-------------------------------------------|---------|
+| `BLUEFRUIT_LE_RST_PIN` | Used to perform a reset on initialization | D4 |
+| `BLUEFRUIT_LE_CS_PIN` | SPI SS/CI "Chip Select" pin | B4 |
+| `BLUEFRUIT_LE_IRQ_PIN` | Module Interrupt Request pin | E6 |
+
+> Defaults are based on the [Adafruit Feather 32u4 Bluefruit](https://learn.adafruit.com/adafruit-feather-32u4-bluefruit-le/overview).
+
+## Keycodes
+
+The following keycodes will allow you change the output selector for the keyboard.
+This allows for switching between USB and Bluetooth on keyboards that support both.
+
+| Key | Aliases | Description |
+|---------------------|---------|----------------------------------------------------------|
+|`QK_OUTPUT_AUTO` |`OU_AUTO`|Automatically switch between USB and Bluetooth *(Default)*|
+|`QK_OUTPUT_USB` |`OU_USB` |USB only |
+|`QK_OUTPUT_BLUETOOTH`|`OU_BT` |Bluetooth only |
+
+## Output Interface Selection
+
+The above keycodes will in turn call the output selector API to direct all key, mouse, consumer, and system output events to the selected interface:
+
+```c
+send_output_t set_send_output(send_output_t send_output);
+send_output_t get_send_output(void);
+```
+
+The *`send_output`* variable should be one of:
+
+```c
+enum send_output_t {
+ SEND_OUTPUT_AUTO, // Selection is USB if USB cable connected, else is Bluetooth is Bluetooth is connected. (Default)
+ SEND_OUTPUT_NONE, // No output is sent.
+ SEND_OUTPUT_USB, // Output is always USB.
+ SEND_OUTPUT_BLUETOOTH, // Output is always Bluetooth.
+ SEND_OUTPUT_BOTH // Output is sent to both USb and Bluetooth (used for testing).
+};
+```
+
+You can change the initial state with the following define in the `config.h` file:
-
-## Bluetooth Rules.mk Options
+```c
+#define SEND_OUTPUT_DEFAULT SEND_OUTPUT_AUTO
+```
-The currently supported Bluetooth chipsets do not support [N-Key Rollover (NKRO)](reference_glossary.md#n-key-rollover-nkro), so `rules.mk` must contain `NKRO_ENABLE = no`.
+Vendor and keymap code can also use the keyboard-level and user-level (to either perform ancillary functions on the setting, or overrode the setting) by creating the following functions in the `kb_name.c` or the `keymap.c` files:
-Add the following to your `rules.mk`:
+```c
+send_output_t set_send_output_kb(send_output_t send_output); // kb-level function usually in the `kb_name.c file`. Should also call `set_send_output_user`.
+send_output_t set_send_output_user(send_output_t send_output); // user-level function usually in `keymap.c` file.
+```
+
+## Bluetooth Driver API
+
+### Custom Bluetooth Driver
+
+You can create your own Bluetooth driver (or for that matter any alternate output interface) with the `bluetooth_driver` variable, and the `bluetooth_driver_t` struct.
+
+Then, to enable a custom Bluetooth driver add this to your `rules.mk` file:
```make
BLUETOOTH_ENABLE = yes
-BLUETOOTH_DRIVER = bluefruit_le # or rn42
+BLUETOOTH_DRIVER = custom
+```
+
+#### Example
+
+You create your own Bluetooth driver by creating compliant functions and referencing these with within the `bluetooth_driver` variable.
+
+In your `kb_name.c` file, create that variable as such:
+
+```c
+const bluetooth_driver_t bluetooth_driver = {
+ .init = xyz_bt_init,
+ .task = xyz_bt_task, // Optional
+ .is_connected = xyz_bt_is_connected, // Optional
+ .send_keyboard = xyz_bt_send_keyboard,
+ .send_mouse = xyz_bt_send_mouse,
+ .send_consumer = xyz_bt_send_consumer,
+ .send_system = xyz_bt_send_system, // Optional
+};
```
-## Bluetooth Keycodes
+> *Optional* items can be set to `NULL`.
+
+Then code for the following functions:
+
+```c
+/* Initialize the Bluetooth system. */
+void xyz_bt_init(void) {}
-This is used when multiple keyboard outputs can be selected. Currently this only allows for switching between USB and Bluetooth on keyboards that support both.
+/* Perform housekeeping tasks. Called every loop. (Optional) */
+void xyz_bt_task(void) {}
-|Key |Aliases |Description |
-|---------------------|---------|----------------------------------------------|
-|`QK_OUTPUT_AUTO` |`OU_AUTO`|Automatically switch between USB and Bluetooth|
-|`QK_OUTPUT_USB` |`OU_USB` |USB only |
-|`QK_OUTPUT_BLUETOOTH`|`OU_BT` |Bluetooth only |
+/* Detects if BT is connected, also used by `SEND_OUTPUT_AUTO`. (Optional) */
+bool xyz_bt_is_connected(void) {}
+
+/* Send a keyboard report. */
+void xyz_bt_send_keyboard(report_keyboard_t *report) {}
+
+/* Send a mouse report. */
+void xyz_bt_send_mouse(report_mouse_t *report) {}
+
+/* Send a consumer usage. */
+void xyz_bt_send_consumer(uint16_t usage) {}
+
+/* Send a system usage. (Optional) */
+void xyz_bt_send_system(uint16_t usage) {}
+```
diff --git a/docs/hardware_drivers.md b/docs/hardware_drivers.md
index a157501326db..f0fb1069948f 100644
--- a/docs/hardware_drivers.md
+++ b/docs/hardware_drivers.md
@@ -33,3 +33,7 @@ Support for up to a single driver with room for expansion. Each driver can contr
## 24xx series external I2C EEPROM
Support for an external I2C-based EEPROM instead of using the on-chip EEPROM. For more information on how to setup the driver see the [EEPROM Driver](eeprom_driver.md) page.
+
+## BlueFruit LE SPI
+
+Support for Bluetooth is provided by the inclusion of the BlueFruit LE SPI module driver. For more information on how to setup the driver see the [Bluetooth](feature_bluetooth.md) page.
From 452e70e32147c542d9f54bd25ee02bc015dc2cfc Mon Sep 17 00:00:00 2001
From: Vino Rodrigues <366673+vinorodrigues@users.noreply.github.com>
Date: Sun, 31 Dec 2023 00:12:00 +1100
Subject: [PATCH 4/6] Update keyboards that used the Bluetooth API
---
keyboards/bioi/bluetooth_custom.c | 11 +++++++++++
.../promethium/keymaps/default/keymap.c | 18 +++++++++---------
keyboards/nek_type_a/matrix.c | 4 ++--
3 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/keyboards/bioi/bluetooth_custom.c b/keyboards/bioi/bluetooth_custom.c
index 4ea277f731a6..ece777d9acfa 100644
--- a/keyboards/bioi/bluetooth_custom.c
+++ b/keyboards/bioi/bluetooth_custom.c
@@ -77,6 +77,8 @@ void bluetooth_init(void) {
void bluetooth_task(void) {}
+bool bluetooth_is_connected(void) { return true; } // lie
+
void bluetooth_send_keyboard(report_keyboard_t *report)
{
#ifdef BLUEFRUIT_TRACE_SERIAL
@@ -161,3 +163,12 @@ void bluetooth_send_consumer(uint16_t usage)
bluefruit_trace_footer();
#endif
}
+
+const bluetooth_driver_t bluetooth_driver = {
+ .init = bluetooth_init,
+ .task = bluetooth_task,
+ .is_connected = bluetooth_is_connected,
+ .send_keyboard = bluetooth_send_keyboard,
+ .send_mouse = bluetooth_send_mouse,
+ .send_consumer = bluetooth_send_consumer,
+};
diff --git a/keyboards/handwired/promethium/keymaps/default/keymap.c b/keyboards/handwired/promethium/keymaps/default/keymap.c
index ff73e51d5eb2..1b6dcbbd145e 100644
--- a/keyboards/handwired/promethium/keymaps/default/keymap.c
+++ b/keyboards/handwired/promethium/keymaps/default/keymap.c
@@ -47,7 +47,7 @@ along with this program. If not, see .
} while (0)
#endif
#endif
-#include "outputselect.h"
+#include "bluetooth.h"
#include "led.h"
#define COUNT(x) ARRAY_SIZE((x))
@@ -1251,13 +1251,13 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return true;
}
-void set_output_user(uint8_t output) {
+void set_send_output_user(send_output_t output) {
#ifdef BLUETOOTH_BLUEFRUIT_LE
- switch(output) {
- case OUTPUT_USB:
+ switch (output) {
+ case SEND_OUTPUT_USB:
led_set_output_usb();
break;
- case OUTPUT_BLUETOOTH:
+ case SEND_OUTPUT_BLUETOOTH:
led_set_output_ble();
break;
default:
@@ -1277,11 +1277,11 @@ void matrix_init_user(void) {
// auto detect output on init
#ifdef BLUETOOTH_BLUEFRUIT_LE
- uint8_t output = auto_detect_output();
- if (output == OUTPUT_USB) {
- set_output(OUTPUT_USB);
+ send_output_t output = get_send_output();
+ if (output == SEND_OUTPUT_USB) {
+ set_send_output(SEND_OUTPUT_USB);
} else {
- set_output(OUTPUT_BLUETOOTH);
+ set_send_output(SEND_OUTPUT_BLUETOOTH);
}
#endif
}
diff --git a/keyboards/nek_type_a/matrix.c b/keyboards/nek_type_a/matrix.c
index 76613947f615..edc5e5c66dee 100644
--- a/keyboards/nek_type_a/matrix.c
+++ b/keyboards/nek_type_a/matrix.c
@@ -34,7 +34,7 @@ along with this program. If not, see .
#include "matrix.h"
#include "timer.h"
#include "mcp23017.h"
-#include "outputselect.h"
+#include "bluetooth.h"
/* Set 0 if debouncing isn't needed */
@@ -136,7 +136,7 @@ void matrix_init(void) {
}
matrix_init_kb();
- set_output(OUTPUT_AUTO);
+ set_send_output(SEND_OUTPUT_AUTO);
}
uint8_t matrix_scan(void)
From a2a8f68a004919ba8536d4fa2e4809dd1f29498c Mon Sep 17 00:00:00 2001
From: Vino Rodrigues <366673+vinorodrigues@users.noreply.github.com>
Date: Sun, 31 Dec 2023 09:37:06 +1100
Subject: [PATCH 5/6] minor fix for handwired/promethium kb
---
keyboards/handwired/promethium/keymaps/default/keymap.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/keyboards/handwired/promethium/keymaps/default/keymap.c b/keyboards/handwired/promethium/keymaps/default/keymap.c
index 1b6dcbbd145e..bf7f14cf0be6 100644
--- a/keyboards/handwired/promethium/keymaps/default/keymap.c
+++ b/keyboards/handwired/promethium/keymaps/default/keymap.c
@@ -1251,7 +1251,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
return true;
}
-void set_send_output_user(send_output_t output) {
+send_output_t set_send_output_user(send_output_t output) {
#ifdef BLUETOOTH_BLUEFRUIT_LE
switch (output) {
case SEND_OUTPUT_USB:
@@ -1264,6 +1264,7 @@ void set_send_output_user(send_output_t output) {
led_set_output_none();
}
#endif
+ return output;
}
void matrix_init_user(void) {
From bf2789060d1b54af79f339c7733246fd6533ecb2 Mon Sep 17 00:00:00 2001
From: Vino Rodrigues <366673+vinorodrigues@users.noreply.github.com>
Date: Sun, 31 Dec 2023 10:02:03 +1100
Subject: [PATCH 6/6] fix typos and grammar
---
docs/config_options.md | 2 +-
docs/feature_bluetooth.md | 18 ++++++++++--------
drivers/bluetooth/bluetooth.c | 7 ++++---
3 files changed, 15 insertions(+), 12 deletions(-)
diff --git a/docs/config_options.md b/docs/config_options.md
index bf57c7b0bdf1..980d0d9c9ac0 100644
--- a/docs/config_options.md
+++ b/docs/config_options.md
@@ -439,7 +439,7 @@ Use these to enable or disable building certain features. The more you have enab
* `UNICODE_ENABLE`
* Unicode
* `BLUETOOTH_ENABLE`
- * Enable Bluetooth driver. Also requires `BLUETOOTH_DRIVER`. Set to onr of `bluefruit_le`, `rn42` or `custom`.
+ * Enable Bluetooth driver. Also requires `BLUETOOTH_DRIVER`. Set to one of `bluefruit_le`, `rn42` or `custom`.
* `SPLIT_KEYBOARD`
* Enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common
* `CUSTOM_MATRIX`
diff --git a/docs/feature_bluetooth.md b/docs/feature_bluetooth.md
index a6a8b8bdec73..cf64b4cff972 100644
--- a/docs/feature_bluetooth.md
+++ b/docs/feature_bluetooth.md
@@ -9,7 +9,7 @@ Currently on the following modules are supported:
| Board | Module based on | Bluetooth Protocol | Connection Type | rules.mk |Bluetooth Chip |
|--------------------------------------------------------------------|---------------------|-----------------------------|-----------------|---------------------------------|----------------|
|[Sparkfun BlueSMiRF Silver](https://www.sparkfun.com/products/12577)|Roving Networks RN-42|Bluetooth 2.1 *"Classic"* |UART |`BLUETOOTH_DRIVER = rn42` |RN421|
-|[Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633) |Raytac MDBT40-256RV3 |Bluettoth 4.1 BLE2|SPI |`BLUETOOTH_DRIVER = bluefruit_le`|nRF51822 |
+|[Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633) |Raytac MDBT40-256RV3 |Bluetooth 4.1 BLE2|SPI |`BLUETOOTH_DRIVER = bluefruit_le`|nRF51822 |
> 1 RN42 based are modules mostly retired or EOL as the BT2.1 spec is deprecated and withdrawn as of July 2020.
>
@@ -35,10 +35,10 @@ BLUETOOTH_ENABLE = yes
BLUETOOTH_DRIVER = bluefruit_le
```
-> ** This module does no support [N-Key Rollover (NKRO)](reference_glossary.md#n-key-rollover-nkro);
+> ** This module does not support [N-Key Rollover (NKRO)](reference_glossary.md#n-key-rollover-nkro);
-The Adafruit Bluefruit SPI Friend is a module based on the MDBT30 module, using a Nordic nRF51822 chip, and is flashed with Adafruit's custom firmware that using AT Command sets.
-Data is transmitted via Adafruit's [SDEP](https://learn.adafruit.com/introducing-the-adafruit-bluefruit-spi-breakout/sdep-spi-data-transport) data packets.
+The Adafruit Bluefruit SPI Friend is a module based on the MDBT30 module with embedded Nordic nRF51822 chip, and is flashed with Adafruit's custom firmware.
+This firmware uses AT Command sets over Adafruit's [SDEP](https://learn.adafruit.com/introducing-the-adafruit-bluefruit-spi-breakout/sdep-spi-data-transport) data transfer protocol.
#### SPI Configuration
@@ -91,7 +91,7 @@ You can change the initial state with the following define in the `config.h` fil
#define SEND_OUTPUT_DEFAULT SEND_OUTPUT_AUTO
```
-Vendor and keymap code can also use the keyboard-level and user-level (to either perform ancillary functions on the setting, or overrode the setting) by creating the following functions in the `kb_name.c` or the `keymap.c` files:
+Vendor and keymap code can also use the keyboard-level and user-level (to either perform ancillary functions on the setting, or override the setting) by creating the following functions in the `kb_name.c` or the `keymap.c` files:
```c
send_output_t set_send_output_kb(send_output_t send_output); // kb-level function usually in the `kb_name.c file`. Should also call `set_send_output_user`.
@@ -102,7 +102,7 @@ send_output_t set_send_output_user(send_output_t send_output); // user-level fun
### Custom Bluetooth Driver
-You can create your own Bluetooth driver (or for that matter any alternate output interface) with the `bluetooth_driver` variable, and the `bluetooth_driver_t` struct.
+You can create your own Bluetooth driver (or for that matter, any alternate output interface) with the `bluetooth_driver` variable, and the `bluetooth_driver_t` struct.
Then, to enable a custom Bluetooth driver add this to your `rules.mk` file:
@@ -113,7 +113,7 @@ BLUETOOTH_DRIVER = custom
#### Example
-You create your own Bluetooth driver by creating compliant functions and referencing these with within the `bluetooth_driver` variable.
+You can create your own Bluetooth driver by creating compliant functions and referencing these with within the `bluetooth_driver` variable.
In your `kb_name.c` file, create that variable as such:
@@ -129,7 +129,9 @@ const bluetooth_driver_t bluetooth_driver = {
};
```
-> *Optional* items can be set to `NULL`.
+> * Members `init`, `send_keyboard`, `send_mouse` and `send_consumer` must be provided.
+> * Members `task`, `is_connected` and `send_system` are optional and may be set to `NULL`.
+
Then code for the following functions:
diff --git a/drivers/bluetooth/bluetooth.c b/drivers/bluetooth/bluetooth.c
index d492baec4c36..77d56a6dc31b 100644
--- a/drivers/bluetooth/bluetooth.c
+++ b/drivers/bluetooth/bluetooth.c
@@ -21,10 +21,11 @@
#include "usb_util.h"
/* Each driver needs to define the struct
- * const rgb_matrix_driver_t rgb_matrix_driver;
- * All members (except `task`, `is_connected` and `send_system`) must be provided.
+ * const bluetooth_driver_t bluetooth_driver;
+ * Members `init`, `send_keyboard`, `send_mouse` and `send_consumer` must be provided.
+ * Members `task`, `is_connected` and `send_system` are optional and may be set to `NULL`.
* Keyboard custom drivers can define this in their own files, it should only
- * be here if shared between boards.
+ * be here if shared between boards on a QMK core driver.
*/
#if defined(BLUETOOTH_BLUEFRUIT_LE)