diff --git a/keyboards/nuphy/air75_v2/ansi/ansi.c b/keyboards/nuphy/air75_v2/ansi/ansi.c index df33cdc9b4c6..0742f5db0a4d 100644 --- a/keyboards/nuphy/air75_v2/ansi/ansi.c +++ b/keyboards/nuphy/air75_v2/ansi/ansi.c @@ -20,30 +20,28 @@ along with this program. If not, see . #include "usb_main.h" #include "mcu_pwr.h" -extern bool f_rf_sw_press; -extern bool f_sleep_show; -extern bool f_dev_reset_press; -extern bool f_bat_num_show; -extern bool f_rgb_test_press; -extern bool f_bat_hold; -extern uint16_t no_act_time; -extern uint8_t rf_sw_temp; -extern uint16_t rf_sw_press_delay; -extern uint16_t rf_linking_time; -extern uint16_t sleep_time_delay; -extern user_config_t user_config; -extern DEV_INFO_STRUCT dev_info; -extern uint8_t rf_blink_cnt; - -/* qmk process record */ -bool process_record_kb(uint16_t keycode, keyrecord_t *record) { +bool pre_process_record_kb(uint16_t keycode, keyrecord_t *record) { no_act_time = 0; rf_linking_time = 0; - if (!process_record_user(keycode, record)) { + // wakeup check for light sleep/no sleep - fire this immediately to not lose wake keys. + if (f_wakeup_prepare) { + f_wakeup_prepare = 0; + if (user_config.sleep_mode) exit_light_sleep(); + } + + if (!pre_process_record_user(keycode, record)) { return false; } + return true; +} + +/* qmk process record */ +bool process_record_kb(uint16_t keycode, keyrecord_t *record) { + if (!process_record_user(keycode, record)) { + return false; + } switch (keycode) { case RF_DFU: if (record->event.pressed) { @@ -200,9 +198,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { case SLEEP_MODE: if (record->event.pressed) { - user_config.sleep_enable = !user_config.sleep_enable; - f_sleep_show = 1; - eeconfig_update_kb_datablock(&user_config); + toggle_sleep_mode(); } return false; @@ -237,7 +233,7 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) { case KB_SLP: if (record->event.pressed) { uint16_t mask = (100 * 30) ^ SLEEP_TIME_DELAY; // 30s or default - sleep_time_delay ^= mask; // XOR swap + sleep_time_delay ^= mask; // XOR swap } return false; diff --git a/keyboards/nuphy/air75_v2/ansi/customizations.md b/keyboards/nuphy/air75_v2/ansi/customizations.md index 7909854369a6..f39f0cc1fec8 100644 --- a/keyboards/nuphy/air75_v2/ansi/customizations.md +++ b/keyboards/nuphy/air75_v2/ansi/customizations.md @@ -14,11 +14,15 @@ This sets how long the board tries to connect (left light blinking) before givin - `Fn + M + D` toggles QMK debugging. Don't turn this on when not connected to QMK toolbox. The letter `D` will light up red when enabled. - Side indicators will flash red for 0.5s when board enters sleep mode, as an indicator. -This is a deep sleep state. It only happens if the board is not charging, otherwise the board enters a light sleep state with no indicators. +This is a deep sleep state. There are no indicators in other sleep modes. - Bluetooth connection indicators will be lit blue when establishing connection. This lights the corresponding BT mode key. No indicator for RF as the sidelight is a different colour. - Default startup LED brightness set to zero and side led set to lowest brightness. This is because I don't use LEDs so I don't need to toggle them off when resetting the board or flashing new firmware. - 3ms debounce instead of 2ms (potential stability) +- 3 sleep modes (inspired by @adi4086) - Toggle with the default sleep mode button. + - Deep Sleep (NRF off, MCU off, LED off) - lowest power consumption. This is the default. + - Light Sleep (NRF off, LED off) - no real reason to use this, but might wake up quicker. + - No Sleep - for those that want their board to always be on... ## Fixes diff --git a/keyboards/nuphy/air75_v2/ansi/mcu_pwr.c b/keyboards/nuphy/air75_v2/ansi/mcu_pwr.c index f374bb0ed4be..79c36216a0e4 100644 --- a/keyboards/nuphy/air75_v2/ansi/mcu_pwr.c +++ b/keyboards/nuphy/air75_v2/ansi/mcu_pwr.c @@ -27,6 +27,7 @@ static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; extern DEV_INFO_STRUCT dev_info; static bool f_usb_deinit = 0; +static bool sleeping = false; static bool side_led_powered_off = 0; static bool rgb_led_powered_off = 0; static bool tim6_enabled = false; @@ -216,6 +217,7 @@ void enter_light_sleep(void) { led_pwr_sleep_handle(); clear_report_buffer(); + sleeping = true; } /** @@ -234,6 +236,7 @@ void exit_light_sleep(void) { // flag for RF wakeup workload. dev_info.rf_state = RF_WAKE; + sleeping = false; } void led_pwr_sleep_handle(void) { @@ -271,7 +274,7 @@ void pwr_rgb_led_off(void) { } void pwr_rgb_led_on(void) { - if (rgb_led_on) return; + if (sleeping || rgb_led_on) return; // LED power supply on gpio_set_pin_output(DC_BOOST_PIN); gpio_write_pin_high(DC_BOOST_PIN); @@ -287,7 +290,7 @@ void pwr_side_led_off(void) { } void pwr_side_led_on(void) { - if (side_led_on) return; + if (sleeping || side_led_on) return; gpio_set_pin_output(DRIVER_SIDE_CS_PIN); gpio_write_pin_low(DRIVER_SIDE_CS_PIN); side_led_on = 1; diff --git a/keyboards/nuphy/air75_v2/ansi/rf_driver.c b/keyboards/nuphy/air75_v2/ansi/rf_driver.c index a53fdf160c71..158b79928321 100644 --- a/keyboards/nuphy/air75_v2/ansi/rf_driver.c +++ b/keyboards/nuphy/air75_v2/ansi/rf_driver.c @@ -21,7 +21,6 @@ along with this program. If not, see . #include "rf_queue.h" /* Variable declaration */ -extern DEV_INFO_STRUCT dev_info; extern report_buffer_t report_buff_a; extern report_buffer_t report_buff_b; extern rf_queue_t rf_queue; diff --git a/keyboards/nuphy/air75_v2/ansi/side.c b/keyboards/nuphy/air75_v2/ansi/side.c index d703ac316f8f..53319cacaf12 100644 --- a/keyboards/nuphy/air75_v2/ansi/side.c +++ b/keyboards/nuphy/air75_v2/ansi/side.c @@ -81,16 +81,6 @@ const uint8_t side_led_index_tab[SIDE_LINE][2] = { }; // clang-format on -extern DEV_INFO_STRUCT dev_info; -extern user_config_t user_config; -extern uint8_t rf_blink_cnt; -extern uint16_t rf_link_show_time; -extern uint16_t side_led_last_act; -extern bool f_bat_hold; -extern bool f_sys_show; -extern bool f_sleep_show; -extern RGB bat_pct_rgb; - void side_ws2812_setleds(rgb_led_t *ledarray, uint16_t leds); void rgb_matrix_update_pwm_buffers(void); @@ -321,15 +311,22 @@ void sleep_sw_led_show(void) { } if (sleep_show_flag) { - if (user_config.sleep_enable) { - r_temp = 0x00; - g_temp = 0x80; - b_temp = 0x00; - } else { - r_temp = 0x80; - g_temp = 0x00; - b_temp = 0x00; + r_temp = 0x00; + g_temp = 0x00; + b_temp = 0x00; + switch (user_config.sleep_mode) { + case SLEEP_MODE_OFF: + r_temp = 0x80; + break; + case SLEEP_MODE_LIGHT: + r_temp = 0x80; + g_temp = 0x40; + break; + case SLEEP_MODE_DEEP: + g_temp = 0x80; + break; } + if ((timer_elapsed32(sleep_show_timer) / 500) % 2 == 0) { set_right_rgb(r_temp, g_temp, b_temp); } else { @@ -483,7 +480,7 @@ static void side_off_mode_show(void) { * @brief rf_led_show. */ void rf_led_show(void) { - static uint32_t rf_blink_timer = 0; + static uint32_t rf_blink_timer = 0; uint16_t rf_blink_period = 0; if (rf_blink_cnt || (rf_link_show_time < RF_LINK_SHOW_TIME)) { diff --git a/keyboards/nuphy/air75_v2/ansi/sleep.c b/keyboards/nuphy/air75_v2/ansi/sleep.c index 05215243dd3d..3919ff88c181 100644 --- a/keyboards/nuphy/air75_v2/ansi/sleep.c +++ b/keyboards/nuphy/air75_v2/ansi/sleep.c @@ -55,7 +55,7 @@ void deep_sleep_handle(void) { // Without doing this, the WS2812 driver wouldn't flush as the previous state is the same as current. rgb_matrix_set_color_all(0, 0, 0); flush_side_leds = true; - no_act_time = 0; // required to not cause an immediate sleep on first wake + no_act_time = 0; // required to not cause an immediate sleep on first wake } /** @@ -77,42 +77,13 @@ void sleep_handle(void) { rf_disconnect_time = 0; rf_linking_time = 0; - if (user_config.sleep_enable) { - bool deep_sleep = 1; - // light sleep if charging? Charging event might keep waking MCU. To be confirmed... - if (dev_info.rf_charge & 0x01) { - deep_sleep = 0; - } - // or if it's in USB mode but USB state is suspended - // TODO: How to detect if USB is unplugged? I only use RF so not a big deal I guess... - else if (dev_info.link_mode == LINK_USB && USB_DRIVER.state == USB_SUSPENDED) { - deep_sleep = 0; - } - - if (deep_sleep) { - deep_sleep_handle(); - return; // don't need to do anything else - } else { - enter_light_sleep(); - } - } - f_wakeup_prepare = 1; // only if light sleep. - } - - // wakeup check - // we only arrive here on light sleep. - if (f_wakeup_prepare) { - if (no_act_time < 10) { // activity wake up - f_wakeup_prepare = 0; - if (user_config.sleep_enable) exit_light_sleep(); - } - // No longer charging? Go deep sleep. - // TODO: don't really know true charge bit logic. I'm just guessing here. - else if (user_config.sleep_enable && (dev_info.rf_charge & 0x01) == 0) { - f_wakeup_prepare = 0; + if (user_config.sleep_mode == SLEEP_MODE_DEEP) { deep_sleep_handle(); - return; + return; // don't need to do anything else + } else if (user_config.sleep_mode == SLEEP_MODE_LIGHT) { + enter_light_sleep(); } + f_wakeup_prepare = 1; // only if light sleep. } // sleep check, won't reach here on deep sleep. diff --git a/keyboards/nuphy/air75_v2/ansi/user_kb.c b/keyboards/nuphy/air75_v2/ansi/user_kb.c index ddf1f81646cd..161fa0a2aae9 100644 --- a/keyboards/nuphy/air75_v2/ansi/user_kb.c +++ b/keyboards/nuphy/air75_v2/ansi/user_kb.c @@ -52,15 +52,7 @@ uint16_t sleep_time_delay = SLEEP_TIME_DELAY; host_driver_t *m_host_driver = 0; RGB bat_pct_rgb = {.r = 0x80, .g = 0x80, .b = 0x00}; -extern bool f_rf_new_adv_ok; -extern report_keyboard_t *keyboard_report; -extern report_nkro_t *nkro_report; -extern host_driver_t rf_host_driver; -extern uint8_t side_mode; -extern uint8_t side_light; -extern uint8_t side_speed; -extern uint8_t side_rgb; -extern uint8_t side_colour; +extern host_driver_t rf_host_driver; /** * @brief gpio initial. @@ -423,7 +415,7 @@ void user_config_reset(void) { user_config.ee_side_speed = side_speed; user_config.ee_side_rgb = side_rgb; user_config.ee_side_colour = side_colour; - user_config.sleep_enable = true; + user_config.sleep_mode = SLEEP_MODE_DEEP; user_config.rf_link_timeout = LINK_TIMEOUT_ALT; eeconfig_update_kb_datablock(&user_config); } @@ -522,4 +514,14 @@ void led_power_handle(void) { pwr_side_led_on(); } } +} + +void toggle_sleep_mode(void) { + if (user_config.sleep_mode > SLEEP_MODE_OFF) { + user_config.sleep_mode--; + } else { + user_config.sleep_mode = SLEEP_MODE_DEEP; + } + f_sleep_show = 1; + eeconfig_update_kb_datablock(&user_config); } \ No newline at end of file diff --git a/keyboards/nuphy/air75_v2/ansi/user_kb.h b/keyboards/nuphy/air75_v2/ansi/user_kb.h index 28e41d37e6d8..708a76229cd4 100644 --- a/keyboards/nuphy/air75_v2/ansi/user_kb.h +++ b/keyboards/nuphy/air75_v2/ansi/user_kb.h @@ -39,7 +39,7 @@ typedef enum { } TYPE_RX_STATE; - +// clang-format off #define RF_IDLE 0 #define RF_PAIRING 1 #define RF_LINKING 2 @@ -108,6 +108,11 @@ typedef enum { #define DEV_RESET_PRESS_DELAY 30 #define RGB_TEST_PRESS_DELAY 30 +#define SLEEP_MODE_OFF 0 +#define SLEEP_MODE_LIGHT 1 +#define SLEEP_MODE_DEEP 2 +// clang-format on + typedef struct { uint8_t RXDState; uint8_t RXDLen; @@ -120,8 +125,7 @@ typedef struct { uint8_t RXDBuf[UART_MAX_LEN]; } USART_MGR_STRUCT; -typedef struct -{ +typedef struct { uint8_t link_mode; uint8_t rf_channel; uint8_t ble_channel; @@ -139,12 +143,41 @@ typedef struct { uint8_t ee_side_speed; uint8_t ee_side_rgb; uint8_t ee_side_colour; - uint8_t sleep_enable; + uint8_t sleep_mode; uint16_t rf_link_timeout; uint8_t retain1; uint8_t retain2; } user_config_t; +// Globals +extern DEV_INFO_STRUCT dev_info; +extern user_config_t user_config; +extern uint8_t rf_blink_cnt; +extern uint16_t rf_link_show_time; +extern uint16_t side_led_last_act; +extern bool f_bat_hold; +extern bool f_sys_show; +extern bool f_sleep_show; +extern RGB bat_pct_rgb; +extern bool f_rf_sw_press; +extern bool f_dev_reset_press; +extern bool f_bat_num_show; +extern bool f_rgb_test_press; +extern uint16_t no_act_time; +extern uint8_t rf_sw_temp; +extern uint16_t rf_sw_press_delay; +extern uint16_t rf_linking_time; +extern uint16_t sleep_time_delay; +extern bool f_wakeup_prepare; +extern bool f_rf_new_adv_ok; +extern report_keyboard_t *keyboard_report; +extern report_nkro_t * nkro_report; +extern uint8_t side_mode; +extern uint8_t side_light; +extern uint8_t side_speed; +extern uint8_t side_rgb; +extern uint8_t side_colour; + void dev_sts_sync(void); void rf_uart_init(void); void rf_device_init(void); @@ -171,4 +204,5 @@ void load_eeprom_data(void); void user_config_reset(void); void user_set_rgb_color(int index, uint8_t red, uint8_t green, uint8_t blue); void led_power_handle(void); +void toggle_sleep_mode(void); uint8_t uart_send_cmd(uint8_t cmd, uint8_t ack_cnt, uint8_t delayms);