summaryrefslogtreecommitdiff
path: root/tmk_core/common/avr
diff options
context:
space:
mode:
authorRyan <fauxpark@gmail.com>2021-02-25 15:54:25 +1100
committerGitHub <noreply@github.com>2021-02-25 15:54:25 +1100
commit39694d5eb0b7e48e06f9544600041fbbedfff956 (patch)
tree2427bbf89b955330f793fd7dad3502cfc1e19de9 /tmk_core/common/avr
parent46f4422a87bf7e3aa52bd8770b14f8361d198e06 (diff)
V-USB suspend refactor (#11891)
Diffstat (limited to 'tmk_core/common/avr')
-rw-r--r--tmk_core/common/avr/sleep_led.c2
-rw-r--r--tmk_core/common/avr/suspend.c95
-rw-r--r--tmk_core/common/avr/suspend_avr.h25
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