change battery voltage meause and battery low indication; update from latest chibios hal

This commit is contained in:
lokher 2023-01-12 15:50:37 +08:00
parent bbe437487d
commit a0d162e03a
35 changed files with 414 additions and 177 deletions

View file

@ -20,6 +20,8 @@
#include "transport.h"
#include "ckbt51.h"
#include "lpm.h"
#include "indicator.h"
#include "rtc_timer.h"
#define BATTERY_EMPTY_COUNT 10
#define CRITICAL_LOW_COUNT 20
@ -29,12 +31,14 @@ static uint16_t voltage = FULL_VOLTAGE_VALUE;
static uint8_t bat_empty = 0;
static uint8_t critical_low = 0;
static uint8_t bat_state;
static uint8_t power_on_sample = 0;
void battery_init(void) {
bat_monitor_timer_buffer = 0;
bat_state = BAT_NOT_CHARGING;
}
__attribute__((weak)) void battery_measure(void) {}
__attribute__((weak)) void battery_measure(void) {
ckbt51_read_state_reg(0x05, 0x02);
}
/* Calculate the voltage */
__attribute__((weak)) void battery_calculate_voltage(uint16_t value) {}
@ -71,10 +75,16 @@ bool battery_is_critical_low(void) {
void battery_check_empty(void) {
if (voltage < EMPTY_VOLTAGE_VALUE) {
if (bat_empty <= BATTERY_EMPTY_COUNT) {
if (++bat_empty > BATTERY_EMPTY_COUNT) indicator_battery_low_enable(true);
if (++bat_empty > BATTERY_EMPTY_COUNT) {
#ifdef BAT_LOW_LED_PIN
indicator_battery_low_enable(true);
#endif
#if defined(LOW_BAT_IND_INDEX)
indicator_battery_low_backlit_enable(true);
#endif
power_on_sample = VOLTAGE_POWER_ON_MEASURE_COUNT;
}
}
} else if (bat_empty <= BATTERY_EMPTY_COUNT) {
bat_empty = BATTERY_EMPTY_COUNT;
}
}
@ -88,20 +98,43 @@ void battery_check_critical_low(void) {
}
}
bool battery_power_on_sample(void) {
return power_on_sample < VOLTAGE_POWER_ON_MEASURE_COUNT;
}
void battery_task(void) {
uint32_t t = rtc_timer_elapsed_ms(bat_monitor_timer_buffer);
if (get_transport() == TRANSPORT_BLUETOOTH && bluetooth_get_state() == BLUETOOTH_CONNECTED) {
if (sync_timer_elapsed32(bat_monitor_timer_buffer) > VOLTAGE_MEASURE_INTERVAL) {
if ((battery_power_on_sample()
#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
&& !indicator_is_enabled()
#endif
&& t > BACKLIGHT_OFF_VOLTAGE_MEASURE_INTERVAL) ||
t > VOLTAGE_MEASURE_INTERVAL) {
battery_check_empty();
battery_check_critical_low();
bat_monitor_timer_buffer = sync_timer_read32();
bat_monitor_timer_buffer = rtc_timer_read_ms();
if (bat_monitor_timer_buffer > RTC_MAX_TIME) {
bat_monitor_timer_buffer = 0;
rtc_timer_clear();
}
battery_measure();
power_on_sample++;
if (power_on_sample > VOLTAGE_POWER_ON_MEASURE_COUNT) power_on_sample = VOLTAGE_POWER_ON_MEASURE_COUNT;
}
}
if ((bat_empty || critical_low) && usb_power_connected()) {
bat_empty = false;
critical_low = false;
#ifdef BAT_LOW_LED_PIN
indicator_battery_low_enable(false);
#endif
#if defined(LOW_BAT_IND_INDEX)
indicator_battery_low_backlit_enable(false);
#endif
}
}

View file

@ -38,6 +38,14 @@ enum {
# define VOLTAGE_MEASURE_INTERVAL 3000
#endif
#ifndef VOLTAGE_POWER_ON_MEASURE_COUNT
# define VOLTAGE_POWER_ON_MEASURE_COUNT 15
#endif
#ifndef BACKLIGHT_OFF_VOLTAGE_MEASURE_INTERVAL
# define BACKLIGHT_OFF_VOLTAGE_MEASURE_INTERVAL 200
#endif
void battery_init(void);
void battery_measure(void);
void battery_calculte_voltage(uint16_t value);
@ -47,5 +55,6 @@ uint8_t battery_get_percentage(void);
void indicator_battery_low_enable(bool enable);
bool battery_is_empty(void);
bool battery_is_critical_low(void);
bool battery_power_on_sample(void);
void battery_task(void);

View file

@ -21,6 +21,7 @@
#include "battery.h"
#include "indicator.h"
#include "transport.h"
#include "rtc_timer.h"
extern uint8_t pairing_indication;
extern host_driver_t chibios_driver;
@ -102,6 +103,7 @@ void bluetooth_init(void) {
#endif
lpm_init();
rtc_timer_init();
}
/*
@ -213,8 +215,11 @@ static void bluetooth_enter_connected(uint8_t host_idx) {
#endif
bluetooth_enter_connected_kb(host_idx);
if (battery_is_empty()) indicator_battery_low_enable(true);
#ifdef BAT_LOW_LED_PIN
if (battery_is_empty()) {
indicator_battery_low_enable(true);
}
#endif
}
/* Enters disconnected state. Upon entering this state we perform the following actions:
@ -236,10 +241,14 @@ static void bluetooth_enter_disconnected(uint8_t host_idx) {
#endif
retry = 0;
bluetooth_enter_disconnected_kb(host_idx);
#ifdef BAT_LOW_LED_PIN
indicator_battery_low_enable(false);
#endif
#if defined(LOW_BAT_IND_INDEX)
indicator_battery_low_backlit_enable(false);
#endif
}
/* Enter pin code entry state. */
static void bluetooth_enter_pin_code_entry(void) {
#if defined(NKRO_ENABLE)
@ -380,7 +389,12 @@ void bluetooth_send_extra(report_extra_t *report) {
}
void bluetooth_low_battery_shutdown(void) {
#ifdef BAT_LOW_LED_PIN
indicator_battery_low_enable(false);
#endif
#if defined(LOW_BAT_IND_INDEX)
indicator_battery_low_backlit_enable(false);
#endif
bluetooth_disconnect();
}
@ -446,6 +460,17 @@ __attribute__((weak)) bool process_record_kb_bt(uint16_t keycode, keyrecord_t *r
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
if (get_transport() == TRANSPORT_BLUETOOTH) {
lpm_timer_reset();
#if defined(BAT_LOW_LED_PIN) || defined(LOW_BAT_IND_INDEX)
if (battery_is_empty() && bluetooth_get_state() == BLUETOOTH_CONNECTED && record->event.pressed) {
# if defined(BAT_LOW_LED_PIN)
indicator_battery_low_enable(true);
# endif
# if defined(LOW_BAT_IND_INDEX)
indicator_battery_low_backlit_enable(true);
# endif
}
#endif
}
process_record_kb_bt(keycode, record);
return process_record_user(keycode, record);

View file

@ -10,5 +10,7 @@ SRC += \
$(BLUETOOTH_DIR)/lpm_stm32l432.c \
$(BLUETOOTH_DIR)/battery.c \
$(BLUETOOTH_DIR)/factory_test.c \
$(BLUETOOTH_DIR)/bat_level_animation.c
$(BLUETOOTH_DIR)/bat_level_animation.c \
$(BLUETOOTH_DIR)/rtc_timer.c
VPATH += $(TOP_DIR)/keyboards/keychron/$(BLUETOOTH_DIR)

View file

@ -39,8 +39,8 @@ enum {
CKBT51_CMD_SEND_KB_NKRO = 0x12,
CKBT51_CMD_SEND_CONSUMER = 0x13,
CKBT51_CMD_SEND_SYSTEM = 0x14,
CKBT51_CMD_SEND_FN = 0x15, // Not used currently
CKBT51_CMD_SEND_MOUSE = 0x16, // Not used currently
CKBT51_CMD_SEND_FN = 0x15, // Not used currently
CKBT51_CMD_SEND_MOUSE = 0x16, // Not used currently
CKBT51_CMD_SEND_BOOT_KB = 0x17,
/* Bluetooth connections */
CKBT51_CMD_PAIRING = 0x21,
@ -51,14 +51,14 @@ enum {
/* Battery */
CKBT51_CMD_BATTERY_MANAGE = 0x31,
CKBT51_CMD_UPDATE_BAT_LVL = 0x32,
/* Set/get parameters */
CKBT51_CMD_GET_MODULE_INFO = 0x40,
CKBT51_CMD_SET_CONFIG = 0x41,
CKBT51_CMD_GET_CONFIG = 0x42,
CKBT51_CMD_SET_BDA = 0x43,
CKBT51_CMD_GET_BDA = 0x44,
CKBT51_CMD_SET_NAME = 0x45,
CKBT51_CMD_GET_NAME = 0x46,
/* Set/get parameters */
CKBT51_CMD_GET_MODULE_INFO = 0x40,
CKBT51_CMD_SET_CONFIG = 0x41,
CKBT51_CMD_GET_CONFIG = 0x42,
CKBT51_CMD_SET_BDA = 0x43,
CKBT51_CMD_GET_BDA = 0x44,
CKBT51_CMD_SET_NAME = 0x45,
CKBT51_CMD_GET_NAME = 0x46,
/* DFU */
CKBT51_CMD_GET_DFU_VER = 0x60,
CKBT51_CMD_HAND_SHAKE_TOKEN = 0x61,
@ -69,10 +69,11 @@ enum {
/* Factory test */
CKBT51_CMD_FACTORY_RESET = 0x71,
CKBT51_CMD_INT_PIN_TEST = 0x72,
CKBT51_CMD_RADIO_TEST = 0x73,
/* Event */
CKBT51_EVT_CKBT51_CMD_RECEIVED = 0xA1,
CKBT51_EVT_OTA_RSP = 0xA3,
CKBT51_CONNECTION_EVT_ACK = 0xA4,
CKBT51_EVT_OTA_RSP = 0xA3,
CKBT51_CONNECTION_EVT_ACK = 0xA4,
};
enum {
@ -139,11 +140,14 @@ void ckbt51_init(bool wakeup_from_low_power_mode) {
}
void ckbt51_send_cmd(uint8_t* payload, uint8_t len, bool ack_enable, bool retry) {
static uint8_t sn = 1;
static uint8_t sn = 0;
uint8_t i;
uint8_t pkt[PACKET_MAX_LEN] = {0};
memset(pkt, 0, PACKET_MAX_LEN);
if (!retry) ++sn;
if (sn == 0) ++sn;
systime_t start = 0;
for (i=0; i< 3; i++) {
@ -161,15 +165,13 @@ void ckbt51_send_cmd(uint8_t* payload, uint8_t len, bool ack_enable, bool retry)
pkt[i++] = ack_enable ? 0x56 : 0x55;
pkt[i++] = len + 2;
pkt[i++] = ~(len + 2) & 0xFF;
pkt[i++] = sn++;
pkt[i++] = sn;
memcpy(pkt + i, payload, len);
i += len;
pkt[i++] = checksum & 0xFF;
pkt[i++] = (checksum >> 8) & 0xFF;
sdWrite(&BT_DRIVER, pkt, i);
if (sn == 0) sn = 1;
}
void ckbt51_send_keyboard(uint8_t* report) {
@ -352,7 +354,7 @@ void ckbt51_set_local_name(const char* name) {
ckbt51_send_cmd(payload, i, false, false);
}
void ckbt51_get_local_name(char* name) {
void ckbt51_get_local_name(void) {
uint8_t i = 0;
memset(payload, 0, PACKET_MAX_LEN);
@ -379,6 +381,16 @@ void ckbt51_int_pin_test(bool enable) {
ckbt51_send_cmd(payload, i, false, false);
}
void ckbt51_radio_test(uint8_t channel) {
uint8_t i = 0;
memset(payload, 0, PACKET_MAX_LEN);
payload[i++] = CKBT51_CMD_RADIO_TEST;
payload[i++] = channel;
payload[i++] = 0;
ckbt51_send_cmd(payload, i, false, false);
}
void ckbt51_dfu_tx(uint8_t rsp, uint8_t* data, uint8_t len, uint8_t sn) {
uint16_t checksum = 0;
uint8_t buf[RAW_EPSIZE] = {0};

View file

@ -146,11 +146,12 @@ void ckbt51_get_info(module_info_t* info);
void ckbt51_set_param(module_param_t* param);
void ckbt51_get_param(module_param_t* param);
void ckbt51_set_local_name(const char* name);
void ckbt51_get_local_name(char* name);
void ckbt51_get_local_name(void);
void ckbt51_factory_reset(void);
void ckbt51_int_pin_test(bool enable);
void ckbt51_dfu_rx(uint8_t* data, uint8_t length);
void ckbt51_radio_test(uint8_t channel);
void ckbt51_task(void);

View file

@ -53,6 +53,7 @@ enum {
FACTORY_TEST_CMD_INT_PIN,
FACTORY_TEST_CMD_GET_TRANSPORT,
FACTORY_TEST_CMD_CHARGING_ADC,
FACTORY_TEST_CMD_RADIO_CARRIER,
};
enum {
@ -193,6 +194,7 @@ bool led_matrix_indicators_user(void) {
#ifdef RGB_MATRIX_ENABLE
bool rgb_matrix_indicators_user(void) {
if (factory_reset_ind_state) {
backlight_test_mode = BACKLIGHT_TEST_OFF;
rgb_matrix_set_color_all(factory_reset_ind_state % 2 ? 0 : 255, 0, 0);
} else if (backlight_test_mode) {
switch (backlight_test_mode) {
@ -246,10 +248,12 @@ void factory_test_rx(uint8_t *data, uint8_t length) {
}
/* Verify checksum */
if ((checksum & 0xFF) != data[RAW_EPSIZE - 2] || checksum >> 8 != data[RAW_EPSIZE - 1]) return;
#ifdef KC_BLUETOOTH_ENABLE
uint8_t payload[32];
uint8_t len = 0;
#endif
switch (data[1]) {
case FACTORY_TEST_CMD_BACKLIGHT:
backlight_test_mode = data[2];
@ -302,12 +306,18 @@ void factory_test_rx(uint8_t *data, uint8_t length) {
factory_test_send(payload, len);
break;
#endif
case FACTORY_TEST_CMD_RADIO_CARRIER:
if (data[2] < 79) ckbt51_radio_test(data[2]);
break;
}
}
}
bool dip_switch_update_user(uint8_t index, bool active) {
if (report_os_sw_state) {
#ifdef INVERT_OS_SWITCH_STATE
active = !active;
#endif
uint8_t payload[3] = {FACTORY_TEST_CMD_OS_SWITCH, OS_SWITCH, active};
factory_test_send(payload, 3);
}

View file

@ -21,6 +21,8 @@
#include "eeconfig.h"
#include "bluetooth_config.h"
#include "config.h"
#include "rtc_timer.h"
#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
# ifdef LED_MATRIX_ENABLE
# include "led_matrix.h"
@ -58,7 +60,17 @@ static bluetooth_state_t indicator_state;
static uint16_t next_period;
static indicator_type_t type;
static uint32_t indicator_timer_buffer = 0;
static uint32_t battery_low_indicator = 0;
#if defined(BAT_LOW_LED_PIN)
static uint32_t bat_low_pin_indicator = 0;
static uint32_t bat_low_blink_duration = 0;
#endif
#if defined(LOW_BAT_IND_INDEX)
static uint32_t bat_low_backlit_indicator = 0;
static uint8_t bat_low_ind_state = 0;
static uint32_t rtc_time = 0;
#endif
#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
backlight_state_t original_backlight_state;
@ -78,6 +90,7 @@ static pin_t host_led_pin_list[HOST_DEVICES_COUNT] = HOST_LED_PIN_LIST;
# define SET_LED_OFF(idx) led_matrix_set_value(idx, 0)
# define SET_LED_ON(idx) led_matrix_set_value(idx, 255)
# define SET_LED_BT(idx) led_matrix_set_value(idx, 255)
# define SET_LED_LOW_BAT(idx) led_matrix_set_value(idx, 255)
# define LED_DRIVER_IS_ENABLED led_matrix_is_enabled
# define LED_DRIVER_EECONFIG_RELOAD() \
eeprom_read_block(&led_matrix_eeconfig, EECONFIG_LED_MATRIX, sizeof(led_matrix_eeconfig)); \
@ -99,6 +112,7 @@ static pin_t host_led_pin_list[HOST_DEVICES_COUNT] = HOST_LED_PIN_LIST;
# define SET_LED_OFF(idx) rgb_matrix_set_color(idx, 0, 0, 0)
# define SET_LED_ON(idx) rgb_matrix_set_color(idx, 255, 255, 255)
# define SET_LED_BT(idx) rgb_matrix_set_color(idx, 0, 0, 255)
# define SET_LED_LOW_BAT(idx) rgb_matrix_set_color(idx, 255, 0, 0)
# define LED_DRIVER_IS_ENABLED rgb_matrix_is_enabled
# define LED_DRIVER_EECONFIG_RELOAD() \
eeprom_read_block(&rgb_matrix_config, EECONFIG_RGB_MATRIX, sizeof(rgb_matrix_config)); \
@ -113,7 +127,7 @@ static pin_t host_led_pin_list[HOST_DEVICES_COUNT] = HOST_LED_PIN_LIST;
#endif
void indicator_init(void) {
memset(&indicator_config, 0, sizeof(indicator_config));
#ifdef HOST_LED_PIN_LIST
for (uint8_t i = 0; i < HOST_DEVICES_COUNT; i++) {
setPinOutput(host_led_pin_list[i]);
@ -157,7 +171,14 @@ void indicator_eeconfig_reload(void) {
#endif
bool indicator_is_running(void) {
return !!indicator_config.value;
return
#if defined(BAT_LOW_LED_PIN)
bat_low_blink_duration ||
#endif
#if defined(LOW_BAT_IND_INDEX)
bat_low_ind_state ||
#endif
!!indicator_config.value;
}
static void indicator_timer_cb(void *arg) {
@ -283,6 +304,9 @@ void indicator_set(bluetooth_state_t state, uint8_t host_index) {
switch (state) {
case BLUETOOTH_DISCONNECTED:
#ifdef HOST_LED_PIN_LIST
writePin(host_led_pin_list[host_index - 1], !HOST_LED_PIN_ON_STATE);
#endif
INDICATOR_SET(disconnected);
indicator_config.value = (indicator_config.type == INDICATOR_NONE) ? 0 : host_index;
indicator_timer_cb((void *)&indicator_config.type);
@ -343,10 +367,82 @@ void indicator_stop(void) {
}
}
void indicator_battery_low_enable(bool enable) {
battery_low_indicator = enable ? (sync_timer_read32() | 1) : 0;
#ifdef BAT_LOW_LED_PIN
if (!enable) writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
void indicator_battery_low_enable(bool enable) {
if (enable) {
if (bat_low_blink_duration == 0) {
bat_low_blink_duration = bat_low_pin_indicator = sync_timer_read32() | 1;
} else
bat_low_blink_duration = sync_timer_read32() | 1;
} else
writePin(BAT_LOW_LED_PIN, !BAT_LOW_LED_PIN_ON_STATE);
}
#endif
#if defined(LOW_BAT_IND_INDEX)
void indicator_battery_low_backlit_enable(bool enable) {
if (enable) {
uint32_t t = rtc_timer_read_ms();
/* Check overflow */
if (rtc_time > t) {
if (bat_low_ind_state == 0)
rtc_time = t; // Update rtc_time if indicating is not running
else {
rtc_time += t;
}
}
/* Indicating at first time or after the interval */
if ((rtc_time == 0 || t - rtc_time > LOW_BAT_LED_TRIG_INTERVAL) && bat_low_ind_state == 0) {
bat_low_backlit_indicator = enable ? (timer_read32() | 1) : 0;
rtc_time = rtc_timer_read_ms();
bat_low_ind_state = 1;
indicator_enable();
}
} else {
rtc_time = 0;
bat_low_ind_state = 0;
indicator_eeconfig_reload();
if (!LED_DRIVER_IS_ENABLED()) indicator_disable();
}
}
#endif
void indicator_battery_low(void) {
#ifdef BAT_LOW_LED_PIN
if (bat_low_pin_indicator && sync_timer_elapsed32(bat_low_pin_indicator) > (LOW_BAT_LED_BLINK_PERIOD)) {
togglePin(BAT_LOW_LED_PIN);
bat_low_pin_indicator = sync_timer_read32() | 1;
// Turn off low battery indication if we reach the duration
if (sync_timer_elapsed32(bat_low_blink_duration) > LOW_BAT_LED_BLINK_DURATION && palReadLine(BAT_LOW_LED_PIN) != BAT_LOW_LED_PIN_ON_STATE) {
bat_low_blink_duration = bat_low_pin_indicator = 0;
}
}
#endif
#if defined(LOW_BAT_IND_INDEX)
if (bat_low_ind_state) {
if ((bat_low_ind_state & 0x0F) <= (LOW_BAT_LED_BLINK_TIMES) && sync_timer_elapsed32(bat_low_backlit_indicator) > (LOW_BAT_LED_BLINK_PERIOD)) {
if (bat_low_ind_state & 0x80) {
bat_low_ind_state &= 0x7F;
bat_low_ind_state++;
} else {
bat_low_ind_state |= 0x80;
}
bat_low_backlit_indicator = sync_timer_read32() | 1;
/* Restore backligth state */
if ((bat_low_ind_state & 0x0F) > (LOW_BAT_LED_BLINK_TIMES)) {
# if defined(NUM_LOCK_INDEX) || defined(CAPS_LOCK_INDEX) || defined(SCROLL_LOCK_INDEX) || defined(COMPOSE_LOCK_INDEX) || defined(KANA_LOCK_INDEX)
if (LED_DRIVER_ALLOW_SHUTDOWN())
# endif
indicator_disable();
}
} else if ((bat_low_ind_state & 0x0F) > (LOW_BAT_LED_BLINK_TIMES)) {
bat_low_ind_state = 0;
}
}
#endif
}
@ -358,12 +454,7 @@ void indicator_task(void) {
indicator_timer_buffer = sync_timer_read32();
}
if (battery_low_indicator && sync_timer_elapsed32(battery_low_indicator) > LOW_BAT_ON_OFF_DURATION) {
#ifdef BAT_LOW_LED_PIN
togglePin(BAT_LOW_LED_PIN);
#endif
battery_low_indicator = sync_timer_read32() | 1;
}
indicator_battery_low();
}
#if defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)
@ -407,6 +498,15 @@ bool LED_INDICATORS_KB(void) {
return false;
}
# if (defined(LED_MATRIX_ENABLE) || defined(RGB_MATRIX_ENABLE)) && defined(LOW_BAT_IND_INDEX)
if (battery_is_empty()) SET_ALL_LED_OFF();
if (bat_low_ind_state && (bat_low_ind_state & 0x0F) <= LOW_BAT_LED_BLINK_TIMES) {
if (bat_low_ind_state & 0x80)
SET_LED_LOW_BAT(LOW_BAT_IND_INDEX);
else
SET_LED_OFF(LOW_BAT_IND_INDEX);
}
# endif
if (bat_level_animiation_actived()) {
bat_level_animiation_indicate();
}
@ -432,19 +532,19 @@ bool LED_INDICATORS_KB(void) {
} else
os_state_indicate();
return false;
}
bool led_update_user(led_t led_state) {
if (!LED_DRIVER_IS_ENABLED()) {
# ifdef RGB_MATRIX_DRIVER_SHUTDOWN_ENABLE
# if defined(LED_MATRIX_DRIVER_SHUTDOWN_ENABLE) || defined(RGB_MATRIX_DRIVER_SHUTDOWN_ENABLE)
LED_DRIVER.exit_shutdown();
# endif
SET_ALL_LED_OFF();
os_state_indicate();
LED_DRIVER.flush();
# ifdef RGB_MATRIX_DRIVER_SHUTDOWN_ENABLE
# if defined(LED_MATRIX_DRIVER_SHUTDOWN_ENABLE) || defined(RGB_MATRIX_DRIVER_SHUTDOWN_ENABLE)
if (LED_DRIVER_ALLOW_SHUTDOWN()) LED_DRIVER.shutdown();
# endif
}
@ -455,7 +555,7 @@ void LED_NONE_INDICATORS_KB(void) {
os_state_indicate();
}
# ifdef RGB_MATRIX_DRIVER_SHUTDOWN_ENABLE
# if defined(LED_MATRIX_DRIVER_SHUTDOWN_ENABLE) || defined(RGB_MATRIX_DRIVER_SHUTDOWN_ENABLE)
bool LED_DRIVER_ALLOW_SHUTDOWN(void) {
# if defined(NUM_LOCK_INDEX)
if (host_keyboard_led_state().num_lock) return false;

View file

@ -49,8 +49,30 @@
# define CONNECTED_BACKLIGHT_OFF_DELAY_TIME 600
#endif
#ifndef LOW_BAT_ON_OFF_DURATION
# define LOW_BAT_ON_OFF_DURATION 1000
#ifdef BAT_LOW_LED_PIN
/* Uint: ms */
# ifndef LOW_BAT_LED_BLINK_PERIOD
# define LOW_BAT_LED_BLINK_PERIOD 1000
# endif
# ifndef LOW_BAT_LED_BLINK_DURATION
# define LOW_BAT_LED_BLINK_DURATION 10000
# endif
#endif
#ifdef LOW_BAT_IND_INDEX
/* Uint: ms */
# ifndef LOW_BAT_LED_BLINK_PERIOD
# define LOW_BAT_LED_BLINK_PERIOD 500
# endif
# ifndef LOW_BAT_LED_BLINK_TIMES
# define LOW_BAT_LED_BLINK_TIMES 3
# endif
# ifndef LOW_BAT_LED_TRIG_INTERVAL
# define LOW_BAT_LED_TRIG_INTERVAL 30000
# endif
#endif
#if BT_HOST_MAX_COUNT > 6
@ -82,8 +104,14 @@ void indicator_enable(void);
void indicator_disable(void);
void indicator_stop(void);
void indicator_eeconfig_reload(void);
bool indicator_is_enabled(void);
bool indicator_is_running(void);
#ifdef BAT_LOW_LED_PIN
void indicator_battery_low_enable(bool enable);
#endif
#if defined(LOW_BAT_IND_INDEX)
void indicator_battery_low_backlit_enable(bool enable);
#endif
void indicator_task(void);

View file

@ -86,7 +86,7 @@ void lpm_task(void) {
#ifdef RGB_MATRIX_ENABLE
&& rgb_matrix_is_driver_shutdown()
#endif
&& !lpm_any_matrix_action())
&& !lpm_any_matrix_action() && !battery_power_on_sample())
enter_power_mode(LOW_POWER_MODE);
}

View file

@ -30,6 +30,7 @@
#include "transport.h"
#include "battery.h"
#include "report_buffer.h"
#include "stm32_bd.inc"
extern pin_t row_pins[MATRIX_ROWS];
extern void select_all_cols(void);
@ -139,15 +140,6 @@ bool lpm_set(pm_t mode) {
}
static inline void enter_low_power_mode_prepare(void) {
#if HAL_USE_RTC
nvicEnableVector(STM32_EXTI20_NUMBER, 13);
PWR->CR3 |= PWR_CR3_EIWF;
RTCWakeup wakeupspec;
wakeupspec.wutr = 0x040014;
rtcSTM32SetPeriodicWakeup(&RTCD1, &wakeupspec);
#endif
#if defined(KEEP_USB_CONNECTION_IN_BLUETOOTH_MODE)
/* Usb unit is actived and running, stop and disconnect first */
@ -183,10 +175,9 @@ static inline void enter_low_power_mode_prepare(void) {
}
static inline void lpm_wakeup(void) {
if (usb_power_connected())
stm32_clock_init();
else
stm32_clock_fast_init();
chSysLock();
stm32_clock_fast_init();
chSysUnlock();
if (bluetooth_transport.init) bluetooth_transport.init(true);
@ -215,6 +206,7 @@ static inline void lpm_wakeup(void) {
#if defined(KEEP_USB_CONNECTION_IN_BLUETOOTH_MODE)
if (usb_power_connected()) {
hsi48_init();
/* Remove USB isolation.*/
//PWR->CR2 |= PWR_CR2_USV; /* PWR_CR2_USV is available on STM32L4x2xx and STM32L4x3xx devices only. */
usb_power_connect();
@ -228,12 +220,6 @@ static inline void lpm_wakeup(void) {
dip_switch_init();
dip_switch_read(true);
#endif
#if HAL_USE_RTC
rtcSTM32SetPeriodicWakeup(&RTCD1, NULL);
nvicDisableVector(STM32_EXTI20_NUMBER);
#endif
}
/*
@ -277,50 +263,41 @@ void usb_power_disconnect(void) {
/*
* This is a simplified version of stm32_clock_init() by removing unnecessary clock initlization
* code snippet. The original stm32_clock_init() take about 2ms, but ckbt51 sends data via uart
* about 200us after wakeup pin is assert, it means that we must get everything ready before
* uart data coming when wakeup pin interrupt of MCU is triggerred.
* Here we reduce clock init time to 100us.
* about 200us after wakeup pin is assert, it means that we must get everything ready before data
* coming when wakeup pin interrupt of MCU is triggerred.
* Here we reduce clock init time to less than 100us.
*/
inline void stm32_clock_fast_init(void) {
void stm32_clock_fast_init(void) {
#if !STM32_NO_INIT
/* Core voltage setup.*/
PWR->CR1 = STM32_VOS;
while ((PWR->SR2 & PWR_SR2_VOSF) != 0) /* Wait until regulator is */
; /* stable. */
/* Clocks setup.*/
msi_init(); // 6.x us
hsi16_init(); // 4.x us
# if STM32_HSI16_ENABLED // 10.7us
/* HSI activation.*/
RCC->CR |= RCC_CR_HSION;
while ((RCC->CR & RCC_CR_HSIRDY) == 0)
; /* Wait until HSI16 is stable. */
/* PLLs activation, if required.*/
pll_init();
pllsai1_init();
pllsai2_init();
/* clang-format off */
/* Other clock-related settings (dividers, MCO etc).*/
RCC->CFGR = STM32_MCOPRE | STM32_MCOSEL | STM32_STOPWUCK |
STM32_PPRE2 | STM32_PPRE1 | STM32_HPRE;
/* CCIPR register initialization, note, must take care of the _OFF
pseudo settings.*/
{
uint32_t ccipr = STM32_DFSDMSEL | STM32_SWPMI1SEL | STM32_ADCSEL |
STM32_CLK48SEL | STM32_LPTIM2SEL | STM32_LPTIM1SEL |
STM32_I2C3SEL | STM32_I2C2SEL | STM32_I2C1SEL |
STM32_UART5SEL | STM32_UART4SEL | STM32_USART3SEL |
STM32_USART2SEL | STM32_USART1SEL | STM32_LPUART1SEL;
/* clang-format on */
# if STM32_SAI2SEL != STM32_SAI2SEL_OFF
ccipr |= STM32_SAI2SEL;
# endif
# if STM32_CLOCK_HAS_HSI48 // 13us
# if STM32_HSI48_ENABLED
/* HSI activation.*/
RCC->CRRCR |= RCC_CRRCR_HSI48ON;
while ((RCC->CRRCR & RCC_CRRCR_HSI48RDY) == 0)
; /* Wait until HSI48 is stable. */
# endif
# endif
# if STM32_ACTIVATE_PLL || STM32_ACTIVATE_PLLSAI1 || STM32_ACTIVATE_PLLSAI2
/* PLLM and PLLSRC are common to all PLLs.*/
# if defined(STM32L496xx) || defined(STM32L4A6xx)
RCC->PLLCFGR = STM32_PLLPDIV | STM32_PLLR | STM32_PLLREN | STM32_PLLQ | STM32_PLLQEN | STM32_PLLP | STM32_PLLPEN | STM32_PLLN | STM32_PLLM | STM32_PLLSRC;
# else
RCC->PLLCFGR = STM32_PLLR | STM32_PLLREN | STM32_PLLQ | STM32_PLLQEN | STM32_PLLP | STM32_PLLPEN | STM32_PLLN | STM32_PLLM | STM32_PLLSRC;
# endif
# endif
# if STM32_ACTIVATE_PLL
/* PLL activation.*/
RCC->CR |= RCC_CR_PLLON;
/* Waiting for PLL lock.*/
while ((RCC->CR & RCC_CR_PLLRDY) == 0)
;
# if STM32_SAI1SEL != STM32_SAI1SEL_OFF
ccipr |= STM32_SAI1SEL;
# endif
RCC->CCIPR = ccipr;
}
/* Set flash WS's for SYSCLK source */
if (STM32_FLASHBITS > STM32_MSI_FLASHBITS) {
@ -330,12 +307,12 @@ inline void stm32_clock_fast_init(void) {
}
/* Switching to the configured SYSCLK source if it is different from MSI.*/
# if (STM32_SW != STM32_SW_MSI)
# if (STM32_SW != STM32_SW_MSI)
RCC->CFGR |= STM32_SW; /* Switches on the selected clock source. */
/* Wait until SYSCLK is stable.*/
while ((RCC->CFGR & RCC_CFGR_SWS) != (STM32_SW << 2))
;
# endif
# endif
/* Reduce the flash WS's for SYSCLK source if they are less than MSI WSs */
if (STM32_FLASHBITS < STM32_MSI_FLASHBITS) {
@ -344,8 +321,4 @@ inline void stm32_clock_fast_init(void) {
}
}
#endif /* STM32_NO_INIT */
/* SYSCFG clock enabled here because it is a multi-functional unit shared
among multiple drivers.*/
rccEnableAPB2(RCC_APB2ENR_SYSCFGEN, true);
}

View file

@ -0,0 +1,42 @@
/* Copyright 2023 @ lokher (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 <http://www.gnu.org/licenses/>.
*/
#include "hal.h"
#if (HAL_USE_RTC)
# include "rtc_timer.h"
void rtc_timer_init(void) {
rtc_timer_clear();
}
void rtc_timer_clear(void) {
RTCDateTime tm = {0, 0, 0, 0, 0, 0};
rtcSetTime(&RTCD1, &tm);
}
uint32_t rtc_timer_read_ms(void) {
RTCDateTime tm;
rtcGetTime(&RTCD1, &tm);
return tm.millisecond;
}
uint32_t rtc_timer_elapsed_ms(uint32_t last) {
return TIMER_DIFF_32(rtc_timer_read_ms(), last);
}
#endif

View file

@ -0,0 +1,43 @@
/* Copyright 2023 @ lokher (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 <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "timer.h"
#include <stdint.h>
#define RTC_MAX_TIME (24 * 3600 * 1000) // Set to 1 day
#if 0
# define TIMER_DIFF(a, b, max) ((max == UINT8_MAX) ? ((uint8_t)((a) - (b))) : ((max == UINT16_MAX) ? ((uint16_t)((a) - (b))) : ((max == UINT32_MAX) ? ((uint32_t)((a) - (b))) : ((a) >= (b) ? (a) - (b) : (max) + 1 - (b) + (a)))))
# define TIMER_DIFF_8(a, b) TIMER_DIFF(a, b, UINT8_MAX)
# define TIMER_DIFF_16(a, b) TIMER_DIFF(a, b, UINT16_MAX)
# define TIMER_DIFF_32(a, b) TIMER_DIFF(a, b, UINT32_MAX)
# define TIMER_DIFF_RAW(a, b) TIMER_DIFF_8(a, b)
#endif
#ifdef __cplusplus
extern "C" {
#endif
void rtc_timer_init(void);
void rtc_timer_clear(void);
uint32_t rtc_timer_read_ms(void);
uint32_t rtc_timer_elapsed_ms(uint32_t last);
#ifdef __cplusplus
}
#endif

View file

@ -36,6 +36,7 @@
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 46
# define LOW_BAT_IND_INDEX 77
# ifdef VIA_ENABLE
# define VIA_QMK_RGBLIGHT_ENABLE

View file

@ -31,6 +31,7 @@
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 46
# define LOW_BAT_IND_INDEX 77
/* LED Matrix Animation modes. Explicitly enabled
* For full list of effects, see:

View file

@ -21,6 +21,7 @@
#ifdef KC_BLUETOOTH_ENABLE
# define PAL_USE_CALLBACKS TRUE
# define HAL_USE_SERIAL TRUE
# define HAL_USE_RTC TRUE
#endif
#include_next <halconf.h>

View file

@ -36,6 +36,7 @@
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 46
# define LOW_BAT_IND_INDEX 78
# ifdef VIA_ENABLE
# define VIA_QMK_RGBLIGHT_ENABLE

View file

@ -31,6 +31,7 @@
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 46
# define LOW_BAT_IND_INDEX 78
/* LED Matrix Animation modes. Explicitly enabled
* For full list of effects, see:

View file

@ -227,21 +227,6 @@ void bluetooth_pre_task(void) {
}
}
}
void battery_measure(void) {
# ifdef LED_MATRIX_ENABLE
if (led_matrix_is_enabled()) {
ckbt51_read_state_reg(0x05, 0x02);
return;
}
# endif
# ifdef RGB_MATRIX_ENABLE
if (rgb_matrix_is_enabled()) {
ckbt51_read_state_reg(0x05, 0x02);
return;
}
# endif
}
#endif
void battery_calculte_voltage(uint16_t value) {

View file

@ -37,6 +37,7 @@
/* Caps lock indicating led */
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 46
# define LOW_BAT_IND_INDEX 77
# ifdef VIA_ENABLE
# define VIA_QMK_RGBLIGHT_ENABLE

View file

@ -32,6 +32,7 @@
/* Caps lock indicating led */
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 46
# define LOW_BAT_IND_INDEX 77
/* LED Matrix Animation modes. Explicitly enabled
* For full list of effects, see:

View file

@ -22,6 +22,7 @@
#ifdef KC_BLUETOOTH_ENABLE
# define PAL_USE_CALLBACKS TRUE
# define HAL_USE_SERIAL TRUE
# define HAL_USE_RTC TRUE
#endif
#include_next <halconf.h>

View file

@ -37,6 +37,7 @@
/* Caps lock indicating led */
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 46
# define LOW_BAT_IND_INDEX 78
# ifdef VIA_ENABLE
# define VIA_QMK_RGBLIGHT_ENABLE

View file

@ -32,6 +32,7 @@
/* Caps lock indicating led */
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 46
# define LOW_BAT_IND_INDEX 78
/* LED Matrix Animation modes. Explicitly enabled
* For full list of effects, see:

View file

@ -232,21 +232,6 @@ void bluetooth_pre_task(void) {
}
}
}
void battery_measure(void) {
# ifdef LED_MATRIX_ENABLE
if (led_matrix_is_enabled()) {
ckbt51_read_state_reg(0x05, 0x02);
return;
}
# endif
# ifdef RGB_MATRIX_ENABLE
if (rgb_matrix_is_enabled()) {
ckbt51_read_state_reg(0x05, 0x02);
return;
}
# endif
}
#endif
void battery_calculte_voltage(uint16_t value) {

View file

@ -36,6 +36,7 @@
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 30
# define LOW_BAT_IND_INDEX 61
# ifdef VIA_ENABLE
# define VIA_QMK_RGBLIGHT_ENABLE

View file

@ -20,7 +20,7 @@
/* LED matrix driver configuration */
# define DRIVER_COUNT 1
# define DRIVER_ADDR_1 0b1110100
# define LED_MATRIX_LED_COUNT 84
# define LED_MATRIX_LED_COUNT 68
/* Set to infinit, which is use in USB mode by default */
# define LED_MATRIX_TIMEOUT LED_MATRIX_TIMEOUT_INFINITE
@ -32,6 +32,7 @@
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 46
# define LOW_BAT_IND_INDEX 61
/* LED Matrix Animation modes. Explicitly enabled
* For full list of effects, see:

View file

@ -21,6 +21,7 @@
#ifdef KC_BLUETOOTH_ENABLE
# define PAL_USE_CALLBACKS TRUE
# define HAL_USE_SERIAL TRUE
# define HAL_USE_RTC TRUE
#endif
#include_next <halconf.h>

View file

@ -33,6 +33,7 @@
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 30
# define LOW_BAT_IND_INDEX 62
# ifdef VIA_ENABLE
# define VIA_QMK_RGBLIGHT_ENABLE

View file

@ -27,6 +27,10 @@
/* Turn off backlight on low brightness to save power */
# define LED_MATRIX_BRIGHTNESS_TURN_OFF_VAL 32
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 30
# define LOW_BAT_IND_INDEX 62
/* LED Matrix Animation modes. Explicitly enabled
* For full list of effects, see:
* https://docs.qmk.fm/#/feature_led_matrix?id=led-matrix-effects
@ -65,7 +69,4 @@
/* Set LED driver current */
# define CKLED2001_CURRENT_TUNE { 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60 }
# define DIM_CAPS_LOCK
# define CAPS_LOCK_INDEX 30
#endif

View file

@ -224,21 +224,6 @@ void bluetooth_pre_task(void) {
}
}
}
void battery_measure(void) {
# ifdef LED_MATRIX_ENABLE
if (led_matrix_is_enabled()) {
ckbt51_read_state_reg(0x05, 0x02);
return;
}
# endif
# ifdef RGB_MATRIX_ENABLE
if (rgb_matrix_is_enabled()) {
ckbt51_read_state_reg(0x05, 0x02);
return;
}
# endif
}
#endif
void battery_calculte_voltage(uint16_t value) {

View file

@ -14,6 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef LED_MATRIX_ENABLE
/* LED matrix driver configuration */
# define DRIVER_COUNT 1
@ -65,5 +67,4 @@
/* Set LED driver current */
# define CKLED2001_CURRENT_TUNE { 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x60 }
#endif

View file

@ -21,6 +21,7 @@
#ifdef KC_BLUETOOTH_ENABLE
# define PAL_USE_CALLBACKS TRUE
# define HAL_USE_SERIAL TRUE
# define HAL_USE_RTC TRUE
#endif
#include_next <halconf.h>

View file

@ -14,6 +14,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#ifdef LED_MATRIX_ENABLE
/* LED matrix driver configuration */
# define DRIVER_COUNT 1

View file

@ -234,21 +234,6 @@ void bluetooth_pre_task(void) {
}
}
}
void battery_measure(void) {
# ifdef LED_MATRIX_ENABLE
if (led_matrix_is_enabled()) {
ckbt51_read_state_reg(0x05, 0x02);
return;
}
# endif
# ifdef RGB_MATRIX_ENABLE
if (rgb_matrix_is_enabled()) {
ckbt51_read_state_reg(0x05, 0x02);
return;
}
# endif
}
#endif
void battery_calculte_voltage(uint16_t value) {