aboutsummaryrefslogtreecommitdiffstats
path: root/tools/autoconf
Commit message (Expand)AuthorAgeFilesLines
* treewide: clean up download hashesFelix Fietkau2016-12-161-1/+1
* tools/autoconf: fix compile on musl hostsImre Kaloz2015-05-041-0/+24
* autoconf: portability fixesJo-Philipp Wich2015-03-243-22/+84
* autoconf: bump version to 2.69Steven Barth2014-10-091-4/+4
* autoconf: another relocatability fix for autom4te, substitute hardcoded prefi...Jo-Philipp Wich2012-01-281-0/+13
* autoconf: make bin/autoconf relocatable as wellJo-Philipp Wich2012-01-201-0/+15
* autoconf: further relocation fixesJo-Philipp Wich2012-01-201-4/+43
* autoconf: make relocatable by searching resources relative to STAGING_DIRJo-Philipp Wich2012-01-202-1/+101
* tools/autoconf: update to version 2.68Alexandros C. Couloumbis2010-12-061-2/+2
* clean up / fix various Host/Clean templates in tools/Felix Fietkau2009-05-081-1/+1
* build system refactoring in preparation for allowing packages to do host-buil...Felix Fietkau2009-02-221-9/+9
* tools: refresh patches for tools lua, mtd-utils, ipkg-utils, squashfs, lzma, ...Hauke Mehrtens2009-02-211-7/+5
* Do not try to build autoconf emacs library, as it can fail on some systems li...Florian Fainelli2008-09-091-0/+24
* fix autoconf compilation (#3956)Felix Fietkau2008-09-081-4/+3
* add autoconf (fixes opkg build issues)Felix Fietkau2008-08-271-0/+38
'>201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
#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"
#include "led.h"
#include "host.h"
#include "rgblight_reconfig.h"
#ifdef SPLIT_KEYBOARD
  #include "split_flags.h"
#endif

#ifdef PROTOCOL_LUFA
	#include "lufa.h"
#endif

#ifdef AUDIO_ENABLE
    #include "audio.h"
#endif /* AUDIO_ENABLE */

#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
  #include "rgblight.h"
  extern rgblight_config_t rgblight_config;
  static bool rgblight_enabled;
  static bool is_suspended;
#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"  \
)


/** \brief Suspend idle
 *
 * FIXME: needs doc
 */
void suspend_idle(uint8_t time) {
    cli();
    set_sleep_mode(SLEEP_MODE_IDLE);
    sleep_enable();
    sei();
    sleep_cpu();
    sleep_disable();
}


// TODO: This needs some cleanup

/** \brief Run keyboard level Power down
 *
 * FIXME: needs doc
 */
__attribute__ ((weak))
void suspend_power_down_user (void) { }
/** \brief Run keyboard level Power down
 *
 * FIXME: needs doc
 */
__attribute__ ((weak))
void suspend_power_down_kb(void) {
  suspend_power_down_user();
}

#ifndef NO_SUSPEND_POWER_DOWN
/** \brief 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;

/** \brief Power down
 *
 * FIXME: needs doc
 */
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);

#ifdef BACKLIGHT_ENABLE
  backlight_set(0);
#endif

  // Turn off LED indicators
  uint8_t leds_off = 0;
#if defined(BACKLIGHT_CAPS_LOCK) && defined(BACKLIGHT_ENABLE)
  if (is_backlight_enabled()) {
    // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off
    leds_off |= (1<<USB_LED_CAPS_LOCK);
  }
#endif
  led_set(leds_off);

#ifdef AUDIO_ENABLE
  // This sometimes disables the start-up noise, so it's been disabled
  // stop_all_notes();
#endif /* AUDIO_ENABLE */
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
#ifdef RGBLIGHT_ANIMATIONS
  rgblight_timer_disable();
#endif
  if (!is_suspended) {
    is_suspended = true;
    rgblight_enabled = rgblight_config.enable;
    rgblight_disable_noeeprom();
    #ifdef SPLIT_KEYBOARD
        RGB_DIRTY = true;
    #endif
  }
#endif
  suspend_power_down_kb();

    // 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();
}
#endif

/** \brief Suspend power down
 *
 * FIXME: needs doc
 */
void suspend_power_down(void) {
	suspend_power_down_kb();

#ifndef NO_SUSPEND_POWER_DOWN
    power_down(WDTO_15MS);
#endif
}

__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}
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;
}

/** \brief run user level code immediately after wakeup
 *
 * FIXME: needs doc
 */
__attribute__ ((weak))
void suspend_wakeup_init_user(void) { }

/** \brief run keyboard level code immediately after wakeup
 *
 * FIXME: needs doc
 */
__attribute__ ((weak))
void suspend_wakeup_init_kb(void) {
  suspend_wakeup_init_user();
}
/** \brief run immediately after wakeup
 *
 * FIXME: needs doc
 */
void suspend_wakeup_init(void) {
    // clear keyboard state
    clear_keyboard();
#ifdef BACKLIGHT_ENABLE
    backlight_init();
#endif
	led_set(host_keyboard_leds());
#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE)
  is_suspended = false;
  if (rgblight_enabled) {
    #ifdef BOOTLOADER_TEENSY
      wait_ms(10);
    #endif
    rgblight_enable_noeeprom();
    #ifdef SPLIT_KEYBOARD
        RGB_DIRTY = true;
    #endif
  }
#ifdef RGBLIGHT_ANIMATIONS
  rgblight_timer_enable();
#endif
#endif
    suspend_wakeup_init_kb();
}

#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