Commit e17d9ea8 authored by mntmn's avatar mntmn
Browse files

Merge remote-tracking branch 'origin/master' into wip-lpc-powersave

parents 39cc9f06 0ce90046
......@@ -39,8 +39,9 @@
#include "ssd1306.h"
#include "scancodes.h"
#include <stdlib.h>
#include <avr/sleep.h>
#define KBD_FW_REV "R1 20210419"
#define KBD_FW_REV "R1 20210815"
//#define KBD_VARIANT_STANDALONE
#define KBD_VARIANT_QWERTY_US
//#define KBD_VARIANT_NEO2
......@@ -509,7 +510,7 @@ const MenuItem menu_items[] = {
{ "System Status s", KEY_S }
};
#else
#define MENU_NUM_ITEMS 9
#define MENU_NUM_ITEMS 10
const MenuItem menu_items[] = {
{ "Exit Menu ESC", KEY_ESCAPE },
{ "Power On 1", KEY_1 },
......@@ -519,7 +520,8 @@ const MenuItem menu_items[] = {
{ "Key Backlight- F1", KEY_F1 },
{ "Key Backlight+ F2", KEY_F2 },
{ "Wake SPC", KEY_SPACE },
{ "System Status s", KEY_S }
{ "System Status s", KEY_S },
{ "KBD Power-Off p", KEY_P }
};
#endif
......@@ -551,6 +553,7 @@ int execute_meta_function(int keycode) {
if (keycode == KEY_0) {
// TODO: are you sure?
remote_turn_off_som();
EnterPowerOff();
}
else if (keycode == KEY_1) {
remote_turn_on_som();
......@@ -607,6 +610,9 @@ int execute_meta_function(int keycode) {
gfx_clear();
gfx_flush();
}
else if (keycode == KEY_P) {
EnterPowerOff();
}
gfx_clear();
gfx_flush();
......@@ -811,6 +817,70 @@ void SetupHardware()
USB_Init();
}
/* Setup the AVR to enter the Power-Down state to greatly save power.
* Configures all outputs to be in the low state if possible, and disables
* services like USB and Serial.
*
* Will leave the ports setup so that the Circle key row is being scanned
* so when the watchdog wakes up it can quickly check and go back to sleep if not
* Added by Chartreuse - 2021/08/14
*
*/
void EnterPowerOff(void)
{
USB_Disable(); // Stop USB stack so it doesn't wake us up
kbd_brightness_set(0);
// Turn off OLED to save power
gfx_clear_screen();
gfx_off();
// Disable ADC to save even more power
ADCSRA=0;
cli(); // No interrupts
// Set all ports not floating if possible, leaving pullups alone
PORTB=0x3F; // Leave pull-up on all the columns on PB0-3, drive rows 2-3 high, 1-low
PORTC=0xC0;
PORTD=0xF0; // Keep pullup on PD5 like setup did, drive rows 4,5,6 high
PORTE=0x40; // Pullup on PE6
PORTF=0xFF; // Pullups on PF (columns)
// ROW1 is the only row driven low and left low, thus is always ready to be read out
// We just need to check COL14 (PC6) if it is low (pressed) or high
// Unfortunatly the circle key is on COL14(PC6) which doesn't have pin change interrupt
// capabilities, so we need to wake up every so often to check if it is pressed, and
// if so bring us out of power-off
// We can use the Watchdog timer to do this.
do {
wdt_reset();
WDTCSR = (1<<WDCE) | (1<<WDE); // Enable writes to watchdog
WDTCSR = (1<<WDIE) | (1<<WDE) | (1<<WDP2) | (1<<WDP1) | (1<<WDP0); // Interrupt mode, 1s timeout
// Enter Power-save mode
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sei(); // Enable interrupts so we can actually wake
sleep_cpu(); // Actually go to sleep
// Zzzzzz
sleep_disable(); // We've woken up
sei();
// Check if circle key has been pressed (active-low)
// If not reset the watchdog and try again
} while(PINC&(1<<6));
// Resume and reinitialize hardware
SetupHardware();
}
ISR(WDT_vect)
{
// WDT interrupt enable and flag cleared on entry
wdt_disable(); // Disable watchdog for now
}
/** Event handler for the library USB Connection event. */
void EVENT_USB_Device_Connect(void)
{
......
......@@ -67,6 +67,7 @@
/* Function Prototypes: */
void SetupHardware(void);
void EnterPowerOff(void);
void EVENT_USB_Device_Connect(void);
void EVENT_USB_Device_Disconnect(void);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment