/* Copyright 2022~2024 @ Keychron (https://www.keychron.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 . */ #include QMK_KEYBOARD_H #include "lkbt51.h" #include "wireless.h" #include "indicator.h" #include "transport.h" #include "battery.h" #include "bat_level_animation.h" #include "lpm.h" #include "wireless_common.h" #include "lemokey_task.h" #include "lemokey_common.h" #include "config.h" bool firstDisconnect = true; static uint32_t pairing_key_timer; static uint8_t host_idx = 0; bool process_record_wireless_common(uint16_t keycode, keyrecord_t *record) { static uint8_t host_idx; switch (keycode) { case BT_HST1 ... BT_HST3: if (get_transport() == TRANSPORT_BLUETOOTH) { if (record->event.pressed) { host_idx = keycode - BT_HST1 + 1; pairing_key_timer = timer_read32(); wireless_connect_ex(host_idx, 0); } else { host_idx = 0; pairing_key_timer = 0; } } break; case P2P4G: if (get_transport() == TRANSPORT_P2P4) { if (record->event.pressed) { host_idx = P24G_INDEX; pairing_key_timer = timer_read32(); } else { host_idx = 0; pairing_key_timer = 0; } } break; #if (defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)) && defined(BAT_LEVEL_LED_LIST) case BAT_LVL: if ((get_transport() & TRANSPORT_WIRELESS) && !usb_power_connected()) { bat_level_animiation_start(battery_get_percentage()); } break; #endif default: break; } return true; } void lkbt51_param_init(void) { /* Set bluetooth device name */ lkbt51_set_local_name(PRODUCT); wait_ms(3); // clang-format off /* Set bluetooth parameters */ module_param_t param = {.event_mode = 0x02, .connected_idle_timeout = 7200, .pairing_timeout = 180, .pairing_mode = 0, .reconnect_timeout = 5, .report_rate = 90, .vendor_id_source = 1, .verndor_id = 0x362D, .product_id = PRODUCT_ID}; // clang-format on lkbt51_set_param(¶m); } void wireless_enter_reset_kb(uint8_t reason) { lkbt51_param_init(); } void wireless_enter_disconnected_kb(uint8_t host_idx, uint8_t reason) { /* CKBT51 bluetooth module boot time is slower, it enters disconnected after boot, so we place initialization here. */ if (firstDisconnect && timer_read32() < 1000) { lkbt51_param_init(); if (get_transport() == TRANSPORT_BLUETOOTH) wireless_connect(); firstDisconnect = false; } } void wireless_common_task(void) { if (pairing_key_timer) { if (timer_elapsed32(pairing_key_timer) > 2000) { pairing_key_timer = 0; wireless_pairing_ex(host_idx, NULL); } } } void wireless_pre_task(void) { static uint8_t dip_switch_state = 0; static uint32_t time = 0; if (time == 0) { uint8_t pins_state = (readPin(BT_MODE_SELECT_PIN) << 1) | readPin(P2P4_MODE_SELECT_PIN); if (pins_state != dip_switch_state) { dip_switch_state = pins_state; time = timer_read32(); } } if ((time && timer_elapsed32(time) > 100) || get_transport() == TRANSPORT_NONE) { uint8_t pins_state = (readPin(BT_MODE_SELECT_PIN) << 1) | readPin(P2P4_MODE_SELECT_PIN); if (pins_state == dip_switch_state) { time = 0; switch (dip_switch_state) { case 0x01: set_transport(TRANSPORT_BLUETOOTH); break; case 0x02: set_transport(TRANSPORT_P2P4); break; case 0x03: set_transport(TRANSPORT_USB); break; default: break; } } else { dip_switch_state = pins_state; time = timer_read32(); } } }