This repository has been archived on 2025-02-01. You can view files and clone it, but cannot push or open issues or pull requests.
tmk_keyboard/common/avr/suspend.c
tmk 22b6e15a17 Squashed 'tmk_core/' changes from 8da1898..e5f9940
e5f9940 Merge commit '1bc3dd200b023cecf063a0cb3ba347f77f6d759d' into core_update
da03c50 Add note for L/R side bit being ignored
e80f3c1 Add in basic documentation for Macro system
35e8a76 core: Swap position of PEQL and PENT in unimap
00751f1 Merge pull request #406 from 39aldo39/patch-1
e50d7de V-USB remote wakeup
4340997 core: Fix typo in definition AC_g
958144d core: Debug print for system and consumer keys
e7e1030 core: Fix sleep_led
0866323 core: Change matrix_init and matrix_print
0dbf73d core: Add matrix_clear() and default impl.
3202ca3 core: Add suspend mode options
4cda3aa core: Fix suspend/wake for converters #386
4e15247 core: LUFA_DEBUG_SUART for serial debug
b9cf8e7 core: Fix mechanical locking supoort #390
12aa0fd Merge branch 'nemith-master'
fccb3fa core: Fix OPT_DEFS for mbed build
2e2d2c8 Merge branch 'master' of github.com:leizzer/tmk_keyboard
f1d3634 Change .gitignore for ChibiOS
3aab802 core: Fix build config in protocol.mk
5e43da0 core: Add short names in unimap
7a56998 core: Fix dfu wait in rules.mk
6d9c500 Merge branch 'mediakey-fix'
08382ac core: Fix 'make dfu' message
78cb04e Fix OS X Recognizing keyboard as Mouse/Tablet
a114714 core: 'make dfu' waits for bootloader to start
d0a8f13 core: Fix unimap UNIMAP_NO case
e17abef core: Change lufa NKRO report size 16 to 32 bytes
375b20f core: Fix common.mk for build options
394fdff core: Fix unimap layout comment
912326c core: Add unimap support
00f4011 core: Fix doc/keymap.md for new keymap framework
ddbd7b4 core: Add default implemenation of keymap read
671cacc core: action codes are action_t struct now
b4fdb27 core: Change chibios repo directory names
7daed10 core: Fix keycode.txt
90399d7 core: Fix USB remote wakeup on ATmega32U2 #361
3677e84 usb_usb: Add multiple keyboard support
54d5b26 core: Fix Logical Maximum in report descriptor
bd0d372 core: Fix LUFA report descriptor
95327b5 Merge pull request #355 from papodaca/XT
62bf548 core: change API of adb.c to accept device address
3097c9e Fix function name in host.h
836e209 Merge branch 'core_split_160522'
3918ea2 Merge commit '20b787fc1284176834cbe7ca2134e4b36bec5828'
7f87b11 core: Add comment of register 3 of ADB
ef6478a core: Add adb_host_talk()
5c665b4 update macro names in bluefruit
4f2c5bf Merge commit '71381457fa1311dfa0b58ba882a96db740640871'
53a9c08 Merge pull request #321 from njbair/master
f08a656 core: Fix media/consumer keys
d526de8 Clean up wording in keymap example
0bb3dbb Clarify layer precedence
d915c75 clarify layer documentation
72070d4 ps2_usb: Fix for VUSB configuration
170e2dc Mostly working. Is unstable, will emit bad codes after a while.
c8e45b5 core: Actionmap support
aabaa24 Codes appear to be detected correctly, the break codes are broken.

git-subtree-dir: tmk_core
git-subtree-split: e5f994033cbc8700745ac0c6d12772820492eed0
2016-12-10 10:29:51 +09:00

147 lines
2.9 KiB
C

#include <stdbool.h>
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include "matrix.h"
#include "action.h"
#include "backlight.h"
#include "suspend_avr.h"
#include "suspend.h"
#include "timer.h"
#ifdef PROTOCOL_LUFA
#include "lufa.h"
#endif
#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" \
)
/* Power down MCU with watchdog timer
* wdto: watchdog timer timeout defined in <avr/wdt.h>
* WDTO_15MS
* WDTO_30MS
* WDTO_60MS
* WDTO_120MS
* WDTO_250MS
* WDTO_500MS
* WDTO_1S
* WDTO_2S
* WDTO_4S
* WDTO_8S
*/
static uint8_t wdt_timeout = 0;
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);
// TODO: more power saving
// See PicoPower application note
// - I/O port input with pullup
// - prescale clock
// - BOD disable
// - Power Reduction Register PRR
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
// Disable watchdog after sleep
wdt_disable();
}
static void standby(void)
{
set_sleep_mode(SLEEP_MODE_STANDBY);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
static void idle(void)
{
set_sleep_mode(SLEEP_MODE_IDLE);
sleep_enable();
sei();
sleep_cpu();
sleep_disable();
}
void suspend_idle(uint8_t time)
{
idle();
}
void suspend_power_down(void)
{
#ifdef NO_SUSPEND_POWER_DOWN
;
#elif defined(SUSPEND_MODE_NOPOWERSAVE)
;
#elif defined(SUSPEND_MODE_STANDBY)
standby();
#elif defined(SUSPEND_MODE_IDLE)
idle();
#else
power_down(WDTO_15MS);
#endif
}
bool suspend_wakeup_condition(void)
{
matrix_power_up();
matrix_scan();
matrix_power_down();
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
if (matrix_get_row(r)) return true;
}
return false;
}
// run immediately after wakeup
void suspend_wakeup_init(void)
{
// clear keyboard state
matrix_clear();
clear_keyboard();
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif
}
#ifndef NO_SUSPEND_POWER_DOWN
/* watchdog timeout */
ISR(WDT_vect)
{
// compensate timer for sleep
switch (wdt_timeout) {
case WDTO_15MS:
timer_count += 15 + 2; // WDTO_15MS + 2(from observation)
break;
default:
;
}
}
#endif