diff options
author | Ryan <fauxpark@gmail.com> | 2021-02-25 15:54:25 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-02-25 15:54:25 +1100 |
commit | 39694d5eb0b7e48e06f9544600041fbbedfff956 (patch) | |
tree | 2427bbf89b955330f793fd7dad3502cfc1e19de9 /tmk_core/common | |
parent | 46f4422a87bf7e3aa52bd8770b14f8361d198e06 (diff) | |
download | qmk_firmware-39694d5eb0b7e48e06f9544600041fbbedfff956.tar.gz qmk_firmware-39694d5eb0b7e48e06f9544600041fbbedfff956.zip |
V-USB suspend refactor (#11891)
Diffstat (limited to 'tmk_core/common')
-rw-r--r-- | tmk_core/common/avr/sleep_led.c | 2 | ||||
-rw-r--r-- | tmk_core/common/avr/suspend.c | 95 | ||||
-rw-r--r-- | tmk_core/common/avr/suspend_avr.h | 25 |
3 files changed, 67 insertions, 55 deletions
diff --git a/tmk_core/common/avr/sleep_led.c b/tmk_core/common/avr/sleep_led.c index 63dcc2afd9..9a3b52abe5 100644 --- a/tmk_core/common/avr/sleep_led.c +++ b/tmk_core/common/avr/sleep_led.c @@ -90,7 +90,7 @@ void sleep_led_toggle(void) { * * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle * - * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 + * https://www.wolframalpha.com/input/?i=sin%28x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } */ static const uint8_t breathing_table[64] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, 15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, 255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, 15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; diff --git a/tmk_core/common/avr/suspend.c b/tmk_core/common/avr/suspend.c index 86c3df040a..cb505ab329 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c @@ -4,7 +4,6 @@ #include <avr/interrupt.h> #include "matrix.h" #include "action.h" -#include "suspend_avr.h" #include "suspend.h" #include "timer.h" #include "led.h" @@ -13,6 +12,9 @@ #ifdef PROTOCOL_LUFA # include "lufa.h" #endif +#ifdef PROTOCOL_VUSB +# include "vusb.h" +#endif #ifdef BACKLIGHT_ENABLE # include "backlight.h" @@ -52,7 +54,25 @@ __attribute__((weak)) void suspend_power_down_user(void) {} */ __attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } -#ifndef NO_SUSPEND_POWER_DOWN +#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) + +// clang-format off +#define wdt_intr_enable(value) \ +__asm__ __volatile__ ( \ + "in __tmp_reg__,__SREG__" "\n\t" \ + "cli" "\n\t" \ + "wdr" "\n\t" \ + "sts %0,%1" "\n\t" \ + "out __SREG__,__tmp_reg__" "\n\t" \ + "sts %0,%2" "\n\t" \ + : /* no outputs */ \ + : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \ + "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \ + "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | _BV(WDIE) | (value & 0x07))) \ + : "r0" \ +) +// clang-format on + /** \brief Power down MCU with watchdog timer * * wdto: watchdog timer timeout defined in <avr/wdt.h> @@ -74,37 +94,11 @@ static uint8_t wdt_timeout = 0; * FIXME: needs doc */ static void power_down(uint8_t wdto) { -# ifdef PROTOCOL_LUFA - if (USB_DeviceState == DEVICE_STATE_Configured) return; -# endif wdt_timeout = wdto; // Watchdog Interrupt Mode wdt_intr_enable(wdto); -# ifdef BACKLIGHT_ENABLE - backlight_set(0); -# endif - - // Turn off LED indicators - uint8_t leds_off = 0; -# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) - if (is_backlight_enabled()) { - // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off - leds_off |= (1 << USB_LED_CAPS_LOCK); - } -# endif - led_set(leds_off); - -# ifdef AUDIO_ENABLE - // This sometimes disables the start-up noise, so it's been disabled - // stop_all_notes(); -# endif /* AUDIO_ENABLE */ -# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) - rgblight_suspend(); -# endif - suspend_power_down_kb(); - // TODO: more power saving // See PicoPower application note // - I/O port input with pullup @@ -127,10 +121,46 @@ static void power_down(uint8_t wdto) { * FIXME: needs doc */ void suspend_power_down(void) { +#ifdef PROTOCOL_LUFA + if (USB_DeviceState == DEVICE_STATE_Configured) return; +#endif +#ifdef PROTOCOL_VUSB + if (!vusb_suspended) return; +#endif + suspend_power_down_kb(); #ifndef NO_SUSPEND_POWER_DOWN + // Turn off backlight +# ifdef BACKLIGHT_ENABLE + backlight_set(0); +# endif + + // Turn off LED indicators + uint8_t leds_off = 0; +# if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) + if (is_backlight_enabled()) { + // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off + leds_off |= (1 << USB_LED_CAPS_LOCK); + } +# endif + led_set(leds_off); + + // Turn off audio +# ifdef AUDIO_ENABLE + // This sometimes disables the start-up noise, so it's been disabled + // stop_all_notes(); +# endif + + // Turn off underglow +# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) + rgblight_suspend(); +# endif + + // Enter sleep state if possible (ie, the MCU has a watchdog timeout interrupt) +# if defined(WDT_vect) power_down(WDTO_15MS); +# endif #endif } @@ -164,17 +194,24 @@ __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_us void suspend_wakeup_init(void) { // clear keyboard state clear_keyboard(); + + // Turn on backlight #ifdef BACKLIGHT_ENABLE backlight_init(); #endif + + // Restore LED indicators led_set(host_keyboard_leds()); + + // Wake up underglow #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) rgblight_wakeup(); #endif + suspend_wakeup_init_kb(); } -#ifndef NO_SUSPEND_POWER_DOWN +#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) /* watchdog timeout */ ISR(WDT_vect) { // compensate timer for sleep diff --git a/tmk_core/common/avr/suspend_avr.h b/tmk_core/common/avr/suspend_avr.h deleted file mode 100644 index 6df048f3bb..0000000000 --- a/tmk_core/common/avr/suspend_avr.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include <stdint.h> -#include <stdbool.h> -#include <avr/sleep.h> -#include <avr/wdt.h> -#include <avr/interrupt.h> - -// clang-format off -#define wdt_intr_enable(value) \ -__asm__ __volatile__ ( \ - "in __tmp_reg__,__SREG__" "\n\t" \ - "cli" "\n\t" \ - "wdr" "\n\t" \ - "sts %0,%1" "\n\t" \ - "out __SREG__,__tmp_reg__" "\n\t" \ - "sts %0,%2" "\n\t" \ - : /* no outputs */ \ - : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \ - "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \ - "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \ - _BV(WDIE) | (value & 0x07)) ) \ - : "r0" \ -) -// clang-format on |