Skip to content

Commit

Permalink
feat(k2v2rgb): add bluetooth support using iton_bt driver
Browse files Browse the repository at this point in the history
  • Loading branch information
gxcreator committed Nov 5, 2024
1 parent 228e330 commit d722cbc
Show file tree
Hide file tree
Showing 9 changed files with 361 additions and 61 deletions.
249 changes: 249 additions & 0 deletions keyboards/keychron/k2/rgb/v2/ansi/ansi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
/*
Copyright 2024 mintyleaf
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 "quantum.h"
#include "keymap.h"
#ifdef BLUETOOTH_ENABLE
# include "iton_bt.h"
# include "outputselect.h"

static uint32_t last_update_time = 0;

static bool ev_connecting = false;
static bool ev_pairing = false;
static uint32_t ev_disconnected = 0;
static uint32_t ev_connected = 0;
static uint32_t ev_battery_level = 0;

static uint32_t battery_level = 0; // Battery level reported by Iton BT
static uint32_t bt_profile = 0; // Bluetooth profile number

static bool dip_switch_bt_en = false; // Bluetooth ON by BT/OFF/Cable dip switch

void iton_bt_connection_successful() {
set_output(OUTPUT_BLUETOOTH);
ev_connected = 2500;
ev_pairing = false;
ev_connecting = false;
}

void iton_bt_entered_pairing() {
ev_pairing = true;
ev_connected = 0;
ev_connecting = false;
}

void iton_bt_enters_connection_state() {
ev_connecting = true;
ev_connected = 0;
ev_pairing = false;
}

void iton_bt_disconnected() {
set_output(OUTPUT_USB);
ev_disconnected = 2500;
ev_connected = 0;
ev_pairing = false;
ev_connecting = false;
}

void iton_bt_battery_level(uint8_t level) {
battery_level = level;
ev_battery_level = 2500;
}

#endif

/**
* @brief Set the Bluetooth profile
*
* @param profile Bluetooth profile number
*/
static void set_bt_profile(uint8_t profile) {
iton_bt_switch_profile(profile);
bt_profile = profile;
}

bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
#ifdef BLUETOOTH_ENABLE
// Ignore BT commands if BT is disabled
if (dip_switch_bt_en && record->event.pressed) {
switch (keycode) {
case KC_BTPROF0:
set_bt_profile(0);
return false;
case KC_BTPROF1:
set_bt_profile(1);
return false;
case KC_BTPROF2:
set_bt_profile(2);
return false;
case KC_BTPAIR:
if (dip_switch_bt_en) {
iton_bt_enter_pairing();
}
return false;
case KC_BTRST:
if (dip_switch_bt_en) {
iton_bt_reset_pairing();
}
return false;
case KC_BTBATT:
if (dip_switch_bt_en && record->event.pressed) {
ev_battery_level = 10000;
iton_bt_query_battery_level();
}
return false;
}
}
#endif

switch (keycode) {
case KC_MISSION_CONTROL:
if (record->event.pressed) {
host_consumer_send(0x29F);
} else {
host_consumer_send(0);
}
return false;
case KC_LAUNCHPAD:
if (record->event.pressed) {
host_consumer_send(0x2A0);
} else {
host_consumer_send(0);
}
return false;
default:
break;
}
return process_record_user(keycode, record);
}

bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) {
uint8_t layer = get_highest_layer(layer_state);
if (layer != 0 && layer != 2) {
for (uint8_t row = 0; row < MATRIX_ROWS; ++row) {
for (uint8_t col = 0; col < MATRIX_COLS; ++col) {
uint8_t index = g_led_config.matrix_co[row][col];

if (index >= led_min && index < led_max && index != NO_LED && keymap_key_to_keycode(layer, (keypos_t){col, row}) > KC_TRNS) {
rgb_matrix_set_color(index, RGB_WHITE);
}
}
}
}

#ifdef BLUETOOTH_ENABLE
if (!dip_switch_bt_en) {
return true;
}

uint32_t current_time = timer_read(); // Get the current time in milliseconds
uint32_t elapsed;
if (current_time >= last_update_time) {
elapsed = current_time - last_update_time;
} else {
elapsed = 1;
}
last_update_time = current_time;

if (ev_connected > 0) {
uint8_t profile_index = 16 + bt_profile;
if ((current_time / 250) % 2 == 0) {
rgb_matrix_set_color(profile_index, RGB_GREEN);
}
if (elapsed >= ev_connected) {
ev_connected = 0;
} else {
ev_connected -= elapsed;
}
}

if (ev_connecting) {
uint8_t profile_index = 16 + bt_profile;
if ((current_time / 125) % 2 == 0) {
rgb_matrix_set_color(profile_index, RGB_YELLOW);
}
}

if (ev_pairing) {
uint8_t profile_index = 16 + bt_profile;
if ((current_time / 62) % 2 == 0) {
rgb_matrix_set_color(profile_index, RGB_BLUE);
}
}

if (ev_disconnected > 0) {
uint8_t profile_index = 16 + bt_profile;
if ((current_time / 250) % 2 == 0) {
rgb_matrix_set_color(profile_index, RGB_RED);
}
if (elapsed >= ev_disconnected) {
ev_disconnected = 0;
} else {
ev_disconnected -= elapsed;
}
}

if (ev_battery_level > 0) {
if (battery_level == 4) {
rgb_matrix_set_color(49, RGB_GREEN);
} else if (battery_level == 3) {
rgb_matrix_set_color(49, RGB_YELLOW);
} else if (battery_level == 2) {
rgb_matrix_set_color(49, RGB_ORANGE);
} else if (battery_level == 1) {
rgb_matrix_set_color(49, RGB_RED);
} else {
rgb_matrix_set_color(49, RGB_WHITE);
}

if (elapsed >= ev_battery_level) {
ev_battery_level = 0;
battery_level = 0;
} else {
ev_battery_level -= elapsed;
}
}

#endif
return true;
}

bool dip_switch_update_user(uint8_t index, bool active) {
dprintf("DIP #%d: %d\n", index, active);
switch (index) {
case DIP_WIN_MAC:
if (active) {
layer_move(MAC_BASE);
} else {
layer_move(WIN_BASE);
}
return false;
#ifdef BLUETOOTH_ENABLE
case DIP_BT_EN:
dip_switch_bt_en = !active;
if (active) {
set_output(OUTPUT_USB);
} else {
iton_bt_init();
set_output(OUTPUT_NONE);
}
return false;
#endif
}
return true;
}
45 changes: 7 additions & 38 deletions keyboards/keychron/k2/rgb/v2/ansi/keymaps/default/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,9 @@ 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 QMK_KEYBOARD_H
#include "keymap.h"


// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
enum layer_names {
WIN_BASE = 0,
WIN_FN = 1,
MAC_BASE = 2,
MAC_FN = 3,
};
#define KC_TASK LGUI(KC_TAB) // Task viewer
#define KC_FLXP LGUI(KC_E) // Windows file explorer

Expand Down Expand Up @@ -81,11 +73,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[WIN_FN] = LAYOUT_ansi(
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
Q_RESET, KC_BRID, KC_BRIU, KC_TASK, KC_FLXP, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, _______, KC_INS, RGB_TOG ,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ,
QK_BOOT, KC_BRID, KC_BRIU, KC_TASK, KC_FLXP, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, _______, KC_INS, RGB_TOG ,
KC_BTPAIR, KC_BTPROF0, KC_BTPROF1, KC_BTPROF2, _______, _______, _______, _______, _______, _______, _______, KC_BTRST, _______, _______, _______ ,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAI, _______ ,
_______, _______, _______, _______, _______, KC_BTBATT, _______, _______, _______, _______, _______, _______, RGB_SAI, _______ ,
_______, _______, _______, _______, _______, _______, _______, RGB_HUD, RGB_SAD, RGB_HUI
),

Expand Down Expand Up @@ -131,38 +123,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
*/
[MAC_FN] = LAYOUT_ansi(
/* 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 */
Q_RESET, KC_BRID, KC_BRIU, KC_MSSN, KC_FIND, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_MSNP, KC_INS, RGB_TOG ,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ,
QK_BOOT, KC_BRID, KC_BRIU, KC_MSSN, KC_FIND, RGB_VAD, RGB_VAI, KC_MPRV, KC_MPLY, KC_MNXT, KC_MUTE, KC_VOLD, KC_VOLU, KC_MSNP, KC_INS, RGB_TOG ,
KC_BTPAIR, KC_BTPROF0, KC_BTPROF1, KC_BTPROF2, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, RGB_SAI, _______ ,
_______, _______, _______, _______, _______, _______, _______, RGB_HUD, RGB_SAD, RGB_HUI
)
};

bool dip_switch_update_user(uint8_t index, bool active) {
switch(index) {
case 0: // OS switch
if (active) { // Mac/iOS mode
layer_move(MAC_BASE);
}
else { // Windows/Android mode
layer_move(WIN_BASE);
}
break;
case 1: // Connection switch
// Probably it's not possible to do anything sensible here as switching from Cable to BT requires turning off the board. (BT / OFF / Cable)
if (active) { // BT mode
// do stuff
}
else { //Cable mode
// do stuff
}
break;
}
return true;
}

void keyboard_post_init_user(void) {
// Customise these values to desired behaviour
// debug_enable = true;
Expand Down
41 changes: 41 additions & 0 deletions keyboards/keychron/k2/rgb/v2/ansi/keymaps/default/keymap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
Copyright 2024 mintyleaf
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 QMK_KEYBOARD_H

/* Extended keycodes for controlling Bluetooth */
enum BT_keycodes {
KC_BTPROF0 = SAFE_RANGE, // Set bluetooth profile 0
KC_BTPROF1, // Set bluetooth profile 1
KC_BTPROF2, // Set bluetooth profile 2
KC_BTPAIR, // Start pairing mode
KC_BTTOGL, // Toggle bluetooth mode
KC_BTRST, // Reset bluetooth module
KC_BTBATT, // Show battery level
K2_SAFE_RANGE
};

enum layer_names {
WIN_BASE = 0, // Windows base layer
WIN_FN = 1, // Windows with FN key
MAC_BASE = 2, // Mac base layer
MAC_FN = 3, // Mac with FN key
};

#define KC_TASK LGUI(KC_TAB) // Task viewer
#define KC_FLXP LGUI(KC_E) // Windows file explorer
#define KC_MCTL KC_MISSION_CONTROL // Mission Control
#define KC_LPAD KC_LAUNCHPAD // Launchpad
23 changes: 0 additions & 23 deletions keyboards/keychron/k2/rgb/v2/ansi/keymaps/via/keymap.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,29 +140,6 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
)
};

bool dip_switch_update_user(uint8_t index, bool active) {
switch(index) {
case 0: // OS switch
if (active) { // Mac/iOS mode
layer_move(MAC_BASE);
}
else { // Windows/Android mode
layer_move(WIN_BASE);
}
break;
case 1: // Connection switch
// Probably it's not possible to do anything sensible here as switching from Cable to BT requires turning off the board. (BT / OFF / Cable)
if (active) { // BT mode
// do stuff
}
else { //Cable mode
// do stuff
}
break;
}
return true;
}

void keyboard_post_init_user(void) {
// Customise these values to desired behaviour
// debug_enable = true;
Expand Down
Loading

0 comments on commit d722cbc

Please sign in to comment.