diff options
| author | tmk <nobody@nowhere> | 2013-03-15 22:22:57 +0900 | 
|---|---|---|
| committer | tmk <nobody@nowhere> | 2013-03-16 17:24:05 +0900 | 
| commit | f0c5f1b910ecf9536e5b95cc4ca9a43b0f4b2c36 (patch) | |
| tree | f68e720804c1c82109c1de19dc3cc7d9eb2cabf0 | |
| parent | 42f6ff088652827a82474c3a07f4c2c9497bacd9 (diff) | |
| download | firmware-f0c5f1b910ecf9536e5b95cc4ca9a43b0f4b2c36.tar.gz firmware-f0c5f1b910ecf9536e5b95cc4ca9a43b0f4b2c36.tar.bz2 firmware-f0c5f1b910ecf9536e5b95cc4ca9a43b0f4b2c36.zip | |
Add breathing sleep LED during USB suspend
| -rw-r--r-- | common.mk | 6 | ||||
| -rw-r--r-- | common/sleep_led.c | 84 | ||||
| -rw-r--r-- | common/sleep_led.h | 10 | ||||
| -rw-r--r-- | keyboard/gh60/Makefile.lufa | 1 | ||||
| -rw-r--r-- | protocol/lufa/lufa.c | 36 | 
5 files changed, 128 insertions, 9 deletions
| @@ -47,5 +47,11 @@ ifdef $(or MOUSEKEY_ENABLE, PS2_MOUSE_ENABLE)      OPT_DEFS += -DMOUSE_ENABLE  endif +ifdef SLEEP_LED_ENABLE +    SRC += $(COMMON_DIR)/sleep_led.c +    OPT_DEFS += -DSLEEP_LED_ENABLE +endif + +  # Search Path  VPATH += $(TOP_DIR)/common diff --git a/common/sleep_led.c b/common/sleep_led.c new file mode 100644 index 000000000..edf68c352 --- /dev/null +++ b/common/sleep_led.c @@ -0,0 +1,84 @@ +#include <stdint.h> +#include <avr/io.h> +#include <avr/interrupt.h> +#include <avr/pgmspace.h> +#include "led.h" +#include "sleep_led.h" + +/* Software PWM + *  ______           ______           __ + * |  ON  |___OFF___|  ON  |___OFF___|   .... + * |<-------------->|<-------------->|<- .... + *     PWM period       PWM period + * + * 256              interrupts/period[resolution] + * 64               periods/second[frequency] + * 256*64           interrupts/second + * F_CPU/(256*64)   clocks/interrupt + */ +#define SLEEP_LED_TIMER_TOP F_CPU/(256*64) + +void sleep_led_init(void) +{ +    /* Timer1 setup */ +    /* CTC mode */ +    TCCR1B |= _BV(WGM12); +    /* Clock selelct: clk/1 */ +    TCCR1B |= _BV(CS10); +    /* Set TOP value */ +    uint8_t sreg = SREG; +    cli(); +    OCR1AH = (SLEEP_LED_TIMER_TOP>>8)&0xff; +    OCR1AL = SLEEP_LED_TIMER_TOP&0xff; +    SREG = sreg; +} + +void sleep_led_enable(void) +{ +    /* Enable Compare Match Interrupt */ +    TIMSK1 |= _BV(OCIE1A); +} + +void sleep_led_disable(void) +{ +    /* Disable Compare Match Interrupt */ +    TIMSK1 &= ~_BV(OCIE1A); +} + + +/* Breathing Sleep LED brighness(PWM On period) table + * (32[steps] * 8[duration]) / 64[PWM periods/s] = 4 second breath cycle + */ +static const uint8_t breathing_table[32] PROGMEM = { +    0, 0, 0, 2, 9, 21, 37, 56, 78, 127, 151, 175, 197, 216, 232, 244, +    254, 244, 216, 197, 175, 151, 127, 78, 56, 37, 21, 9, 2, 0, 0, 0 +}; + +ISR(TIMER1_COMPA_vect) +{ +    /* Software PWM +     * timer:1111 1111 1111 1111 +     *       \----/\-/ \-------/+---  count(0-255) +     *         |    +---------------  duration of step(8) +     *         +--------------------  index of step table(0-31) +     */ +    static union { +        uint16_t row; +        struct { +            uint8_t count:8; +            uint8_t duration:3; +            uint8_t index:5; +        } pwm; +    } timer = { .row = 0 }; + +    timer.row++; +     +    // LED on +    if (timer.pwm.count == 0) { +        led_set(1<<USB_LED_CAPS_LOCK); +    } +    // LED off +    if (timer.pwm.count == pgm_read_byte(&breathing_table[timer.pwm.index])) { +        led_set(0); +    } +} diff --git a/common/sleep_led.h b/common/sleep_led.h new file mode 100644 index 000000000..aebdbeaa5 --- /dev/null +++ b/common/sleep_led.h @@ -0,0 +1,10 @@ +#ifndef SLEEP_LED_H +#define SLEEP_LED_H + +#define NO_SUSPEND_POWER_DOWN + +void sleep_led_init(void); +void sleep_led_enable(void); +void sleep_led_disable(void); + +#endif diff --git a/keyboard/gh60/Makefile.lufa b/keyboard/gh60/Makefile.lufa index a5ff609a7..8042ff3f4 100644 --- a/keyboard/gh60/Makefile.lufa +++ b/keyboard/gh60/Makefile.lufa @@ -103,6 +103,7 @@ BOOTMAGIC_ENABLE = yes	# Virtual DIP switch configuration(+1000)  MOUSEKEY_ENABLE = yes	# Mouse keys(+4700)  EXTRAKEY_ENABLE = yes	# Audio control and System control(+450)  CONSOLE_ENABLE = yes	# Console for debug(+400) +SLEEP_LED_ENABLE = yes  # Breathing sleep LED during USB suspend  #NKRO_ENABLE = yes	# USB Nkey Rollover - not yet supported in LUFA  #PS2_MOUSE_ENABLE = yes	# PS/2 mouse(TrackPoint) support diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c index 556d0aeec..127dece54 100644 --- a/protocol/lufa/lufa.c +++ b/protocol/lufa/lufa.c @@ -36,12 +36,20 @@    this software.  */ +#include <avr/sleep.h> +#include <avr/wdt.h>  #include "report.h"  #include "host.h"  #include "host_driver.h"  #include "keyboard.h" +#include "action.h" +#include "matrix.h" +#include "led.h"  #include "sendchar.h"  #include "debug.h" +#ifdef SLEEP_LED_ENABLE +#include "sleep_led.h" +#endif  #include "descriptor.h"  #include "lufa.h" @@ -140,10 +148,9 @@ static void Console_Task(void)   * 2) EVENT_USB_Device_Reset   * 3) EVENT_USB_Device_Wake  */ -#include "led.h" -#include "matrix.h"  void EVENT_USB_Device_Connect(void)  { +    led_set(0x1f);  // all on  }  void EVENT_USB_Device_Disconnect(void) @@ -156,17 +163,21 @@ void EVENT_USB_Device_Reset(void)  void EVENT_USB_Device_Suspend()  { +#ifdef SLEEP_LED_ENABLE +    sleep_led_enable(); +#endif  } -#include "action.h"  void EVENT_USB_Device_WakeUp()  {      // initialize      matrix_init();      clear_keyboard(); -    // turn off LED -    led_set(0); +#ifdef SLEEP_LED_ENABLE +    sleep_led_disable(); +#endif +    led_set(host_keyboard_leds());  }  void EVENT_USB_Device_StartOfFrame(void) @@ -493,7 +504,6 @@ static void SetupHardware(void)  } -#include "matrix.h"  static bool wakeup_condition(void)  {      matrix_scan(); @@ -503,8 +513,6 @@ static bool wakeup_condition(void)      return false;  } -#include <avr/sleep.h> -#include <avr/wdt.h>  #define wdt_intr_enable(value)   \  __asm__ __volatile__ (  \      "in __tmp_reg__,__SREG__" "\n\t"    \ @@ -527,11 +535,15 @@ int main(void)      SetupHardware();      keyboard_init();      host_set_driver(&lufa_driver); +#ifdef SLEEP_LED_ENABLE +    sleep_led_init(); +#endif      sei();      while (1) {          // while suspend          while (USB_DeviceState == DEVICE_STATE_Suspended) { +#ifndef NO_SUSPEND_POWER_DOWN              // Enable watchdog to wake from MCU sleep              cli();              wdt_reset(); @@ -558,6 +570,7 @@ int main(void)              // Disable watchdog after sleep              wdt_disable(); +#endif              // Send request of USB Wakeup from Suspend to host              if (USB_Device_RemoteWakeupEnabled) { @@ -575,9 +588,12 @@ int main(void)      }  } -/* watchdog timeout during sleep */ +#ifndef NO_SUSPEND_POWER_DOWN +/* watchdog timeout */  ISR(WDT_vect)  { +    /* wakeup from MCU sleep mode */ +/*      // blink LED      static uint8_t led_state = 0;      static uint8_t led_count = 0; @@ -585,4 +601,6 @@ ISR(WDT_vect)      if ((led_count & 0x07) == 0) {          led_set((led_state ^= (1<<USB_LED_CAPS_LOCK)));      } +*/  } +#endif | 
