diff --git a/builddefs/common_features.mk b/builddefs/common_features.mk index 0734f70f47ca..00c8b4a4a291 100644 --- a/builddefs/common_features.mk +++ b/builddefs/common_features.mk @@ -879,7 +879,7 @@ ifeq ($(strip $(USBPD_ENABLE)), yes) endif BLUETOOTH_ENABLE ?= no -VALID_BLUETOOTH_DRIVER_TYPES := bluefruit_le custom rn42 +VALID_BLUETOOTH_DRIVER_TYPES := bluefruit_le custom rn42 iton_bt ifeq ($(strip $(BLUETOOTH_ENABLE)), yes) ifeq ($(filter $(strip $(BLUETOOTH_DRIVER)),$(VALID_BLUETOOTH_DRIVER_TYPES)),) $(call CATASTROPHIC_ERROR,Invalid BLUETOOTH_DRIVER,BLUETOOTH_DRIVER="$(BLUETOOTH_DRIVER)" is not a valid Bluetooth driver type) @@ -902,6 +902,11 @@ ifeq ($(strip $(BLUETOOTH_ENABLE)), yes) SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c SRC += $(DRIVER_PATH)/bluetooth/rn42.c endif + + ifeq ($(strip $(BLUETOOTH_DRIVER)), iton_bt) + SRC += $(DRIVER_PATH)/bluetooth/bluetooth.c + SRC += $(DRIVER_PATH)/bluetooth/iton_bt.c + endif endif ENCODER_ENABLE ?= no diff --git a/data/schemas/keyboard.jsonschema b/data/schemas/keyboard.jsonschema index 769786f2b5aa..9990330e9112 100644 --- a/data/schemas/keyboard.jsonschema +++ b/data/schemas/keyboard.jsonschema @@ -190,7 +190,7 @@ "properties": { "driver": { "type": "string", - "enum": ["bluefruit_le", "custom", "rn42"] + "enum": ["bluefruit_le", "custom", "rn42", "iton_bt"] } } }, diff --git a/drivers/bluetooth/bluetooth.c b/drivers/bluetooth/bluetooth.c index d5382401e7e5..abb20d144881 100644 --- a/drivers/bluetooth/bluetooth.c +++ b/drivers/bluetooth/bluetooth.c @@ -21,6 +21,8 @@ # include "bluefruit_le.h" #elif defined(BLUETOOTH_RN42) # include "rn42.h" +#elif defined(BLUETOOTH_ITON_BT) +# include "iton_bt.h" #endif void bluetooth_init(void) { @@ -28,6 +30,8 @@ void bluetooth_init(void) { bluefruit_le_init(); #elif defined(BLUETOOTH_RN42) rn42_init(); +#elif defined(BLUETOOTH_ITON_BT) + iton_bt_init(); #endif } @@ -42,6 +46,8 @@ void bluetooth_send_keyboard(report_keyboard_t *report) { bluefruit_le_send_keyboard(report); #elif defined(BLUETOOTH_RN42) rn42_send_keyboard(report); +#elif defined(BLUETOOTH_ITON_BT) + iton_bt_send_keyboard(report); #endif } @@ -58,5 +64,7 @@ void bluetooth_send_consumer(uint16_t usage) { bluefruit_le_send_consumer(usage); #elif defined(BLUETOOTH_RN42) rn42_send_consumer(usage); +#elif defined(BLUETOOTH_ITON_BT) + iton_bt_send_consumer(usage); #endif } diff --git a/drivers/bluetooth/iton_bt.c b/drivers/bluetooth/iton_bt.c new file mode 100644 index 000000000000..3a6fcbb930a0 --- /dev/null +++ b/drivers/bluetooth/iton_bt.c @@ -0,0 +1,245 @@ +// Copyright 2023 1Conan (@1Conan) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include "gpio.h" +#include "config.h" +#include "iton_bt.h" + +#ifndef ITON_BT_SPI_PORT +# define ITON_BT_SPI_PORT SPID0 +#endif + +#ifndef ITON_BT_IRQ_LINE +# define ITON_BT_IRQ_LINE A0 +#endif + +#ifndef ITON_BT_INT_LINE +# define ITON_BT_INT_LINE A1 +#endif + +#ifndef ITON_BT_BUFFER_LEN +# define ITON_BT_BUFFER_LEN 16 +#endif + +/** + * Driver Macros + */ +#define HIGH_BITS(x) ((uint8_t)(x >> 8)) +#define LOW_BITS(x) ((uint8_t)(x & 0x00FF)) + +/** + * Function definitions + */ +void iton_bt_data_cb(SPIDriver *spip); + +/** + * Callbacks + */ +__attribute__((weak)) void iton_bt_battery_voltage_low(void) {} +__attribute__((weak)) void iton_bt_battery_exit_low_battery_mode(void) {} +__attribute__((weak)) void iton_bt_battery_low_power_shutdown(void) {} +__attribute__((weak)) void iton_bt_battery_level(uint8_t level) {} + +__attribute__((weak)) void iton_bt_connection_successful(void) {} +__attribute__((weak)) void iton_bt_entered_pairing(void) {} +__attribute__((weak)) void iton_bt_disconnected(void) {} +__attribute__((weak)) void iton_bt_enters_connection_state(void) {} + +/** + * Driver variables + */ +bool iton_bt_is_connected = false; +uint8_t iton_bt_led_state = 0x00; + +static uint8_t iton_bt_buffer[ITON_BT_BUFFER_LEN]; +uint8_t iton_bt_send_kb_last_key = 0x00; + +const SPIConfig iton_bt_spicfg = { + .slave = true, + .data_cb = iton_bt_data_cb, +#if defined(SN32) + .ctrl0 = SPI_DATA_LENGTH(8), +#endif +}; + +/** + * Callbacks + */ +#if defined(PAL_USE_CALLBACKS) || defined(PAL_USE_WAIT) +static inline void iton_bt_rx_battery_notif(uint8_t data) { + switch (data) { + case batt_voltage_low: + iton_bt_battery_voltage_low(); + break; + case batt_exit_low_battery_mode: + iton_bt_battery_exit_low_battery_mode(); + break; + case batt_low_power_shutdown: + iton_bt_battery_low_power_shutdown(); + break; + case batt_above_70: + case batt_between_30_70: + case batt_below_30: + iton_bt_battery_level(data); + break; + case batt_wake_mcu: + #ifdef ITON_BT_ENABLE_ACK + iton_bt_send_ack(control_bt, wake_ack); + #endif + break; + case batt_unknown: + #ifdef ITON_BT_ENABLE_ACK + iton_bt_send_ack(control_bt, unknown_ack); + #endif + break; + case query_working_mode: + break; + case query_bt_name: + break; + } +} + +static inline void iton_bt_rx_bluetooth_notif(uint8_t data) { + switch (iton_bt_buffer[2]) { + case bt_connection_success: + iton_bt_is_connected = true; + + #ifdef ITON_BT_ENABLE_ACK + iton_bt_send_ack(control_bt, connect_ack); + #endif + + iton_bt_connection_successful(); + break; + case bt_entered_pairing: + iton_bt_entered_pairing(); + break; + case bt_disconected: + iton_bt_is_connected = false; + + #ifdef ITON_BT_ENABLE_ACK + iton_bt_send_ack(control_bt, disconnect_ack); + #endif + + iton_bt_disconnected(); + break; + case bt_enters_connection: + iton_bt_enters_connection_state(); + break; + } +} + +static void iton_bt_rx_cb(void *arg) { + if (readPin(ITON_BT_INT_LINE)) { + chSysLockFromISR(); + spiStartReceiveI(&ITON_BT_SPI_PORT, ITON_BT_BUFFER_LEN, &iton_bt_buffer[0]); + chSysUnlockFromISR(); + } else { + chSysLockFromISR(); + spiStopTransferI(&ITON_BT_SPI_PORT, NULL); + chSysUnlockFromISR(); + + #ifdef ITON_BT_ENABLE_ACK + // hack to make sure irq is low since acks messes with stuff + writePinLow(ITON_BT_IRQ_LINE); + #endif + + switch (iton_bt_buffer[0]) { + case led_state: + iton_bt_led_state = iton_bt_buffer[1]; + break; + case notification: + switch (iton_bt_buffer[1]) { + case notif_battery: + iton_bt_rx_battery_notif(iton_bt_buffer[2]); + break; + case notif_bluetooth: + iton_bt_rx_bluetooth_notif(iton_bt_buffer[2]); + break; + } + break; + } + } +} +#endif + + +void iton_bt_data_cb(SPIDriver *spip) { + writePinLow(ITON_BT_IRQ_LINE); +} + +/** + * Driver Functions + */ +void iton_bt_init(void) { + setPinOutput(ITON_BT_IRQ_LINE); + setPinInput(ITON_BT_INT_LINE); + + writePinLow(ITON_BT_IRQ_LINE); + +#if defined(PAL_USE_CALLBACKS) || defined(PAL_USE_WAIT) + palSetLineCallback(ITON_BT_INT_LINE, iton_bt_rx_cb, NULL); + palEnableLineEvent(ITON_BT_INT_LINE, PAL_EVENT_MODE_BOTH_EDGES); +#endif + + spiStart(&ITON_BT_SPI_PORT, &iton_bt_spicfg); +} + +void iton_bt_send(uint8_t cmd, uint8_t *data, uint8_t len) { + while (readPin(ITON_BT_IRQ_LINE)); + + writePinHigh(ITON_BT_IRQ_LINE); + iton_bt_buffer[0] = cmd; + memcpy(&iton_bt_buffer[1], data, len); + spiStartSend(&ITON_BT_SPI_PORT, len + 1, &iton_bt_buffer[0]); +} + +void iton_bt_send2(uint8_t cmd, uint8_t b1, uint8_t b2) { + while (readPin(ITON_BT_IRQ_LINE)); + + writePinHigh(ITON_BT_IRQ_LINE); + iton_bt_buffer[0] = cmd; + iton_bt_buffer[1] = b1; + iton_bt_buffer[2] = b2; + + spiStartSend(&ITON_BT_SPI_PORT, 3, &iton_bt_buffer[0]); +} + +inline void iton_bt_send_ack(uint8_t b1, uint8_t b2) { + writePinHigh(ITON_BT_IRQ_LINE); + iton_bt_buffer[0] = control; + iton_bt_buffer[1] = b1; + iton_bt_buffer[2] = b2; + chSysLockFromISR(); + spiStartSendI(&ITON_BT_SPI_PORT, 3, &iton_bt_buffer[0]); + chSysUnlockFromISR(); +} + +void iton_bt_send_fn(bool pressed) { + uint8_t data = pressed ? 0xA3 : 0x00; + + iton_bt_send(report_fn, &data, 1); +} + +void iton_bt_send_system(uint16_t data) { + iton_bt_send(report_system, (uint8_t *)&data, 1); +} + +void iton_bt_send_consumer(uint16_t data) { + iton_bt_send2(report_consumer, HIGH_BITS(data), LOW_BITS(data)); +} + +void iton_bt_send_keyboard(report_keyboard_t *report) { + // iton module only reads 5 of the keys in the hid report + // so we send the last key as an nkro report. + if (report->keys[5] != iton_bt_send_kb_last_key) { + uint8_t nkro_report[15] = {0}; + nkro_report[report->keys[5] >> 3] |= (1 << (report->keys[5] & 7)); + iton_bt_send_kb_last_key = report->keys[5]; + + return iton_bt_send(report_nkro, &nkro_report[0], 15); + } + + iton_bt_send(report_hid, &report->mods, 8); +} diff --git a/drivers/bluetooth/iton_bt.h b/drivers/bluetooth/iton_bt.h new file mode 100644 index 000000000000..cdbf48cb3e95 --- /dev/null +++ b/drivers/bluetooth/iton_bt.h @@ -0,0 +1,147 @@ +// Copyright 2023 1Conan (@1Conan) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "report.h" + +#pragma once + +/** + * Driver Structures + */ +enum iton_bt_cmd { + // mcu to iton + report_hid = 0xA1, + report_nkro = 0xA2, + report_consumer = 0xA3, + report_system = 0xA4, + report_fn = 0xA5, + control = 0xA6, + set_name = 0xA7, + set_alarm_volt = 0xA8, + + // iton to mcu + led_state = 0xB1, + notification = 0xB6, +}; + +enum iton_bt_control_cmd { + control_power = 0x25, + control_usb = 0x58, + control_bt = 0x51, + control_pins = 0x52, +}; + +enum iton_bt_control_param { + // control_power + sleep_idle_10m = 0x01, + sleep_idle_20m = 0x02, + sleep_idle_30m = 0x03, + + // control_usb + mode_usb = 0x01, + + // control_bt + mode_bt = 0x62, + reset_pairing = 0x70, + enter_pairing = 0x89, + switch_profile = 0x81, // + 0-5 profiles + os_mac = 0x74, + os_win = 0x75, + + connect_ack = 0x50, + disconnect_ack = 0x51, + wake_ack = 0x60, + unknown_ack = 0x52, + + query_voltage = 0x66, + query_battery_level = 0x61, + + disable_sleep = 0x65, + enable_sleep = 0x68, +}; + +enum iton_bt_notification_type { + notif_battery = 0x5A, + notif_bluetooth = 0x51, +}; + +enum iton_bt_notification_param { + // notif_battery + batt_voltage_low = 0x06, + batt_exit_low_battery_mode = 0x0A, + batt_low_power_shutdown = 0x07, + + batt_above_70 = 0x04, + batt_between_30_70 = 0x02, + batt_below_30 = 0x01, + + query_working_mode = 0xA0, + query_bt_name = 0xA1, + + // Wake from batt_low_power_shutdown + batt_wake_mcu = 0x0B, + + batt_unknown = 0x08, + + // notif_bluetooth + bt_connection_success = 0x76, + bt_entered_pairing = 0x77, + bt_disconected = 0x78, + bt_enters_connection = 0x79, +}; + +/** + * Exported Variables + */ +uint8_t iton_bt_led_state; +bool iton_bt_is_connected; + +/** + * Driver Callbacks + */ + +/** + * Driver Callbacks + */ +void iton_bt_battery_voltage_low(void); +void iton_bt_battery_exit_low_battery_mode(void); +void iton_bt_battery_low_power_shutdown(void); +void iton_bt_battery_level(uint8_t level); + +void iton_bt_connection_successful(void); +void iton_bt_entered_pairing(void); +void iton_bt_disconnected(void); +void iton_bt_enters_connection_state(void); + +/** + * Driver Functions + */ +void iton_bt_init(void); +void iton_bt_send(uint8_t cmd, uint8_t *data, uint8_t len); +void iton_bt_send2(uint8_t cmd, uint8_t b1, uint8_t b2); +void iton_bt_send_ack(uint8_t b1, uint8_t b2); + +void iton_bt_send_fn(bool pressed); +void iton_bt_send_system(uint16_t data); +void iton_bt_send_consumer(uint16_t data); +void iton_bt_send_keyboard(report_keyboard_t *report); + +/** + * Driver Macros + */ +#define iton_bt_control(cmd, param) iton_bt_send2(control, cmd, param) +#define iton_bt_control_bt(param) iton_bt_control(control_bt, param) +#define iton_bt_control_usb(param) iton_bt_control(control_usb, param) + +#define iton_bt_mode_usb() iton_bt_control_usb(mode_usb) +#define iton_bt_mode_bt() iton_bt_control_bt(mode_bt) +#define iton_bt_reset_pairing() iton_bt_control_bt(reset_pairing) +#define iton_bt_enter_pairing() iton_bt_control_bt(enter_pairing) +#define iton_bt_switch_profile(x) iton_bt_control_bt(switch_profile + x) +#define iton_bt_os_mac() iton_bt_control_bt(os_mac) +#define iton_bt_os_win() iton_bt_control_bt(os_win) +#define iton_bt_query_voltage() iton_bt_control_bt(query_voltage) + +#define iton_bt_query_battery_level() iton_bt_control_bt(query_battery_level) +#define iton_bt_disable_sleep() iton_bt_control_bt(disable_sleep) +#define iton_bt_enable_sleep() iton_bt_control_bt(enable_sleep) diff --git a/drivers/bluetooth/outputselect.c b/drivers/bluetooth/outputselect.c index b986ba274e9d..bb88f9765a42 100644 --- a/drivers/bluetooth/outputselect.c +++ b/drivers/bluetooth/outputselect.c @@ -19,6 +19,10 @@ along with this program. If not, see . # include "bluefruit_le.h" #endif +#ifdef BLUETOOTH_ITON_BT +# include "iton_bt.h" +#endif + uint8_t desired_output = OUTPUT_DEFAULT; /** \brief Set Output @@ -51,6 +55,12 @@ uint8_t auto_detect_output(void) { } #endif +#ifdef BLUETOOTH_ITON_BT + if (iton_bt_is_connected) { + return OUTPUT_BLUETOOTH; + } +#endif + #ifdef BLUETOOTH_ENABLE return OUTPUT_BLUETOOTH; // should check if BT is connected here #endif diff --git a/keyboards/keychron/k2/rgb/v2/ansi/ansi.c b/keyboards/keychron/k2/rgb/v2/ansi/ansi.c new file mode 100644 index 000000000000..7b79c07151fd --- /dev/null +++ b/keyboards/keychron/k2/rgb/v2/ansi/ansi.c @@ -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 . +*/ +#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; +} diff --git a/keyboards/keychron/k2/rgb/v2/ansi/keymaps/default/keymap.c b/keyboards/keychron/k2/rgb/v2/ansi/keymaps/default/keymap.c index 5455fb701901..5e5604ba1feb 100644 --- a/keyboards/keychron/k2/rgb/v2/ansi/keymaps/default/keymap.c +++ b/keyboards/keychron/k2/rgb/v2/ansi/keymaps/default/keymap.c @@ -17,17 +17,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ #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 @@ -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 ), @@ -131,8 +123,8 @@ 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, _______ , @@ -140,29 +132,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; diff --git a/keyboards/keychron/k2/rgb/v2/ansi/keymaps/default/keymap.h b/keyboards/keychron/k2/rgb/v2/ansi/keymaps/default/keymap.h new file mode 100644 index 000000000000..78bf82cc5626 --- /dev/null +++ b/keyboards/keychron/k2/rgb/v2/ansi/keymaps/default/keymap.h @@ -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 . +*/ +#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 diff --git a/keyboards/keychron/k2/rgb/v2/ansi/keymaps/via/keymap.c b/keyboards/keychron/k2/rgb/v2/ansi/keymaps/via/keymap.c index 5455fb701901..8ecfb12ea96c 100644 --- a/keyboards/keychron/k2/rgb/v2/ansi/keymaps/via/keymap.c +++ b/keyboards/keychron/k2/rgb/v2/ansi/keymaps/via/keymap.c @@ -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; diff --git a/keyboards/keychron/k2/rgb/v2/ansi/rules.mk b/keyboards/keychron/k2/rgb/v2/ansi/rules.mk new file mode 100644 index 000000000000..0e1d0de931f6 --- /dev/null +++ b/keyboards/keychron/k2/rgb/v2/ansi/rules.mk @@ -0,0 +1,4 @@ +BLUETOOTH_ENABLE = yes +BLUETOOTH_DRIVER = iton_bt +BLUETOOTH_ITON_BT = yes + diff --git a/keyboards/keychron/k2/rgb/v2/config.h b/keyboards/keychron/k2/rgb/v2/config.h index 5147b70a57e2..c7ce8c3b71d8 100644 --- a/keyboards/keychron/k2/rgb/v2/config.h +++ b/keyboards/keychron/k2/rgb/v2/config.h @@ -17,5 +17,18 @@ */ #pragma once + +/* RGB defines */ #define SN32F2XX_RGB_MATRIX_ROW_PINS { C3, C1, C0, C6, C5, C4, C9, C8, C7, C12, C11, C10, B13, C14, C13, B14, B15, D3 } + +/* DIP switch defines */ +#define DIP_BT_EN (1) // 0: Disable, 1: Enable +#define DIP_WIN_MAC (0) // 0: Windows, 1: Mac #define DIP_SWITCH_PINS { D4, D5 } + +/* Bluetooth defines */ +#define ITON_BT_ENABLE_ACK +#define BLUETOOTH_MANUAL_INIT + +/* QMK defines */ +#define DYNAMIC_KEYMAP_LAYER_COUNT 4 diff --git a/keyboards/keychron/k2/rgb/v2/halconf.h b/keyboards/keychron/k2/rgb/v2/halconf.h new file mode 100644 index 000000000000..b6564c6d5fd9 --- /dev/null +++ b/keyboards/keychron/k2/rgb/v2/halconf.h @@ -0,0 +1,29 @@ +// Copyright 2021 1Conan (@1Conan) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#ifdef BLUETOOTH_ITON_BT +/* + * GPIO and SPI IRQs needs to be set to 0 to avoid erratic behavior + */ + +/** + * PAL driver settings + */ +# define PAL_USE_CALLBACKS TRUE +# define SN32_GPIOA_IRQ_PRIORITY 0 + +/** + * SPI driver settings + */ +# define HAL_USE_SPI TRUE +# define SPI_USE_MUTUAL_EXCLUSION FALSE +# define SPI_USE_WAIT FALSE +# define SPI_USE_ASSERT_ON_ERROR FALSE +# define SPI_SELECT_MODE SPI_SELECT_MODE_NONE + +# define SN32_SPI_SPI0_IRQ_PRIORITY 0 +#endif + +#include_next \ No newline at end of file diff --git a/keyboards/keychron/k2/rgb/v2/mcuconf.h b/keyboards/keychron/k2/rgb/v2/mcuconf.h new file mode 100644 index 000000000000..a9c4f1936fd7 --- /dev/null +++ b/keyboards/keychron/k2/rgb/v2/mcuconf.h @@ -0,0 +1,12 @@ +// Copyright 2021 1Conan (@1Conan) +// SPDX-License-Identifier: GPL-2.0-or-later + +/** + * SPI driver settings + */ +#ifdef BLUETOOTH_ITON_BT +# define SN32_SPI_USE_SPI0 TRUE +# define SN32 +#endif + +#include_next \ No newline at end of file diff --git a/platforms/chibios/boards/SN_SN32F240B/board/board.mk b/platforms/chibios/boards/SN_SN32F240B/board/board.mk index b3cf15dd678c..77cb01c43a1c 100644 --- a/platforms/chibios/boards/SN_SN32F240B/board/board.mk +++ b/platforms/chibios/boards/SN_SN32F240B/board/board.mk @@ -11,6 +11,12 @@ OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE # Shave some extra bytes OPT_DEFS += -DCRT1_AREAS_NUMBER=1 +# Some options to reduce RAM usage +# USE_LINK_GC = yes +# LTO_ENABLE = yes + +# OPT = s + # Shared variables ALLCSRC += $(BOARDSRC) ALLINC += $(BOARDINC) diff --git a/quantum/keyboard.c b/quantum/keyboard.c index df1dc1c3ee09..77e69f8c132a 100644 --- a/quantum/keyboard.c +++ b/quantum/keyboard.c @@ -479,7 +479,7 @@ void keyboard_init(void) { // init after split init pointing_device_init(); #endif -#ifdef BLUETOOTH_ENABLE +#if defined(BLUETOOTH_ENABLE) && !defined(BLUETOOTH_MANUAL_INIT) bluetooth_init(); #endif #ifdef HAPTIC_ENABLE