aboutsummaryrefslogtreecommitdiff
path: root/tmk_core/common/avr
diff options
context:
space:
mode:
authorfauxpark <fauxpark@gmail.com>2021-02-25 16:04:53 +1100
committerfauxpark <fauxpark@gmail.com>2021-02-25 16:04:53 +1100
commit23fd1aee00c762b1e9496795ad595325be82a956 (patch)
tree4b6a68d6015f6a730f8c15baf7103010f0f8ad56 /tmk_core/common/avr
parent23ef327e118307d276677d30e3fda064ace6713b (diff)
parent39694d5eb0b7e48e06f9544600041fbbedfff956 (diff)
downloadqmk_firmware-23fd1aee00c762b1e9496795ad595325be82a956.tar.gz
qmk_firmware-23fd1aee00c762b1e9496795ad595325be82a956.zip
Merge remote-tracking branch 'upstream/master' into develop
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.c92
-rw-r--r--tmk_core/common/avr/suspend_avr.h25
3 files changed, 66 insertions, 53 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 */
96static 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}; 96static 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 b784a0835..47a82a2ee 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,35 +94,11 @@ static uint8_t wdt_timeout = 0;
74 * FIXME: needs doc 94 * FIXME: needs doc
75 */ 95 */
76static void power_down(uint8_t wdto) { 96static 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 stop_all_notes();
101# endif /* AUDIO_ENABLE */
102# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
103 rgblight_suspend();
104# endif
105
106 // TODO: more power saving 102 // TODO: more power saving
107 // See PicoPower application note 103 // See PicoPower application note
108 // - I/O port input with pullup 104 // - I/O port input with pullup
@@ -125,10 +121,45 @@ static void power_down(uint8_t wdto) {
125 * FIXME: needs doc 121 * FIXME: needs doc
126 */ 122 */
127void suspend_power_down(void) { 123void 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
128 suspend_power_down_kb(); 131 suspend_power_down_kb();
129 132
130#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 stop_all_notes();
152# endif
153
154 // Turn off underglow
155# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
156 rgblight_suspend();
157# endif
158
159 // Enter sleep state if possible (ie, the MCU has a watchdog timeout interrupt)
160# if defined(WDT_vect)
131 power_down(WDTO_15MS); 161 power_down(WDTO_15MS);
162# endif
132#endif 163#endif
133} 164}
134 165
@@ -163,17 +194,24 @@ __attribute__((weak)) void suspend_wakeup_init_kb(void) { suspend_wakeup_init_us
163void suspend_wakeup_init(void) { 194void suspend_wakeup_init(void) {
164 // clear keyboard state 195 // clear keyboard state
165 clear_keyboard(); 196 clear_keyboard();
197
198 // Turn on backlight
166#ifdef BACKLIGHT_ENABLE 199#ifdef BACKLIGHT_ENABLE
167 backlight_init(); 200 backlight_init();
168#endif 201#endif
202
203 // Restore LED indicators
169 led_set(host_keyboard_leds()); 204 led_set(host_keyboard_leds());
205
206 // Wake up underglow
170#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) 207#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
171 rgblight_wakeup(); 208 rgblight_wakeup();
172#endif 209#endif
210
173 suspend_wakeup_init_kb(); 211 suspend_wakeup_init_kb();
174} 212}
175 213
176#ifndef NO_SUSPEND_POWER_DOWN 214#if !defined(NO_SUSPEND_POWER_DOWN) && defined(WDT_vect)
177/* watchdog timeout */ 215/* watchdog timeout */
178ISR(WDT_vect) { 216ISR(WDT_vect) {
179 // 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