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/avr | |
parent | 46f4422a87bf7e3aa52bd8770b14f8361d198e06 (diff) | |
download | qmk_firmware-39694d5eb0b7e48e06f9544600041fbbedfff956.tar.gz qmk_firmware-39694d5eb0b7e48e06f9544600041fbbedfff956.zip |
V-USB suspend refactor (#11891)
Diffstat (limited to 'tmk_core/common/avr')
-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 63dcc2afd..9a3b52abe 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) { | |||
90 | * | 90 | * |
91 | * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle | 91 | * (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle |
92 | * | 92 | * |
93 | * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 | 93 | * https://www.wolframalpha.com/input/?i=sin%28x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 |
94 | * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } | 94 | * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } |
95 | */ | 95 | */ |
96 | 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}; | 96 | 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 86c3df040..cb505ab32 100644 --- a/tmk_core/common/avr/suspend.c +++ b/tmk_core/common/avr/suspend.c | |||
@@ -4,7 +4,6 @@ | |||
4 | #include <avr/interrupt.h> | 4 | #include <avr/interrupt.h> |
5 | #include "matrix.h" | 5 | #include "matrix.h" |
6 | #include "action.h" | 6 | #include "action.h" |
7 | #include "suspend_avr.h" | ||
8 | #include "suspend.h" | 7 | #include "suspend.h" |
9 | #include "timer.h" | 8 | #include "timer.h" |
10 | #include "led.h" | 9 | #include "led.h" |
@@ -13,6 +12,9 @@ | |||
13 | #ifdef PROTOCOL_LUFA | 12 | #ifdef PROTOCOL_LUFA |
14 | # include "lufa.h" | 13 | # include "lufa.h" |
15 | #endif | 14 | #endif |
15 | #ifdef PROTOCOL_VUSB | ||
16 | # include "vusb.h" | ||
17 | #endif | ||
16 | 18 | ||
17 | #ifdef BACKLIGHT_ENABLE | 19 | #ifdef BACKLIGHT_ENABLE |
18 | # include "backlight.h" | 20 | # include "backlight.h" |
@@ -52,7 +54,25 @@ __attribute__((weak)) void suspend_power_down_user(void) {} | |||
52 | */ | 54 | */ |
53 | __attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } | 55 | __attribute__((weak)) void suspend_power_down_kb(void) { suspend_power_down_user(); } |
54 | 56 | ||
55 | #ifndef NO_SUSPEND_POWER_DOWN | 57 | #if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) |
58 | |||
59 | // clang-format off | ||
60 | #define wdt_intr_enable(value) \ | ||
61 | __asm__ __volatile__ ( \ | ||
62 | "in __tmp_reg__,__SREG__" "\n\t" \ | ||
63 | "cli" "\n\t" \ | ||
64 | "wdr" "\n\t" \ | ||
65 | "sts %0,%1" "\n\t" \ | ||
66 | "out __SREG__,__tmp_reg__" "\n\t" \ | ||
67 | "sts %0,%2" "\n\t" \ | ||
68 | : /* no outputs */ \ | ||
69 | : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \ | ||
70 | "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \ | ||
71 | "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | _BV(WDIE) | (value & 0x07))) \ | ||
72 | : "r0" \ | ||
73 | ) | ||
74 | // clang-format on | ||
75 | |||
56 | /** \brief Power down MCU with watchdog timer | 76 | /** \brief Power down MCU with watchdog timer |
57 | * | 77 | * |
58 | * wdto: watchdog timer timeout defined in <avr/wdt.h> | 78 | * wdto: watchdog timer timeout defined in <avr/wdt.h> |
@@ -74,37 +94,11 @@ static uint8_t wdt_timeout = 0; | |||
74 | * FIXME: needs doc | 94 | * FIXME: needs doc |
75 | */ | 95 | */ |
76 | static void power_down(uint8_t wdto) { | 96 | static void power_down(uint8_t wdto) { |
77 | # ifdef PROTOCOL_LUFA | ||
78 | if (USB_DeviceState == DEVICE_STATE_Configured) return; | ||
79 | # endif | ||
80 | wdt_timeout = wdto; | 97 | wdt_timeout = wdto; |
81 | 98 | ||
82 | // Watchdog Interrupt Mode | 99 | // Watchdog Interrupt Mode |
83 | wdt_intr_enable(wdto); | 100 | wdt_intr_enable(wdto); |
84 | 101 | ||
85 | # ifdef BACKLIGHT_ENABLE | ||
86 | backlight_set(0); | ||
87 | # endif | ||
88 | |||
89 | // Turn off LED indicators | ||
90 | uint8_t leds_off = 0; | ||
91 | # if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) | ||
92 | if (is_backlight_enabled()) { | ||
93 | // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off | ||
94 | leds_off |= (1 << USB_LED_CAPS_LOCK); | ||
95 | } | ||
96 | # endif | ||
97 | led_set(leds_off); | ||
98 | |||
99 | # ifdef AUDIO_ENABLE | ||
100 | // This sometimes disables the start-up noise, so it's been disabled | ||
101 | // stop_all_notes(); | ||
102 | # endif /* AUDIO_ENABLE */ | ||
103 | # if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) | ||
104 | rgblight_suspend(); | ||
105 | # endif | ||
106 | suspend_power_down_kb(); | ||
107 | |||
108 | // TODO: more power saving | 102 | // TODO: more power saving |
109 | // See PicoPower application note | 103 | // See PicoPower application note |
110 | // - I/O port input with pullup | 104 | // - I/O port input with pullup |
@@ -127,10 +121,46 @@ static void power_down(uint8_t wdto) { | |||
127 | * FIXME: needs doc | 121 | * FIXME: needs doc |
128 | */ | 122 | */ |
129 | void suspend_power_down(void) { | 123 | void suspend_power_down(void) { |
124 | #ifdef PROTOCOL_LUFA | ||
125 | if (USB_DeviceState == DEVICE_STATE_Configured) return; | ||
126 | #endif | ||
127 | #ifdef PROTOCOL_VUSB | ||
128 | if (!vusb_suspended) return; | ||
129 | #endif | ||
130 | |||
130 | suspend_power_down_kb(); | 131 | suspend_power_down_kb(); |
131 | 132 | ||
132 | #ifndef NO_SUSPEND_POWER_DOWN | 133 | #ifndef NO_SUSPEND_POWER_DOWN |
134 | // Turn off backlight | ||
135 | # ifdef BACKLIGHT_ENABLE | ||
136 | backlight_set(0); | ||
137 | # endif | ||
138 | |||
139 | // Turn off LED indicators | ||
140 | uint8_t leds_off = 0; | ||
141 | # if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE) | ||
142 | if (is_backlight_enabled()) { | ||
143 | // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off | ||
144 | leds_off |= (1 << USB_LED_CAPS_LOCK); | ||
145 | } | ||
146 | # endif | ||
147 | led_set(leds_off); | ||
148 | |||
149 | // Turn off audio | ||
150 | # ifdef AUDIO_ENABLE | ||
151 | // This sometimes disables the start-up noise, so it's been disabled | ||
152 | // stop_all_notes(); | ||
153 | # endif | ||
154 | |||
155 | // Turn off underglow | ||
156 | # if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) | ||
157 | rgblight_suspend(); | ||
158 | # endif | ||
159 | |||
160 | // Enter sleep state if possible (ie, the MCU has a watchdog timeout interrupt) | ||
161 | # if defined(WDT_vect) | ||
133 | power_down(WDTO_15MS); | 162 | power_down(WDTO_15MS); |
163 | # endif | ||
134 | #endif | 164 | #endif |
135 | } | 165 | } |
136 | 166 | ||
@@ -164,17 +194,24 @@ __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_us | |||
164 | void suspend_wakeup_init(void) { | 194 | void suspend_wakeup_init(void) { |
165 | // clear keyboard state | 195 | // clear keyboard state |
166 | clear_keyboard(); | 196 | clear_keyboard(); |
197 | |||
198 | // Turn on backlight | ||
167 | #ifdef BACKLIGHT_ENABLE | 199 | #ifdef BACKLIGHT_ENABLE |
168 | backlight_init(); | 200 | backlight_init(); |
169 | #endif | 201 | #endif |
202 | |||
203 | // Restore LED indicators | ||
170 | led_set(host_keyboard_leds()); | 204 | led_set(host_keyboard_leds()); |
205 | |||
206 | // Wake up underglow | ||
171 | #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) | 207 | #if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) |
172 | rgblight_wakeup(); | 208 | rgblight_wakeup(); |
173 | #endif | 209 | #endif |
210 | |||
174 | suspend_wakeup_init_kb(); | 211 | suspend_wakeup_init_kb(); |
175 | } | 212 | } |
176 | 213 | ||
177 | #ifndef NO_SUSPEND_POWER_DOWN | 214 | #if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect) |
178 | /* watchdog timeout */ | 215 | /* watchdog timeout */ |
179 | ISR(WDT_vect) { | 216 | ISR(WDT_vect) { |
180 | // compensate timer for sleep | 217 | // 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 6df048f3b..000000000 --- a/tmk_core/common/avr/suspend_avr.h +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | #pragma once | ||
2 | |||
3 | #include <stdint.h> | ||
4 | #include <stdbool.h> | ||
5 | #include <avr/sleep.h> | ||
6 | #include <avr/wdt.h> | ||
7 | #include <avr/interrupt.h> | ||
8 | |||
9 | // clang-format off | ||
10 | #define wdt_intr_enable(value) \ | ||
11 | __asm__ __volatile__ ( \ | ||
12 | "in __tmp_reg__,__SREG__" "\n\t" \ | ||
13 | "cli" "\n\t" \ | ||
14 | "wdr" "\n\t" \ | ||
15 | "sts %0,%1" "\n\t" \ | ||
16 | "out __SREG__,__tmp_reg__" "\n\t" \ | ||
17 | "sts %0,%2" "\n\t" \ | ||
18 | : /* no outputs */ \ | ||
19 | : "M" (_SFR_MEM_ADDR(_WD_CONTROL_REG)), \ | ||
20 | "r" (_BV(_WD_CHANGE_BIT) | _BV(WDE)), \ | ||
21 | "r" ((uint8_t) ((value & 0x08 ? _WD_PS3_MASK : 0x00) | \ | ||
22 | _BV(WDIE) | (value & 0x07)) ) \ | ||
23 | : "r0" \ | ||
24 | ) | ||
25 | // clang-format on | ||