aboutsummaryrefslogtreecommitdiff
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
parent23ef327e118307d276677d30e3fda064ace6713b (diff)
parent39694d5eb0b7e48e06f9544600041fbbedfff956 (diff)
downloadqmk_firmware-23fd1aee00c762b1e9496795ad595325be82a956.tar.gz
qmk_firmware-23fd1aee00c762b1e9496795ad595325be82a956.zip
Merge remote-tracking branch 'upstream/master' into develop
-rw-r--r--quantum/mcu_selection.mk13
-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
-rw-r--r--tmk_core/protocol/vusb/main.c54
-rw-r--r--tmk_core/protocol/vusb/vusb.h3
6 files changed, 106 insertions, 83 deletions
diff --git a/quantum/mcu_selection.mk b/quantum/mcu_selection.mk
index 81c467c65..f7329fc4d 100644
--- a/quantum/mcu_selection.mk
+++ b/quantum/mcu_selection.mk
@@ -400,9 +400,6 @@ ifneq (,$(filter $(MCU),atmega32a))
400 # calculate timings. Do NOT tack on a 'UL' at the end, this will be done 400 # calculate timings. Do NOT tack on a 'UL' at the end, this will be done
401 # automatically to create a 32-bit value in your source code. 401 # automatically to create a 32-bit value in your source code.
402 F_CPU ?= 12000000 402 F_CPU ?= 12000000
403
404 # unsupported features for now
405 NO_SUSPEND_POWER_DOWN ?= yes
406endif 403endif
407 404
408ifneq (,$(filter $(MCU),atmega328p)) 405ifneq (,$(filter $(MCU),atmega328p))
@@ -417,9 +414,6 @@ ifneq (,$(filter $(MCU),atmega328p))
417 # calculate timings. Do NOT tack on a 'UL' at the end, this will be done 414 # calculate timings. Do NOT tack on a 'UL' at the end, this will be done
418 # automatically to create a 32-bit value in your source code. 415 # automatically to create a 32-bit value in your source code.
419 F_CPU ?= 16000000 416 F_CPU ?= 16000000
420
421 # unsupported features for now
422 NO_SUSPEND_POWER_DOWN ?= yes
423endif 417endif
424 418
425ifneq (,$(filter $(MCU),atmega328)) 419ifneq (,$(filter $(MCU),atmega328))
@@ -434,10 +428,6 @@ ifneq (,$(filter $(MCU),atmega328))
434 # calculate timings. Do NOT tack on a 'UL' at the end, this will be done 428 # calculate timings. Do NOT tack on a 'UL' at the end, this will be done
435 # automatically to create a 32-bit value in your source code. 429 # automatically to create a 32-bit value in your source code.
436 F_CPU ?= 16000000 430 F_CPU ?= 16000000
437
438 # unsupported features for now
439 NO_UART ?= yes
440 NO_SUSPEND_POWER_DOWN ?= yes
441endif 431endif
442 432
443ifneq (,$(filter $(MCU),attiny85)) 433ifneq (,$(filter $(MCU),attiny85))
@@ -449,7 +439,4 @@ ifneq (,$(filter $(MCU),attiny85))
449 # calculate timings. Do NOT tack on a 'UL' at the end, this will be done 439 # calculate timings. Do NOT tack on a 'UL' at the end, this will be done
450 # automatically to create a 32-bit value in your source code. 440 # automatically to create a 32-bit value in your source code.
451 F_CPU ?= 16500000 441 F_CPU ?= 16500000
452
453 # unsupported features for now
454 NO_SUSPEND_POWER_DOWN ?= yes
455endif 442endif
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
diff --git a/tmk_core/protocol/vusb/main.c b/tmk_core/protocol/vusb/main.c
index 3f93ef6d2..4095979e9 100644
--- a/tmk_core/protocol/vusb/main.c
+++ b/tmk_core/protocol/vusb/main.c
@@ -53,10 +53,10 @@ static void initForUsbConnectivity(void) {
53 usbDeviceConnect(); 53 usbDeviceConnect();
54} 54}
55 55
56static void usb_remote_wakeup(void) { 56static void vusb_send_remote_wakeup(void) {
57 cli(); 57 cli();
58 58
59 int8_t ddr_orig = USBDDR; 59 uint8_t ddr_orig = USBDDR;
60 USBOUT |= (1 << USBMINUS); 60 USBOUT |= (1 << USBMINUS);
61 USBDDR = ddr_orig | USBMASK; 61 USBDDR = ddr_orig | USBMASK;
62 USBOUT ^= USBMASK; 62 USBOUT ^= USBMASK;
@@ -70,6 +70,27 @@ static void usb_remote_wakeup(void) {
70 sei(); 70 sei();
71} 71}
72 72
73bool vusb_suspended = false;
74
75static void vusb_suspend(void) {
76 vusb_suspended = true;
77
78#ifdef SLEEP_LED_ENABLE
79 sleep_led_enable();
80#endif
81
82 suspend_power_down();
83}
84
85static void vusb_wakeup(void) {
86 vusb_suspended = false;
87 suspend_wakeup_init();
88
89#ifdef SLEEP_LED_ENABLE
90 sleep_led_disable();
91#endif
92}
93
73/** \brief Setup USB 94/** \brief Setup USB
74 * 95 *
75 * FIXME: Needs doc 96 * FIXME: Needs doc
@@ -82,9 +103,8 @@ static void setup_usb(void) { initForUsbConnectivity(); }
82 */ 103 */
83int main(void) __attribute__((weak)); 104int main(void) __attribute__((weak));
84int main(void) { 105int main(void) {
85 bool suspended = false;
86#if USB_COUNT_SOF 106#if USB_COUNT_SOF
87 uint16_t last_timer = timer_read(); 107 uint16_t sof_timer = timer_read();
88#endif 108#endif
89 109
90#ifdef CLKPR 110#ifdef CLKPR
@@ -107,23 +127,24 @@ int main(void) {
107 while (1) { 127 while (1) {
108#if USB_COUNT_SOF 128#if USB_COUNT_SOF
109 if (usbSofCount != 0) { 129 if (usbSofCount != 0) {
110 suspended = false;
111 usbSofCount = 0; 130 usbSofCount = 0;
112 last_timer = timer_read(); 131 sof_timer = timer_read();
113# ifdef SLEEP_LED_ENABLE 132 if (vusb_suspended) {
114 sleep_led_disable(); 133 vusb_wakeup();
115# endif 134 }
116 } else { 135 } else {
117 // Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1) 136 // Suspend when no SOF in 3ms-10ms(7.1.7.4 Suspending of USB1.1)
118 if (timer_elapsed(last_timer) > 5) { 137 if (!vusb_suspended && timer_elapsed(sof_timer) > 5) {
119 suspended = true; 138 vusb_suspend();
120# ifdef SLEEP_LED_ENABLE
121 sleep_led_enable();
122# endif
123 } 139 }
124 } 140 }
125#endif 141#endif
126 if (!suspended) { 142 if (vusb_suspended) {
143 vusb_suspend();
144 if (suspend_wakeup_condition()) {
145 vusb_send_remote_wakeup();
146 }
147 } else {
127 usbPoll(); 148 usbPoll();
128 149
129 // TODO: configuration process is inconsistent. it sometime fails. 150 // TODO: configuration process is inconsistent. it sometime fails.
@@ -140,6 +161,7 @@ int main(void) {
140 raw_hid_task(); 161 raw_hid_task();
141 } 162 }
142#endif 163#endif
164
143#ifdef CONSOLE_ENABLE 165#ifdef CONSOLE_ENABLE
144 usbPoll(); 166 usbPoll();
145 167
@@ -151,8 +173,6 @@ int main(void) {
151 // Run housekeeping 173 // Run housekeeping
152 housekeeping_task_kb(); 174 housekeeping_task_kb();
153 housekeeping_task_user(); 175 housekeeping_task_user();
154 } else if (suspend_wakeup_condition()) {
155 usb_remote_wakeup();
156 } 176 }
157 } 177 }
158} 178}
diff --git a/tmk_core/protocol/vusb/vusb.h b/tmk_core/protocol/vusb/vusb.h
index b4c73aaba..b1ecc98f3 100644
--- a/tmk_core/protocol/vusb/vusb.h
+++ b/tmk_core/protocol/vusb/vusb.h
@@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
18#pragma once 18#pragma once
19 19
20#include "host_driver.h" 20#include "host_driver.h"
21#include <usbdrv/usbdrv.h>
21 22
22typedef struct usbDescriptorHeader { 23typedef struct usbDescriptorHeader {
23 uchar bLength; 24 uchar bLength;
@@ -119,5 +120,7 @@ typedef struct usbConfigurationDescriptor {
119 120
120#define USB_STRING_LEN(s) (sizeof(usbDescriptorHeader_t) + ((s) << 1)) 121#define USB_STRING_LEN(s) (sizeof(usbDescriptorHeader_t) + ((s) << 1))
121 122
123extern bool vusb_suspended;
124
122host_driver_t *vusb_driver(void); 125host_driver_t *vusb_driver(void);
123void vusb_transfer_keyboard(void); 126void vusb_transfer_keyboard(void);