From ab8c5013c856bfa23289d7892be1c2bee808b542 Mon Sep 17 00:00:00 2001
From: Ryan <fauxpark@gmail.com>
Date: Sat, 20 May 2023 22:12:59 +1000
Subject: [PATCH] BIOI G60/Morgan65: use custom Bluetooth driver (#20897)

---
 builddefs/common_features.mk     |   4 +-
 data/schemas/keyboard.jsonschema |   2 +-
 keyboards/bioi/ble.c             |  87 ++-----
 keyboards/bioi/ble.h             |   6 -
 keyboards/bioi/g60/rules.mk      |  15 +-
 keyboards/bioi/main.c            | 388 -------------------------------
 keyboards/bioi/morgan65/rules.mk |  15 +-
 7 files changed, 43 insertions(+), 474 deletions(-)
 delete mode 100644 keyboards/bioi/main.c

diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk
index 61dffb2713..e904d6beb9 100644
--- a/builddefs/common_features.mk
+++ b/builddefs/common_features.mk
@@ -906,10 +906,11 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
     OPT_DEFS += -DBLUETOOTH_ENABLE
     NO_USB_STARTUP_CHECK := yes
     COMMON_VPATH += $(DRIVER_PATH)/bluetooth
-    SRC += outputselect.c bluetooth.c
+    SRC += outputselect.c
 
     ifeq ($(strip $(BLUETOOTH_DRIVER)), BluefruitLE)
         OPT_DEFS += -DBLUETOOTH_BLUEFRUIT_LE -DHAL_USE_SPI=TRUE
+        SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
         SRC += $(DRIVER_PATH)/bluetooth/bluefruit_le.cpp
         QUANTUM_LIB_SRC += analog.c
         QUANTUM_LIB_SRC += spi_master.c
@@ -917,6 +918,7 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes)
 
     ifeq ($(strip $(BLUETOOTH_DRIVER)), RN42)
         OPT_DEFS += -DBLUETOOTH_RN42 -DHAL_USE_SERIAL=TRUE
+        SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c
         SRC += $(DRIVER_PATH)/bluetooth/rn42.c
         QUANTUM_LIB_SRC += uart.c
     endif
diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema
index d608e8f796..ba4a7eec55 100644
--- a/data/schemas/keyboard.jsonschema
+++ b/data/schemas/keyboard.jsonschema
@@ -146,7 +146,7 @@
             "properties": {
                 "driver": {
                     "type": "string",
-                    "enum": ["BluefruitLE", "RN42"]
+                    "enum": ["BluefruitLE", "RN42", "custom"]
                 }
             }
         },
diff --git a/keyboards/bioi/ble.c b/keyboards/bioi/ble.c
index 7118cef8c6..12c180966a 100644
--- a/keyboards/bioi/ble.c
+++ b/keyboards/bioi/ble.c
@@ -12,35 +12,17 @@ You should have received a copy of the GNU General Public License
 along with this program. If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include <avr/pgmspace.h>
-#include "report.h"
-#include "host.h"
-#include "host_driver.h"
-#include "keyboard.h"
-#include "action.h"
-#include "led.h"
-
-#include "sendchar.h"
-#include "debug.h"
-#ifdef SLEEP_LED_ENABLE
-#include "sleep_led.h"
-#endif
-#include "suspend.h"
-
-#include "usb_descriptor.h"
-#include "lufa.h"
-#include "quantum.h"
-#include <util/atomic.h>
-
-#include "print.h"
-
+#include "bluetooth.h"
 #include "ble.h"
 #include "usart.h"
+#include "progmem.h"
+#include "wait.h"
+#include "debug.h"
+#include "usb_descriptor.h"
+#include "report.h"
 
 keyboard_config_t ble_config;
 
-static uint8_t bluefruit_keyboard_leds = 0;
-
 static void bluefruit_serial_send(uint8_t);
 
 void send_str(const char *str)
@@ -89,30 +71,13 @@ static void bluefruit_serial_send(uint8_t data)
     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_extra(report_extra_t *report);
-
-host_driver_t bluefruit_driver = {
-    keyboard_leds,
-    send_keyboard,
-    send_mouse,
-    send_extra
-};
-
-host_driver_t null_driver = {};
-
-static uint8_t keyboard_leds(void)
-{
-    return bluefruit_keyboard_leds;
+void bluetooth_init(void) {
+    usart_init();
 }
 
-static void send_keyboard(report_keyboard_t *report)
+void bluetooth_task(void) {}
+
+void bluetooth_send_keyboard(report_keyboard_t *report)
 {
 #ifdef BLUEFRUIT_TRACE_SERIAL
     bluefruit_trace_header();
@@ -136,7 +101,7 @@ static void send_keyboard(report_keyboard_t *report)
 #endif
 }
 
-static void send_mouse(report_mouse_t *report)
+void bluetooth_send_mouse(report_mouse_t *report)
 {
 #ifdef BLUEFRUIT_TRACE_SERIAL
     bluefruit_trace_header();
@@ -177,27 +142,25 @@ static void send_mouse(report_mouse_t *report)
 #define CONSUMER2BLUEFRUIT(usage) \
     (usage == AUDIO_MUTE ? 0x00e2 : (usage == AUDIO_VOL_UP ? 0x00e9 : (usage == AUDIO_VOL_DOWN ? 0x00ea : (usage == TRANSPORT_NEXT_TRACK ? 0x00b5 : (usage == TRANSPORT_PREV_TRACK ? 0x00b6 : (usage == TRANSPORT_STOP ? 0x00b7 : (usage == TRANSPORT_STOP_EJECT ? 0x00b8 : (usage == TRANSPORT_PLAY_PAUSE ? 0x00b1 : (usage == AL_CC_CONFIG ? 0x0183 : (usage == AL_EMAIL ? 0x018c : (usage == AL_CALCULATOR ? 0x0192 : (usage == AL_LOCAL_BROWSER ? 0x0196 : (usage == AC_SEARCH ? 0x021f : (usage == AC_HOME ? 0x0223 : (usage == AC_BACK ? 0x0224 : (usage == AC_FORWARD ? 0x0225 : (usage == AC_STOP ? 0x0226 : (usage == AC_REFRESH ? 0x0227 : (usage == AC_BOOKMARKS ? 0x022a : 0)))))))))))))))))))
 
-static void send_extra(report_extra_t *report)
+void bluetooth_send_consumer(uint16_t usage)
 {
-    if (report->report_id == REPORT_ID_CONSUMER) {
-        uint16_t bitmap = CONSUMER2BLUEFRUIT(report->usage);
+    uint16_t bitmap = CONSUMER2BLUEFRUIT(usage);
 
 #ifdef BLUEFRUIT_TRACE_SERIAL
-        dprintf("\nData: ");
-        debug_hex16(data);
-        dprintf("; bitmap: ");
-        debug_hex16(bitmap);
-        dprintf("\n");
-        bluefruit_trace_header();
+    dprintf("\nData: ");
+    debug_hex16(data);
+    dprintf("; bitmap: ");
+    debug_hex16(bitmap);
+    dprintf("\n");
+    bluefruit_trace_header();
 #endif
-        send_str(PSTR("AT+BLEHIDCONTROLKEY=0x"));
-        send_bytes((bitmap >> 8) & 0xFF);
-        send_bytes(bitmap & 0xFF);
-        send_str(PSTR("\r\n"));
+    send_str(PSTR("AT+BLEHIDCONTROLKEY=0x"));
+    send_bytes((bitmap >> 8) & 0xFF);
+    send_bytes(bitmap & 0xFF);
+    send_str(PSTR("\r\n"));
 #ifdef BLUEFRUIT_TRACE_SERIAL
-        bluefruit_trace_footer();
+    bluefruit_trace_footer();
 #endif
-    }
 }
 
 void usart_init(void)
diff --git a/keyboards/bioi/ble.h b/keyboards/bioi/ble.h
index 9167a09728..529ebf5241 100644
--- a/keyboards/bioi/ble.h
+++ b/keyboards/bioi/ble.h
@@ -15,9 +15,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
 #pragma once
 
 #include <stdbool.h>
-#include "host_driver.h"
-#include "host.h"
-
 
 typedef union {
   uint32_t raw;
@@ -28,9 +25,6 @@ typedef union {
 
 extern keyboard_config_t ble_config;
 
-extern host_driver_t bluefruit_driver;
-extern host_driver_t null_driver;
-
 void send_str(const char *str);
 void usart_init(void);
 void module_reset(void);
diff --git a/keyboards/bioi/g60/rules.mk b/keyboards/bioi/g60/rules.mk
index d6c97aa974..a22a56ecec 100644
--- a/keyboards/bioi/g60/rules.mk
+++ b/keyboards/bioi/g60/rules.mk
@@ -1,14 +1,6 @@
 # Processor frequency
 F_CPU = 8000000
 
-SRC += usart.c \
-       ble.c \
-       main.c
-
-OPT_DEFS += -DPROTOCOL_BLE
-OPT_DEFS += -DUART_RX1_BUFFER_SIZE=16 -DUART_TX1_BUFFER_SIZE=16
-OPT_DEFS += -DUSART1_ENABLED
-
 # Build Options
 #   change yes to no to disable
 #
@@ -22,5 +14,12 @@ BACKLIGHT_ENABLE = yes      # Enable keyboard backlight functionality
 RGBLIGHT_ENABLE = yes       # Enable keyboard RGB underglow
 AUDIO_ENABLE = no           # Audio output
 LTO_ENABLE = yes            # Reduce firmware size
+BLUETOOTH_ENABLE = yes
+BLUETOOTH_DRIVER = custom
 
 VIA_ENABLE = yes            # VIA support should be enabled here due to the main() loop will be compiled first.
+
+SRC += usart.c ble.c
+
+OPT_DEFS += -DUART_RX1_BUFFER_SIZE=16 -DUART_TX1_BUFFER_SIZE=16
+OPT_DEFS += -DUSART1_ENABLED
diff --git a/keyboards/bioi/main.c b/keyboards/bioi/main.c
deleted file mode 100644
index eb149eb7cd..0000000000
--- a/keyboards/bioi/main.c
+++ /dev/null
@@ -1,388 +0,0 @@
-/*
-Copyright 2019 Basic I/O Instruments(Scott Wei) <scot.wei@gmail.com>
-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 <http://www.gnu.org/licenses/>.
-*/
-
-#include <avr/pgmspace.h>
-#include <util/delay.h>
-
-#include "report.h"
-#include "host.h"
-#include "host_driver.h"
-#include "keyboard.h"
-#include "action.h"
-#include "led.h"
-#include "sendchar.h"
-#include "debug.h"
-#include "print.h"
-#ifdef SLEEP_LED_ENABLE
-#include "sleep_led.h"
-#endif
-#include "suspend.h"
-
-#include "usb_descriptor.h"
-#include "lufa.h"
-#include "quantum.h"
-#include <util/atomic.h>
-
-#ifdef NKRO_ENABLE
-#include "keycode_config.h"
-
-extern keymap_config_t keymap_config;
-#endif
-
-#ifdef AUDIO_ENABLE
-#include <audio.h>
-#endif
-
-#ifdef BLUETOOTH_ENABLE
-#ifdef BLUETOOTH_BLUEFRUIT_LE
-#include "bluefruit_le.h"
-#else
-#include "bluetooth.h"
-#endif
-#endif
-
-#ifdef VIRTSER_ENABLE
-#include "virtser.h"
-#endif
-
-#if defined(RGBLIGHT_ENABLE)
-#include "rgblight.h"
-#endif
-
-#ifdef MIDI_ENABLE
-#include "qmk_midi.h"
-#endif
-
-#ifdef RAW_ENABLE
-#include "raw_hid.h"
-#endif
-
-#include "ble.h"
-#include "usart.h"
-
-#include <avr/power.h>
-#include <avr/sleep.h>
-
-bool force_usb = false; //Reserved for FORCE USB Mode function.
-bool force_ble = false; //Reserved for FORCE USB Mode function.
-
-bool usb_connected = false;
-bool ble_enabled = false;
-
-uint32_t kb_idle_timer = 0;
-
-bool usb_state_sent = false;
-
-uint8_t USB_DeviceLastState = 0;
-
-#ifdef RAW_ENABLE
-/** \brief Raw HID Task
- *
- * FIXME: Needs doc
- */
-static void raw_hid_task(void)
-{
-    // Create a temporary buffer to hold the read in data from the host
-    uint8_t data[RAW_EPSIZE];
-    bool data_read = false;
-
-    // Device must be connected and configured for the task to run
-    if (USB_DeviceState != DEVICE_STATE_Configured)
-        return;
-
-    Endpoint_SelectEndpoint(RAW_OUT_EPNUM);
-
-    // Check to see if a packet has been sent from the host
-    if (Endpoint_IsOUTReceived())
-    {
-        // Check to see if the packet contains data
-        if (Endpoint_IsReadWriteAllowed())
-        {
-            /* Read data */
-            Endpoint_Read_Stream_LE(data, sizeof(data), NULL);
-            data_read = true;
-        }
-
-        // Finalize the stream transfer to receive the last packet
-        Endpoint_ClearOUT();
-
-        if (data_read)
-        {
-            raw_hid_receive(data, sizeof(data));
-        }
-    }
-}
-#endif
-
-static void setup_mcu(void)
-{
-    /* Disable watchdog if enabled by bootloader/fuses */
-    MCUSR &= ~(1 << WDRF);
-    wdt_disable();
-
-    CLKPR = (1 << CLKPCE);
-    CLKPR = (0 << CLKPS3) | (0 << CLKPS2) | (0 << CLKPS1) | (0 << CLKPS0);
-}
-
-static void setup_usb(void)
-{
-    // Leonardo needs. Without this USB device is not recognized.
-    USB_Disable();
-
-    USB_Init();
-
-    // for Console_Task
-    USB_Device_EnableSOFEvents();
-    print_set_sendchar(sendchar);
-}
-
-void power_saving(void)
-{
-    power_adc_disable();
-    power_usart0_disable();
-    power_spi_disable();
-    power_twi_disable();
-
-    USBCON |= (1 << FRZCLK); // Freeze the USB Clock
-    PLLCSR &= ~(1 << PLLE);  // Disable the USB Clock (PPL)
-    USBCON &= ~(1 << USBE);
-}
-
-void power_recover(void)
-{
-
-    USBCON |= (1 << USBE);
-    PLLCSR |= (1 << PLLE);    // Resume the USB Clock (PPL)
-    USBCON &= ~(1 << FRZCLK); // Resume the USB Clock
-
-    power_adc_enable();
-    power_usart0_enable();
-    power_spi_enable();
-    power_twi_enable();
-}
-
-void ble_task_init(void)
-{
-    kb_idle_timer = timer_read32();  //Mark current time, reserved for further usage;
-}
-
-void ble_task(void)
-{
-
-    if (USB_DeviceLastState != USB_DeviceState)
-    {
-        usb_state_sent = false;
-#ifdef BLE_DEBUG
-        send_str(PSTR("USB State Changed\r\n"));
-        if (USB_DeviceState == DEVICE_STATE_Unattached)
-        {
-            send_str(PSTR("USB State Unattached\r\n"));
-        }
-#endif
-        if (USB_DeviceState == DEVICE_STATE_Powered)
-        {
-#ifdef BLE_DEBUG
-            send_str(PSTR("USB State Powered\r\n"));
-#endif
-            power_recover();
-            host_set_driver(&null_driver);
-        }
-#ifdef BLE_DEBUG
-        if ((USB_DeviceState == DEVICE_STATE_Default))
-        {
-            send_str(PSTR("USB State Default\r\n"));
-        }
-        if ((USB_DeviceState == DEVICE_STATE_Addressed))
-        {
-            send_str(PSTR("USB State Addressed\r\n"));
-        }
-        if (USB_DeviceState == DEVICE_STATE_Configured)
-        {
-            send_str(PSTR("USB State Configured\r\n"));
-        }
-        if (USB_DeviceState > DEVICE_STATE_Unattached)
-        {
-        }
-        else
-        {
-            //
-        }
-#endif
-    }
-    else
-    {
-#ifdef BLE_DEBUG
-        if (!usb_state_sent)
-        {
-            if (USB_DeviceState == DEVICE_STATE_Unattached)
-            {
-                send_str(PSTR("USB State Stopped at Unattached\r\n"));
-            }
-            if (USB_DeviceState == DEVICE_STATE_Powered)
-            {
-                send_str(PSTR("USB State Stopped at Powered\r\n"));
-            }
-            if ((USB_DeviceState == DEVICE_STATE_Default))
-            {
-                send_str(PSTR("USB State Stopped at Default\r\n"));
-            }
-            if ((USB_DeviceState == DEVICE_STATE_Addressed))
-            {
-                send_str(PSTR("USB State Stopped at Addressed\r\n"));
-            }
-            if (USB_DeviceState == DEVICE_STATE_Configured)
-            {
-                send_str(PSTR("USB State Stopped at Configured\r\n"));
-            }
-        }
-#endif
-        if (USB_DeviceState == DEVICE_STATE_Unattached)
-        {
-            if (host_get_driver() && host_get_driver() != &bluefruit_driver)
-            {
-#ifdef BLE_DEBUG
-                send_str(PSTR("USB State stopped at Unattached\r\n"));
-#endif
-                ble_task_init();
-
-                force_usb = 0;
-                usb_connected = 0;
-
-                //Reinit USB to prepare for next connection.
-                USB_Init();
-                USB_Detach();
-                USB_Attach();
-
-#ifdef BLE_DEBUG
-                send_str(PSTR("Loading &bluefruit_driver\r\n"));
-#endif
-                host_set_driver(&bluefruit_driver);
-                clear_keyboard();
-                power_saving();
-            }
-            else
-            {
-                //Do nothing if USB is unattached and the driver is &bluefruit_driver
-            }
-        }
-        if (USB_DeviceState == DEVICE_STATE_Configured)
-        {
-            if (host_get_driver() && host_get_driver() != &lufa_driver)
-            {
-#ifdef BLE_DEBUG
-                send_str(PSTR("USB State stopped at Configured\r\n"));
-#endif
-                power_recover();
-
-                usb_connected = 1;
-                ble_enabled = 0;
-#ifdef BLE_DEBUG
-                send_str(PSTR("Loading &lufa_driver\r\n"));
-#endif
-                host_set_driver(&lufa_driver);
-                clear_keyboard();
-            }
-            else
-            {
-                //Do nothing if the driver is &lufa_driver
-            }
-        }
-
-        usb_state_sent = true;
-    }
-
-    USB_DeviceLastState = USB_DeviceState;
-}
-
-// Use a custom main() function because the task logic is different from the common one.
-int main(void)
-{
-#ifdef MIDI_ENABLE
-    setup_midi();
-#endif
-
-    setup_mcu();
-
-    keyboard_setup();
-
-    setup_usb();
-    sei();
-
-#if defined(BLUETOOTH_RN42)
-    serial_init();
-#endif
-
-    /* wait for USB startup to get ready for debug output */
-    uint8_t timeout = 255; // timeout when USB is not available(Bluetooth)
-    while (timeout-- && USB_DeviceState != DEVICE_STATE_Configured)
-    {
-        wait_ms(4);
-#if defined(INTERRUPT_CONTROL_ENDPOINT)
-        ;
-#else
-        USB_USBTask();
-#endif
-    }
-
-    print("\nUSB init\n");
-
-    keyboard_init();
-    host_set_driver(&lufa_driver);
-
-    backlight_disable();
-    //host_set_driver(&lufa_driver);
-    print("Keyboard initialized.\n");
-
-    //Init Hardware UART
-    usart_init();
-
-#ifdef BLE_DEBUG
-    send_str(PSTR("Keyboard has been setup up\r\n"));
-
-    if (usb_connected)
-    {
-        send_str(PSTR("usb_connected=1\r\n"));
-    }
-    else
-    {
-        send_str(PSTR("usb_connected=0\r\n"));
-    }
-#endif
-
-#ifdef SLEEP_LED_ENABLE
-    sleep_led_init();
-#endif
-
-#ifdef VIRTSER_ENABLE
-    virtser_init();
-#endif
-
-    while (1)
-    {
-        ble_task();
-        keyboard_task();
-
-#ifdef RAW_ENABLE
-        raw_hid_task();
-#endif
-
-#if defined(RGBLIGHT_ENABLE)
-        rgblight_task();
-#endif
-
-#if !defined(INTERRUPT_CONTROL_ENDPOINT)
-        USB_USBTask();
-#endif
-    }
-}
diff --git a/keyboards/bioi/morgan65/rules.mk b/keyboards/bioi/morgan65/rules.mk
index d6c97aa974..a22a56ecec 100644
--- a/keyboards/bioi/morgan65/rules.mk
+++ b/keyboards/bioi/morgan65/rules.mk
@@ -1,14 +1,6 @@
 # Processor frequency
 F_CPU = 8000000
 
-SRC += usart.c \
-       ble.c \
-       main.c
-
-OPT_DEFS += -DPROTOCOL_BLE
-OPT_DEFS += -DUART_RX1_BUFFER_SIZE=16 -DUART_TX1_BUFFER_SIZE=16
-OPT_DEFS += -DUSART1_ENABLED
-
 # Build Options
 #   change yes to no to disable
 #
@@ -22,5 +14,12 @@ BACKLIGHT_ENABLE = yes      # Enable keyboard backlight functionality
 RGBLIGHT_ENABLE = yes       # Enable keyboard RGB underglow
 AUDIO_ENABLE = no           # Audio output
 LTO_ENABLE = yes            # Reduce firmware size
+BLUETOOTH_ENABLE = yes
+BLUETOOTH_DRIVER = custom
 
 VIA_ENABLE = yes            # VIA support should be enabled here due to the main() loop will be compiled first.
+
+SRC += usart.c ble.c
+
+OPT_DEFS += -DUART_RX1_BUFFER_SIZE=16 -DUART_TX1_BUFFER_SIZE=16
+OPT_DEFS += -DUSART1_ENABLED