From cf06612edfdb8bc05a5d5b64179ecafce720b0d6 Mon Sep 17 00:00:00 2001 From: Kai Ryu Date: Sun, 20 Jul 2014 12:52:56 +0900 Subject: [PATCH] Implement led mapping feature --- common.mk | 33 +++++++++------ common/action_layer.c | 6 +++ common/action_layer.h | 8 ++++ common/ledmap.c | 99 +++++++++++++++++++++++++++++++++++++++++++ common/ledmap.h | 53 ++++++++++++++++++++++- common/softpwm_led.c | 14 +++--- 6 files changed, 191 insertions(+), 22 deletions(-) diff --git a/common.mk b/common.mk index 540d8da4..f4c5c420 100644 --- a/common.mk +++ b/common.mk @@ -1,18 +1,18 @@ COMMON_DIR = common -SRC += $(COMMON_DIR)/host.c \ - $(COMMON_DIR)/keyboard.c \ - $(COMMON_DIR)/action.c \ - $(COMMON_DIR)/action_tapping.c \ - $(COMMON_DIR)/action_macro.c \ - $(COMMON_DIR)/action_layer.c \ - $(COMMON_DIR)/action_util.c \ - $(COMMON_DIR)/keymap.c \ - $(COMMON_DIR)/timer.c \ - $(COMMON_DIR)/print.c \ - $(COMMON_DIR)/bootloader.c \ - $(COMMON_DIR)/suspend.c \ - $(COMMON_DIR)/xprintf.S \ - $(COMMON_DIR)/util.c +SRC += $(COMMON_DIR)/host.c \ + $(COMMON_DIR)/keyboard.c \ + $(COMMON_DIR)/action.c \ + $(COMMON_DIR)/action_tapping.c \ + $(COMMON_DIR)/action_macro.c \ + $(COMMON_DIR)/action_layer.c \ + $(COMMON_DIR)/action_util.c \ + $(COMMON_DIR)/keymap.c \ + $(COMMON_DIR)/timer.c \ + $(COMMON_DIR)/print.c \ + $(COMMON_DIR)/bootloader.c \ + $(COMMON_DIR)/suspend.c \ + $(COMMON_DIR)/xprintf.S \ + $(COMMON_DIR)/util.c # Option modules @@ -76,6 +76,11 @@ ifdef BACKLIGHT_ENABLE OPT_DEFS += -DBACKLIGHT_ENABLE endif +ifdef LEDMAP_ENABLE + SRC += $(COMMON_DIR)/ledmap.c + OPT_DEFS += -DLEDMAP_ENABLE +endif + ifdef KEYMAP_SECTION_ENABLE OPT_DEFS += -DKEYMAP_SECTION_ENABLE EXTRALDFLAGS = -Wl,-L$(TOP_DIR),-Tldscript_keymap_avr5.x diff --git a/common/action_layer.c b/common/action_layer.c index 526e24d5..579950ac 100644 --- a/common/action_layer.c +++ b/common/action_layer.c @@ -22,6 +22,9 @@ static void default_layer_state_set(uint32_t state) default_layer_debug(); debug(" to "); default_layer_state = state; default_layer_debug(); debug("\n"); +#ifdef LEDMAP_ENABLE + default_layer_state_change(state); +#endif clear_keyboard_but_mods(); // To avoid stuck keys } @@ -63,6 +66,9 @@ static void layer_state_set(uint32_t state) layer_debug(); dprint(" to "); layer_state = state; layer_debug(); dprintln(); +#ifdef LEDMAP_ENABLE + layer_state_change(state); +#endif clear_keyboard_but_mods(); // To avoid stuck keys } diff --git a/common/action_layer.h b/common/action_layer.h index 034e0002..9af7b875 100644 --- a/common/action_layer.h +++ b/common/action_layer.h @@ -70,6 +70,14 @@ void layer_xor(uint32_t state); #define layer_debug() #endif +#ifdef LEDMAP_ENABLE +void default_layer_state_change(uint32_t state); +void layer_state_change(uint32_t state); +#else +#define default_layer_state_change() +#define layer_state_change() +#endif + /* return action depending on current layer status */ action_t layer_switch_get_action(key_t key); diff --git a/common/ledmap.c b/common/ledmap.c index df30af98..fccd4218 100644 --- a/common/ledmap.c +++ b/common/ledmap.c @@ -1 +1,100 @@ #include "ledmap.h" +#include "led.h" +#include "softpwm_led.h" +#include "action_layer.h" + +static led_state_t led_state = 0; +static led_state_t led_state_last = 0; + +static void update_led_state(void); + +void led_set(uint8_t usb_led) +{ + for (uint8_t i = 0; i < LED_COUNT; i++) { + uint8_t code = ledmap_get_code(i); + switch (code) { + case LEDMAP_NUM_LOCK: + usb_led & (1 << USB_LED_NUM_LOCK) ? LED_BIT_ON(led_state, i) : LED_BIT_OFF(led_state, i); + break; + case LEDMAP_CAPS_LOCK: + usb_led & (1 << USB_LED_CAPS_LOCK) ? LED_BIT_ON(led_state, i) : LED_BIT_OFF(led_state, i); + break; + case LEDMAP_SCROLL_LOCK: + usb_led & (1 << USB_LED_SCROLL_LOCK) ? LED_BIT_ON(led_state, i) : LED_BIT_OFF(led_state, i); + break; + case LEDMAP_COMPOSE: + usb_led & (1 << USB_LED_COMPOSE) ? LED_BIT_ON(led_state, i) : LED_BIT_OFF(led_state, i); + break; + case LEDMAP_KANA: + usb_led & (1 << USB_LED_KANA) ? LED_BIT_ON(led_state, i) : LED_BIT_OFF(led_state, i); + break; + default: + break; + } + } + update_led_state(); +} + +#ifndef NO_ACTION_LAYER +void default_layer_state_change(uint32_t state) +{ + for (uint8_t i = 0; i < LED_COUNT; i++) { + uint8_t code = ledmap_get_code(i); + if (code >= LEDMAP_DEFAULT_LAYER_0 && code < LEDMAP_DEFAULT_LAYER_31) { + state & (1UL << (code - LEDMAP_DEFAULT_LAYER_0)) ? LED_BIT_ON(led_state, i) : LED_BIT_OFF(led_state, i); + } + } + update_led_state(); +} + +void layer_state_change(uint32_t state) +{ + for (uint8_t i = 0; i < LED_COUNT; i++) { + uint8_t code = ledmap_get_code(i); + if (code >= LEDMAP_LAYER_0 && code < LEDMAP_LAYER_31) { + state & (1UL << (code - LEDMAP_LAYER_0)) ? LED_BIT_ON(led_state, i) : LED_BIT_OFF(led_state, i); + } + } + update_led_state(); +} +#endif + +#ifdef SOFTPWM_LED_ENABLE +void softpwm_led_on() +{ + for (uint8_t i = 0; i < LED_COUNT; i++) { + uint8_t code = ledmap_get_code(i); + if (code == LEDMAP_BACKLIGHT) { + ledmap_led_on(i); + } + } +} + +void softpwm_led_off() +{ + for (uint8_t i = 0; i < LED_COUNT; i++) { + uint8_t code = ledmap_get_code(i); + if (code == LEDMAP_BACKLIGHT) { + ledmap_led_off(i); + } + } +} +#endif + +void update_led_state(void) +{ + uint8_t diff = led_state_last ^ led_state; + if (diff) { + for (uint8_t i = 0; i < LED_COUNT; i++) { + if (diff & LED_BIT(i)) { + if (led_state & LED_BIT(i)) { + ledmap_led_on(i); + } + else { + ledmap_led_off(i); + } + } + } + led_state_last = led_state; + } +} diff --git a/common/ledmap.h b/common/ledmap.h index 32c8d733..8a570081 100644 --- a/common/ledmap.h +++ b/common/ledmap.h @@ -1,9 +1,60 @@ #ifndef LEDMAP_H #define LEDMAP_H -#ifdef LEDMAP_ENABLE +#include "stdint.h" +#if (LED_COUNT <= 8) +typedef uint8_t led_pack_t; +#elif (LED_COUNT <= 16) +typedef uint16_t led_pack_t; +#elif (LED_COUNT <= 32) +typedef uint32_t led_pack_t; #else +#error "LED_COUNT: invalid value" +#endif + +typedef led_pack_t led_state_t; + +#if (LED_COUNT <= 16) +#define LED_BIT(i) (1U<<(i)) +#elif (LED_COUNT <= 32) +#define LED_BIT(i) (1UL<<(i)) +#else +#error "LED_COUNT: invalid value" +#endif + +#define LED_BIT_ON(state, i) ((state) |= LED_BIT(i)) +#define LED_BIT_OFF(state, i) ((state) &= ~LED_BIT(i)) + +typedef enum { + LEDMAP_DEFAULT_LAYER_0 = 0, + LEDMAP_DEFAULT_LAYER_31 = 31, + LEDMAP_LAYER_0 = 32, + LEDMAP_LAYER_31 = 63, + LEDMAP_NUM_LOCK = 64, + LEDMAP_CAPS_LOCK, + LEDMAP_SCROLL_LOCK, + LEDMAP_COMPOSE, + LEDMAP_KANA, + LEDMAP_BACKLIGHT +} ledmap_code_t; + +#define LEDMAP_LAYER(x) (x) +#define LEDMAP_DEFAULT_LAYER(x) (32 + x) + +void ledmap_init(void); + +#ifdef LEDMAP_ENABLE +uint8_t ledmap_get_code(uint8_t index); +void ledmap_led_init(void); +void ledmap_led_on(uint8_t index); +void ledmap_led_off(uint8_t index); +#else +#define ledmaps +#define ledmap_get() +#define ledmap_led_init() +#define ledmap_led_on() +#define ledmap_led_off() #endif #endif diff --git a/common/softpwm_led.c b/common/softpwm_led.c index e2195c2f..d95ab48d 100644 --- a/common/softpwm_led.c +++ b/common/softpwm_led.c @@ -44,10 +44,10 @@ void softpwm_led_enable(void) /* Enable Compare Match Interrupt */ #ifdef SOFTPWM_LED_TIMER3 TIMSK3 |= (1<