diff --git a/.gitignore b/.gitignore
index 36d378de..f3f46872 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,4 +8,6 @@
*.map
*.sym
tags
-*.swp
+*~
+build/
+*.bak
diff --git a/common.mk b/common.mk
index e5a64933..648d0354 100644
--- a/common.mk
+++ b/common.mk
@@ -1,24 +1,25 @@
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)/print.c \
+ $(COMMON_DIR)/debug.c \
+ $(COMMON_DIR)/util.c \
+ $(COMMON_DIR)/avr/suspend.c \
+ $(COMMON_DIR)/avr/xprintf.S \
+ $(COMMON_DIR)/avr/timer.c \
+ $(COMMON_DIR)/avr/bootloader.c
# Option modules
ifdef BOOTMAGIC_ENABLE
SRC += $(COMMON_DIR)/bootmagic.c
- SRC += $(COMMON_DIR)/eeconfig.c
+ SRC += $(COMMON_DIR)/avr/eeconfig.c
OPT_DEFS += -DBOOTMAGIC_ENABLE
endif
diff --git a/common/action.c b/common/action.c
index 7d045aa1..a511b6f3 100644
--- a/common/action.c
+++ b/common/action.c
@@ -239,6 +239,16 @@ void process_action(keyrecord_t *record)
case ACT_LAYER_TAP:
case ACT_LAYER_TAP_EXT:
switch (action.layer_tap.code) {
+ case 0xe0 ... 0xef:
+ /* layer On/Off with modifiers(left only) */
+ if (event.pressed) {
+ layer_on(action.layer_tap.val);
+ register_mods(action.layer_tap.code & 0x0f);
+ } else {
+ layer_off(action.layer_tap.val);
+ unregister_mods(action.layer_tap.code & 0x0f);
+ }
+ break;
case OP_TAP_TOGGLE:
/* tap toggle */
if (event.pressed) {
@@ -505,7 +515,7 @@ void clear_keyboard_but_mods(void)
#endif
}
-bool is_tap_key(key_t key)
+bool is_tap_key(keypos_t key)
{
action_t action = layer_switch_get_action(key);
diff --git a/common/action.h b/common/action.h
index 99b2f2c5..d64aa118 100644
--- a/common/action.h
+++ b/common/action.h
@@ -25,6 +25,10 @@ along with this program. If not, see .
#include "action_macro.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
/* tapping count and state */
typedef struct {
bool interrupted :1;
@@ -42,12 +46,11 @@ typedef struct {
#endif
} keyrecord_t;
-
/* Execute action per keyevent */
void action_exec(keyevent_t event);
/* action for key */
-action_t action_for_key(uint8_t layer, key_t key);
+action_t action_for_key(uint8_t layer, keypos_t key);
/* macro */
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt);
@@ -68,11 +71,15 @@ void unregister_mods(uint8_t mods);
void clear_keyboard(void);
void clear_keyboard_but_mods(void);
void layer_switch(uint8_t new_layer);
-bool is_tap_key(key_t key);
+bool is_tap_key(keypos_t key);
/* debug */
void debug_event(keyevent_t event);
void debug_record(keyrecord_t record);
void debug_action(action_t action);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* ACTION_H */
diff --git a/common/action_code.h b/common/action_code.h
index 50112d4d..bc40e2c6 100644
--- a/common/action_code.h
+++ b/common/action_code.h
@@ -71,7 +71,7 @@ along with this program. If not, see .
*
* ACT_LAYER_TAP(101x):
* 101E|LLLL| keycode On/Off with tap key
- * 101E|LLLL|1110 xxxx Reserved(0xE0-EF)
+ * 101E|LLLL|1110 mods On/Off with modifiers(0xE0-EF)
* 101E|LLLL|1111 0000 Invert with tap toggle(0xF0)
* 101E|LLLL|1111 0001 On/Off
* 101E|LLLL|1111 0010 Off/On
@@ -266,6 +266,7 @@ enum layer_pram_tap_op {
#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF)
#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON)
#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR)
+#define ACTION_LAYER_MODS(layer, mods) ACTION_LAYER_TAP((layer), 0xe0 | (mods)&0x0f)
/* With Tapping */
#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key))
#define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE)
diff --git a/common/action_layer.c b/common/action_layer.c
index 579950ac..8b064ee4 100644
--- a/common/action_layer.c
+++ b/common/action_layer.c
@@ -118,7 +118,7 @@ void layer_debug(void)
-action_t layer_switch_get_action(key_t key)
+action_t layer_switch_get_action(keypos_t key)
{
action_t action;
action.code = ACTION_TRANSPARENT;
diff --git a/common/action_layer.h b/common/action_layer.h
index 9af7b875..8ede65cf 100644
--- a/common/action_layer.h
+++ b/common/action_layer.h
@@ -80,6 +80,6 @@ void layer_state_change(uint32_t state);
/* return action depending on current layer status */
-action_t layer_switch_get_action(key_t key);
+action_t layer_switch_get_action(keypos_t key);
#endif
diff --git a/common/action_macro.c b/common/action_macro.c
index d85aee37..ba93fc8b 100644
--- a/common/action_macro.c
+++ b/common/action_macro.c
@@ -14,10 +14,10 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
-#include
#include "action.h"
#include "action_util.h"
#include "action_macro.h"
+#include "wait.h"
#ifdef DEBUG_ACTION
#include "debug.h"
@@ -28,7 +28,7 @@ along with this program. If not, see .
#ifndef NO_ACTION_MACRO
-#define MACRO_READ() (macro = pgm_read_byte(macro_p++))
+#define MACRO_READ() (macro = MACRO_GET(macro_p++))
void action_macro_play(const macro_t *macro_p)
{
macro_t macro = END;
@@ -58,7 +58,7 @@ void action_macro_play(const macro_t *macro_p)
case WAIT:
MACRO_READ();
dprintf("WAIT(%u)\n", macro);
- { uint8_t ms = macro; while (ms--) _delay_ms(1); }
+ { uint8_t ms = macro; while (ms--) wait_ms(1); }
break;
case INTERVAL:
interval = MACRO_READ();
@@ -77,7 +77,7 @@ void action_macro_play(const macro_t *macro_p)
return;
}
// interval
- { uint8_t ms = interval; while (ms--) _delay_ms(1); }
+ { uint8_t ms = interval; while (ms--) wait_ms(1); }
}
}
#endif
diff --git a/common/action_macro.h b/common/action_macro.h
index 62182630..aedc32ec 100644
--- a/common/action_macro.h
+++ b/common/action_macro.h
@@ -17,12 +17,12 @@ along with this program. If not, see .
#ifndef ACTION_MACRO_H
#define ACTION_MACRO_H
#include
-#include
+#include "progmem.h"
-#define MACRO_NONE 0
-#define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
-
+#define MACRO_NONE 0
+#define MACRO(...) ({ static const macro_t __m[] PROGMEM = { __VA_ARGS__ }; &__m[0]; })
+#define MACRO_GET(p) pgm_read_byte(p)
typedef uint8_t macro_t;
diff --git a/common/action_util.c b/common/action_util.c
index c4ca8cfa..cb990522 100644
--- a/common/action_util.c
+++ b/common/action_util.c
@@ -33,8 +33,8 @@ static uint8_t weak_mods = 0;
#ifdef USB_6KRO_ENABLE
#undef REPORT_KEYS
#define REPORT_KEYS 6
-#define RO_ADD(a, b) ((a + b) % REPORT_KEYS)
-#define RO_SUB(a, b) ((a - b + REPORT_KEYS) % REPORT_KEYS)
+#define RO_ADD(a, b) ((a + b) % KEYBOARD_REPORT_KEYS)
+#define RO_SUB(a, b) ((a - b + KEYBOARD_REPORT_KEYS) % KEYBOARD_REPORT_KEYS)
#define RO_INC(a) RO_ADD(a, 1)
#define RO_DEC(a) RO_SUB(a, 1)
static int8_t cb_head = 0;
@@ -100,7 +100,7 @@ void del_key(uint8_t key)
void clear_keys(void)
{
// not clear mods
- for (int8_t i = 1; i < REPORT_SIZE; i++) {
+ for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
keyboard_report->raw[i] = 0;
}
}
@@ -156,7 +156,7 @@ uint8_t has_anykey(void)
#endif
#else
uint8_t cnt = 0;
- for (uint8_t i = 1; i < REPORT_SIZE; i++) {
+ for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
if (keyboard_report->raw[i])
cnt++;
}
@@ -174,7 +174,7 @@ uint8_t get_first_key(void)
#ifdef NKRO_ENABLE
if (keyboard_nkro) {
uint8_t i = 0;
- for (; i < REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
+ for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
;
return i<<3 | biton(keyboard_report->nkro.bits[i]);
}
@@ -263,7 +263,7 @@ static inline void add_key_byte(uint8_t code)
#else
int8_t i = 0;
int8_t empty = -1;
- for (; i < REPORT_KEYS; i++) {
+ for (; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
break;
}
@@ -271,7 +271,7 @@ static inline void add_key_byte(uint8_t code)
empty = i;
}
}
- if (i == REPORT_KEYS) {
+ if (i == KEYBOARD_REPORT_KEYS) {
if (empty != -1) {
keyboard_report->keys[empty] = code;
}
@@ -310,7 +310,7 @@ static inline void del_key_byte(uint8_t code)
dump_report_keys();
#endif
#else
- for (uint8_t i = 0; i < REPORT_KEYS; i++) {
+ for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
if (keyboard_report->keys[i] == code) {
keyboard_report->keys[i] = 0;
}
@@ -321,7 +321,7 @@ static inline void del_key_byte(uint8_t code)
#ifdef NKRO_ENABLE
static inline void add_key_bit(uint8_t code)
{
- if ((code>>3) < REPORT_BITS) {
+ if ((code>>3) < KEYBOARD_REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] |= 1<<(code&7);
} else {
dprintf("add_key_bit: can't add: %02X\n", code);
@@ -330,7 +330,7 @@ static inline void add_key_bit(uint8_t code)
static inline void del_key_bit(uint8_t code)
{
- if ((code>>3) < REPORT_BITS) {
+ if ((code>>3) < KEYBOARD_REPORT_BITS) {
keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7));
} else {
dprintf("del_key_bit: can't del: %02X\n", code);
diff --git a/common/action_util.h b/common/action_util.h
index f9d3161a..a955638b 100644
--- a/common/action_util.h
+++ b/common/action_util.h
@@ -20,6 +20,10 @@ along with this program. If not, see .
#include
#include "report.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern report_keyboard_t *keyboard_report;
void send_keyboard_report(void);
@@ -54,4 +58,9 @@ void oneshot_disable(void);
uint8_t has_anykey(void);
uint8_t has_anymod(void);
uint8_t get_first_key(void);
+
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/common/bootloader.c b/common/avr/bootloader.c
similarity index 100%
rename from common/bootloader.c
rename to common/avr/bootloader.c
diff --git a/common/eeconfig.c b/common/avr/eeconfig.c
similarity index 100%
rename from common/eeconfig.c
rename to common/avr/eeconfig.c
diff --git a/common/avr/suspend.c b/common/avr/suspend.c
new file mode 100644
index 00000000..66a579fd
--- /dev/null
+++ b/common/avr/suspend.c
@@ -0,0 +1,117 @@
+#include
+#include
+#include
+#include
+#include "matrix.h"
+#include "action.h"
+#include "backlight.h"
+#include "suspend_avr.h"
+#include "suspend.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" \
+)
+
+
+void suspend_idle(uint8_t time)
+{
+ cli();
+ set_sleep_mode(SLEEP_MODE_IDLE);
+ sleep_enable();
+ sei();
+ sleep_cpu();
+ sleep_disable();
+}
+
+/* Power down MCU with watchdog timer
+ * wdto: watchdog timer timeout defined in
+ * WDTO_15MS
+ * WDTO_30MS
+ * WDTO_60MS
+ * WDTO_120MS
+ * WDTO_250MS
+ * WDTO_500MS
+ * WDTO_1S
+ * WDTO_2S
+ * WDTO_4S
+ * WDTO_8S
+ */
+void suspend_power_down(uint8_t wdto)
+{
+#ifdef PROTOCOL_LUFA
+ if (USB_DeviceState == DEVICE_STATE_Configured) return;
+#endif
+
+ // 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();
+}
+
+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
+ clear_keyboard();
+#ifdef BACKLIGHT_ENABLE
+ backlight_init();
+#endif
+}
+
+#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;
+ led_count++;
+ if ((led_count & 0x07) == 0) {
+ led_set((led_state ^= (1<
+#include
+#include
+#include
+#include
+
+
+#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" \
+)
+
+#endif
diff --git a/common/timer.c b/common/avr/timer.c
similarity index 98%
rename from common/timer.c
rename to common/avr/timer.c
index e0dec6ce..292b41c3 100644
--- a/common/timer.c
+++ b/common/avr/timer.c
@@ -18,6 +18,7 @@ along with this program. If not, see .
#include
#include
#include
+#include "timer_avr.h"
#include "timer.h"
diff --git a/common/avr/timer_avr.h b/common/avr/timer_avr.h
new file mode 100644
index 00000000..0e85eb10
--- /dev/null
+++ b/common/avr/timer_avr.h
@@ -0,0 +1,42 @@
+/*
+Copyright 2011 Jun Wako
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#ifndef TIMER_AVR_H
+#define TIMER_AVR_H 1
+
+#include
+
+#ifndef TIMER_PRESCALER
+# if F_CPU > 16000000
+# define TIMER_PRESCALER 256
+# elif F_CPU > 2000000
+# define TIMER_PRESCALER 64
+# elif F_CPU > 250000
+# define TIMER_PRESCALER 8
+# else
+# define TIMER_PRESCALER 1
+# endif
+#endif
+#define TIMER_RAW_FREQ (F_CPU/TIMER_PRESCALER)
+#define TIMER_RAW TCNT0
+#define TIMER_RAW_TOP (TIMER_RAW_FREQ/1000)
+
+#if (TIMER_RAW_TOP > 255)
+# error "Timer0 can't count 1ms at this clock freq. Use larger prescaler."
+#endif
+
+#endif
diff --git a/common/xprintf.S b/common/avr/xprintf.S
similarity index 100%
rename from common/xprintf.S
rename to common/avr/xprintf.S
diff --git a/common/xprintf.h b/common/avr/xprintf.h
similarity index 94%
rename from common/xprintf.h
rename to common/avr/xprintf.h
index f58bca81..59c6f253 100644
--- a/common/xprintf.h
+++ b/common/avr/xprintf.h
@@ -8,6 +8,10 @@
#include
#include
+#ifdef __cplusplus
+extern "C" {
+#endif
+
extern void (*xfunc_out)(uint8_t);
#define xdev_out(func) xfunc_out = (void(*)(uint8_t))(func)
@@ -99,5 +103,9 @@ char xatoi(char **str, long *ret);
Pointer to return value
*/
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/common/bootmagic.c b/common/bootmagic.c
index 9e734db5..18012af0 100644
--- a/common/bootmagic.c
+++ b/common/bootmagic.c
@@ -120,7 +120,7 @@ static bool scan_keycode(uint8_t keycode)
matrix_row_t matrix_row = matrix_get_row(r);
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_row & ((matrix_row_t)1< ");
- state = CONSOLE;
+ command_state = CONSOLE;
break;
case KC_PAUSE:
clear_keyboard();
@@ -388,14 +398,14 @@ static bool command_console(uint8_t code)
case KC_Q:
case KC_ESC:
print("\nQuit Console Mode\n");
- state = ONESHOT;
+ command_state = ONESHOT;
return false;
#ifdef MOUSEKEY_ENABLE
case KC_M:
mousekey_console_help();
print("\nEnter Mousekey Console\n");
print("M0>");
- state = MOUSEKEY;
+ command_state = MOUSEKEY;
return true;
#endif
default:
@@ -555,7 +565,7 @@ static bool mousekey_console(uint8_t code)
mousekey_param = 0;
print("\nQuit Mousekey Console\n");
print("C> ");
- state = CONSOLE;
+ command_state = CONSOLE;
return false;
case KC_P:
mousekey_param_print();
diff --git a/common/command.h b/common/command.h
index be739faf..b57a6c1c 100644
--- a/common/command.h
+++ b/common/command.h
@@ -18,10 +18,16 @@ along with this program. If not, see .
#ifndef COMMAND_H
#define COMMAND
+/* TODO: Refactoring */
+typedef enum { ONESHOT, CONSOLE, MOUSEKEY } command_state_t;
+extern command_state_t command_state;
+
+/* This allows to extend commands. Return false when command is not processed. */
+bool command_extra(uint8_t code);
+bool command_console_extra(uint8_t code);
+
#ifdef COMMAND_ENABLE
bool command_proc(uint8_t code);
-/* This allows to extend commands. Return 0 when command is not processed. */
-bool command_extra(uint8_t code);
#else
#define command_proc(code) false
#endif
diff --git a/common/debug.c b/common/debug.c
new file mode 100644
index 00000000..18613fc2
--- /dev/null
+++ b/common/debug.c
@@ -0,0 +1,24 @@
+#include
+#include "debug.h"
+
+#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+
+debug_config_t debug_config = {
+/* GCC Bug 10676 - Using unnamed fields in initializers
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=10676 */
+#if GCC_VERSION >= 40600
+ .enable = false,
+ .matrix = false,
+ .keyboard = false,
+ .mouse = false,
+ .reserved = 0
+#else
+ {
+ false, // .enable
+ false, // .matrix
+ false, // .keyboard
+ false, // .mouse
+ 0 // .reserved
+ }
+#endif
+};
diff --git a/common/debug.h b/common/debug.h
index 8aaa5ed9..3cbe2092 100644
--- a/common/debug.h
+++ b/common/debug.h
@@ -18,45 +18,100 @@ along with this program. If not, see .
#ifndef DEBUG_H
#define DEBUG_H 1
+#include
#include "print.h"
-#include "debug_config.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Debug output control
+ */
+typedef union {
+ struct {
+ bool enable:1;
+ bool matrix:1;
+ bool keyboard:1;
+ bool mouse:1;
+ uint8_t reserved:4;
+ };
+ uint8_t raw;
+} debug_config_t;
+
+extern debug_config_t debug_config;
+
+#ifdef __cplusplus
+}
+#endif
+
+/* for backward compatibility */
+#define debug_enable (debug_config.enable)
+#define debug_matrix (debug_config.matrix)
+#define debug_keyboard (debug_config.keyboard)
+#define debug_mouse (debug_config.mouse)
+
+
+/*
+ * Debug print utils
+ */
#ifndef NO_DEBUG
-#define dprint(s) do { if (debug_enable) print(s); } while (0)
-#define dprintln() do { if (debug_enable) print_crlf(); } while (0)
-#define dprintf(fmt, ...) do { if (debug_enable) __xprintf(PSTR(fmt), ##__VA_ARGS__); } while (0)
-#define dmsg(s) dprintf("%s at %s: %S\n", __FILE__, __LINE__, PSTR(s))
+#define dprint(s) do { if (debug_enable) print(s); } while (0)
+#define dprintln(s) do { if (debug_enable) println(s); } while (0)
+#define dprintf(fmt, ...) do { if (debug_enable) xprintf(fmt, ##__VA_ARGS__); } while (0)
+#define dmsg(s) dprintf("%s at %s: %S\n", __FILE__, __LINE__, PSTR(s))
-/* DO NOT USE these anymore */
-#define debug(s) do { if (debug_enable) print(s); } while (0)
-#define debugln(s) do { if (debug_enable) print_crlf(); } while (0)
-#define debug_S(s) do { if (debug_enable) print_S(s); } while (0)
-#define debug_P(s) do { if (debug_enable) print_P(s); } while (0)
-#define debug_msg(s) do { \
+/* Deprecated. DO NOT USE these anymore, use dprintf instead. */
+#define debug(s) do { if (debug_enable) print(s); } while (0)
+#define debugln(s) do { if (debug_enable) println(s); } while (0)
+#define debug_msg(s) do { \
if (debug_enable) { \
print(__FILE__); print(" at "); print_dec(__LINE__); print(" in "); print(": "); print(s); \
} \
} while (0)
-#define debug_dec(data) do { if (debug_enable) print_dec(data); } while (0)
-#define debug_decs(data) do { if (debug_enable) print_decs(data); } while (0)
-#define debug_hex4(data) do { if (debug_enable) print_hex4(data); } while (0)
-#define debug_hex8(data) do { if (debug_enable) print_hex8(data); } while (0)
-#define debug_hex16(data) do { if (debug_enable) print_hex16(data); } while (0)
-#define debug_hex32(data) do { if (debug_enable) print_hex32(data); } while (0)
-#define debug_bin8(data) do { if (debug_enable) print_bin8(data); } while (0)
-#define debug_bin16(data) do { if (debug_enable) print_bin16(data); } while (0)
-#define debug_bin32(data) do { if (debug_enable) print_bin32(data); } while (0)
-#define debug_bin_reverse8(data) do { if (debug_enable) print_bin_reverse8(data); } while (0)
-#define debug_bin_reverse16(data) do { if (debug_enable) print_bin_reverse16(data); } while (0)
-#define debug_bin_reverse32(data) do { if (debug_enable) print_bin_reverse32(data); } while (0)
-#define debug_hex(data) debug_hex8(data)
-#define debug_bin(data) debug_bin8(data)
-#define debug_bin_reverse(data) debug_bin8(data)
+#define debug_dec(data) do { if (debug_enable) print_dec(data); } while (0)
+#define debug_decs(data) do { if (debug_enable) print_decs(data); } while (0)
+#define debug_hex4(data) do { if (debug_enable) print_hex4(data); } while (0)
+#define debug_hex8(data) do { if (debug_enable) print_hex8(data); } while (0)
+#define debug_hex16(data) do { if (debug_enable) print_hex16(data); } while (0)
+#define debug_hex32(data) do { if (debug_enable) print_hex32(data); } while (0)
+#define debug_bin8(data) do { if (debug_enable) print_bin8(data); } while (0)
+#define debug_bin16(data) do { if (debug_enable) print_bin16(data); } while (0)
+#define debug_bin32(data) do { if (debug_enable) print_bin32(data); } while (0)
+#define debug_bin_reverse8(data) do { if (debug_enable) print_bin_reverse8(data); } while (0)
+#define debug_bin_reverse16(data) do { if (debug_enable) print_bin_reverse16(data); } while (0)
+#define debug_bin_reverse32(data) do { if (debug_enable) print_bin_reverse32(data); } while (0)
+#define debug_hex(data) debug_hex8(data)
+#define debug_bin(data) debug_bin8(data)
+#define debug_bin_reverse(data) debug_bin8(data)
-#else
-#include "nodebug.h"
-#endif
+#else /* NO_DEBUG */
+
+#define dprint(s)
+#define dprintln(s)
+#define dprintf(fmt, ...)
+#define dmsg(s)
+#define debug(s)
+#define debugln(s)
+#define debug_msg(s)
+#define debug_dec(data)
+#define debug_decs(data)
+#define debug_hex4(data)
+#define debug_hex8(data)
+#define debug_hex16(data)
+#define debug_hex32(data)
+#define debug_bin8(data)
+#define debug_bin16(data)
+#define debug_bin32(data)
+#define debug_bin_reverse8(data)
+#define debug_bin_reverse16(data)
+#define debug_bin_reverse32(data)
+#define debug_hex(data)
+#define debug_bin(data)
+#define debug_bin_reverse(data)
+
+#endif /* NO_DEBUG */
#endif
diff --git a/common/debug_config.h b/common/debug_config.h
deleted file mode 100644
index e00fd103..00000000
--- a/common/debug_config.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-Copyright 2013 Jun Wako
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 2 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-#ifndef DEBUG_CONFIG_H
-#define DEBUG_CONFIG_H 1
-
-#include
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* NOTE: Not portable. Bit field order depends on implementation */
-typedef union {
- uint8_t raw;
- struct {
- bool enable:1;
- bool matrix:1;
- bool keyboard:1;
- bool mouse:1;
- uint8_t reserved:4;
- };
-} debug_config_t;
-debug_config_t debug_config;
-
-/* for backward compatibility */
-#define debug_enable (debug_config.enable)
-#define debug_matrix (debug_config.matrix)
-#define debug_keyboard (debug_config.keyboard)
-#define debug_mouse (debug_config.mouse)
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/common/host.c b/common/host.c
index 2e56971b..e9b79167 100644
--- a/common/host.c
+++ b/common/host.c
@@ -16,7 +16,7 @@ along with this program. If not, see .
*/
#include
-#include
+//#include
#include "keycode.h"
#include "host.h"
#include "util.h"
@@ -55,7 +55,7 @@ void host_keyboard_send(report_keyboard_t *report)
if (debug_keyboard) {
dprint("keyboard_report: ");
- for (uint8_t i = 0; i < REPORT_SIZE; i++) {
+ for (uint8_t i = 0; i < KEYBOARD_REPORT_SIZE; i++) {
dprintf("%02X ", report->raw[i]);
}
dprint("\n");
diff --git a/common/host.h b/common/host.h
index a56e6c3b..918af69e 100644
--- a/common/host.h
+++ b/common/host.h
@@ -32,8 +32,8 @@ extern "C" {
extern bool keyboard_nkro;
#endif
-uint8_t keyboard_idle;
-uint8_t keyboard_protocol;
+extern uint8_t keyboard_idle;
+extern uint8_t keyboard_protocol;
/* host driver */
diff --git a/common/keyboard.c b/common/keyboard.c
index ef2efb6f..f989dc1f 100644
--- a/common/keyboard.c
+++ b/common/keyboard.c
@@ -15,7 +15,6 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see .
*/
#include
-#include
#include "keyboard.h"
#include "matrix.h"
#include "keymap.h"
@@ -45,6 +44,9 @@ along with this program. If not, see .
#ifdef PS2_MOUSE_ENABLE
# include "ps2_mouse.h"
#endif
+#ifdef SERIAL_MOUSE_ENABLE
+#include "serial_mouse.h"
+#endif
#ifdef MATRIX_HAS_GHOST
@@ -79,6 +81,10 @@ void keyboard_init(void)
ps2_mouse_init();
}
#endif
+#ifdef SERIAL_MOUSE_ENABLE
+ serial_mouse_init();
+#endif
+
#ifdef BOOTMAGIC_ENABLE
bootmagic();
@@ -134,7 +140,7 @@ void keyboard_task(void)
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_change & ((matrix_row_t)1<.
*/
-#include
#include "keymap.h"
#include "report.h"
#include "keycode.h"
@@ -28,7 +27,7 @@ static action_t keycode_to_action(uint8_t keycode);
/* converts key to action */
-action_t action_for_key(uint8_t layer, key_t key)
+action_t action_for_key(uint8_t layer, keypos_t key)
{
uint8_t keycode = keymap_key_to_keycode(layer, key);
switch (keycode) {
@@ -156,7 +155,7 @@ static action_t keycode_to_action(uint8_t keycode)
* Consider using new keymap API instead.
*/
__attribute__ ((weak))
-uint8_t keymap_key_to_keycode(uint8_t layer, key_t key)
+uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key)
{
return keymap_get_keycode(layer, key.row, key.col);
}
diff --git a/common/keymap.h b/common/keymap.h
index 4c3019a3..e1a6f992 100644
--- a/common/keymap.h
+++ b/common/keymap.h
@@ -43,7 +43,7 @@ keymap_config_t keymap_config;
/* translates key to keycode */
-uint8_t keymap_key_to_keycode(uint8_t layer, key_t key);
+uint8_t keymap_key_to_keycode(uint8_t layer, keypos_t key);
/* translates Fn keycode to action */
action_t keymap_fn_to_action(uint8_t keycode);
diff --git a/common/matrix.h b/common/matrix.h
index d1d14a6e..23fef78f 100644
--- a/common/matrix.h
+++ b/common/matrix.h
@@ -53,4 +53,9 @@ matrix_row_t matrix_get_row(uint8_t row);
void matrix_print(void);
+/* power control */
+void matrix_power_up(void);
+void matrix_power_down(void);
+
+
#endif
diff --git a/common/mbed/bootloader.c b/common/mbed/bootloader.c
new file mode 100644
index 00000000..b51e8394
--- /dev/null
+++ b/common/mbed/bootloader.c
@@ -0,0 +1,4 @@
+#include "bootloader.h"
+
+
+void bootloader_jump(void) {}
diff --git a/common/mbed/suspend.c b/common/mbed/suspend.c
new file mode 100644
index 00000000..32651574
--- /dev/null
+++ b/common/mbed/suspend.c
@@ -0,0 +1,6 @@
+#include
+
+
+void suspend_power_down(void) {}
+bool suspend_wakeup_condition(void) { return true; }
+void suspend_wakeup_init(void) {}
diff --git a/common/mbed/timer.c b/common/mbed/timer.c
new file mode 100644
index 00000000..c357ceb7
--- /dev/null
+++ b/common/mbed/timer.c
@@ -0,0 +1,41 @@
+#include "cmsis.h"
+#include "timer.h"
+
+/* Mill second tick count */
+volatile uint32_t timer_count = 0;
+
+/* Timer interrupt handler */
+void SysTick_Handler(void) {
+ timer_count++;
+}
+
+void timer_init(void)
+{
+ timer_count = 0;
+ SysTick_Config(SystemCoreClock / 1000); /* 1ms tick */
+}
+
+void timer_clear(void)
+{
+ timer_count = 0;
+}
+
+uint16_t timer_read(void)
+{
+ return (uint16_t)(timer_count & 0xFFFF);
+}
+
+uint32_t timer_read32(void)
+{
+ return timer_count;
+}
+
+uint16_t timer_elapsed(uint16_t last)
+{
+ return TIMER_DIFF_16(timer_read(), last);
+}
+
+uint32_t timer_elapsed32(uint32_t last)
+{
+ return TIMER_DIFF_32(timer_read32(), last);
+}
diff --git a/common/mbed/xprintf.cpp b/common/mbed/xprintf.cpp
new file mode 100644
index 00000000..4342b79f
--- /dev/null
+++ b/common/mbed/xprintf.cpp
@@ -0,0 +1,46 @@
+#include
+//#include
+#include "mbed.h"
+#include "mbed/xprintf.h"
+
+
+#define STRING_STACK_LIMIT 120
+
+/* mbed Serial */
+Serial ser(UART_TX, UART_RX);
+
+/* TODO: Need small implementation for embedded */
+int xprintf(const char* format, ...)
+{
+ /* copy from mbed/common/RawSerial.cpp */
+ std::va_list arg;
+ va_start(arg, format);
+ int len = vsnprintf(NULL, 0, format, arg);
+ if (len < STRING_STACK_LIMIT) {
+ char temp[STRING_STACK_LIMIT];
+ vsprintf(temp, format, arg);
+ ser.puts(temp);
+ } else {
+ char *temp = new char[len + 1];
+ vsprintf(temp, format, arg);
+ ser.puts(temp);
+ delete[] temp;
+ }
+ va_end(arg);
+ return len;
+
+/* Fail: __builtin_va_arg_pack?
+ * https://gcc.gnu.org/onlinedocs/gcc-4.3.5/gcc/Constructing-Calls.html#Constructing-Calls
+ void *arg = __builtin_apply_args();
+ void *ret = __builtin_apply((void*)(&(ser.printf)), arg, 100);
+ __builtin_return(ret)
+*/
+/* Fail: varargs can not be passed to printf
+ //int r = ser.printf("test %i\r\n", 123);
+ va_list arg;
+ va_start(arg, format);
+ int r = ser.printf(format, arg);
+ va_end(arg);
+ return r;
+*/
+}
diff --git a/common/mbed/xprintf.h b/common/mbed/xprintf.h
new file mode 100644
index 00000000..26bc529e
--- /dev/null
+++ b/common/mbed/xprintf.h
@@ -0,0 +1,17 @@
+#ifndef XPRINTF_H
+#define XPRINTF_H
+
+//#define xprintf(format, ...) __xprintf(format, ##__VA_ARGS__)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int xprintf(const char *format, ...);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/common/mousekey.c b/common/mousekey.c
index 017be941..23469476 100644
--- a/common/mousekey.c
+++ b/common/mousekey.c
@@ -16,7 +16,6 @@ along with this program. If not, see .
*/
#include
-#include
#include "keycode.h"
#include "host.h"
#include "timer.h"
diff --git a/common/mousekey.h b/common/mousekey.h
index d8d7beaa..6eede06b 100644
--- a/common/mousekey.h
+++ b/common/mousekey.h
@@ -52,12 +52,16 @@ along with this program. If not, see .
#endif
-uint8_t mk_delay;
-uint8_t mk_interval;
-uint8_t mk_max_speed;
-uint8_t mk_time_to_max;
-uint8_t mk_wheel_max_speed;
-uint8_t mk_wheel_time_to_max;
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern uint8_t mk_delay;
+extern uint8_t mk_interval;
+extern uint8_t mk_max_speed;
+extern uint8_t mk_time_to_max;
+extern uint8_t mk_wheel_max_speed;
+extern uint8_t mk_wheel_time_to_max;
void mousekey_task(void);
@@ -66,4 +70,8 @@ void mousekey_off(uint8_t code);
void mousekey_clear(void);
void mousekey_send(void);
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/common/nodebug.h b/common/nodebug.h
index aec790bb..93309ada 100644
--- a/common/nodebug.h
+++ b/common/nodebug.h
@@ -18,32 +18,8 @@ along with this program. If not, see .
#ifndef NODEBUG_H
#define NODEBUG_H 1
-#include "debug_config.h"
-
-#define dprint(s)
-#define dprintln(s)
-#define dprintf(fmt, ...)
-#define dmsg(s)
-
-#define debug(s)
-#define debugln(s)
-#define debug_S(s)
-#define debug_P(s)
-#define debug_msg(s)
-#define debug_dec(data)
-#define debug_decs(data)
-#define debug_hex4(data)
-#define debug_hex8(data)
-#define debug_hex16(data)
-#define debug_hex32(data)
-#define debug_bin8(data)
-#define debug_bin16(data)
-#define debug_bin32(data)
-#define debug_bin_reverse8(data)
-#define debug_bin_reverse16(data)
-#define debug_bin_reverse32(data)
-#define debug_hex(data)
-#define debug_bin(data)
-#define debug_bin_reverse(data)
+#define NO_DEBUG
+#include "debug.h"
+#undef NO_DEBUG
#endif
diff --git a/common/print.c b/common/print.c
index 783bb4e9..c13a29f3 100644
--- a/common/print.c
+++ b/common/print.c
@@ -37,26 +37,4 @@ void print_set_sendchar(int8_t (*sendchar_func)(uint8_t))
xdev_out(sendchar_func);
}
-void print_S(const char *s)
-{
- uint8_t c;
- while (1) {
- c = *s++;
- if (!c) break;
- if (c == '\n') sendchar('\r');
- sendchar(c);
- }
-}
-
-void print_lf(void)
-{
- sendchar('\n');
-}
-
-void print_crlf(void)
-{
- sendchar('\r');
- sendchar('\n');
-}
-
#endif
diff --git a/common/print.h b/common/print.h
index 930e84be..a8dbbc02 100644
--- a/common/print.h
+++ b/common/print.h
@@ -27,98 +27,79 @@
#include
#include
-#include
-#include "xprintf.h"
#include "util.h"
-// this macro allows you to write print("some text") and
-// the string is automatically placed into flash memory :)
-// TODO: avoid collision with arduino/Print.h
-#ifndef __cplusplus
-#define print(s) print_P(PSTR(s))
-#endif
-#define println(s) print_P(PSTR(s "\n"))
-
-/* for old name */
-#define pdec(data) print_dec(data)
-#define pdec16(data) print_dec(data)
-#define phex(data) print_hex8(data)
-#define phex16(data) print_hex16(data)
-#define pbin(data) print_bin8(data)
-#define pbin16(data) print_bin16(data)
-#define pbin_reverse(data) print_bin_reverse8(data)
-#define pbin_reverse16(data) print_bin_reverse16(data)
-
-/* print value utility */
-#define print_val_dec(v) xprintf(#v ": %u\n", v)
-#define print_val_decs(v) xprintf(#v ": %d\n", v)
-#define print_val_hex8(v) xprintf(#v ": %X\n", v)
-#define print_val_hex16(v) xprintf(#v ": %02X\n", v)
-#define print_val_hex32(v) xprintf(#v ": %04lX\n", v)
-#define print_val_bin8(v) xprintf(#v ": %08b\n", v)
-#define print_val_bin16(v) xprintf(#v ": %016b\n", v)
-#define print_val_bin32(v) xprintf(#v ": %032lb\n", v)
-#define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v))
-#define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v))
-#define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v))
-
#ifndef NO_PRINT
-#ifdef __cplusplus
-extern "C" {
-#endif
+#if defined(__AVR__)
+
+#include "avr/xprintf.h"
+
+
+// TODO: avoid collision with arduino/Print.h
+#ifndef __cplusplus
+#define print(s) xputs(PSTR(s))
+#endif
+#define println(s) xputs(PSTR(s "\r\n"))
+
+#ifdef __cplusplus
+extern "C"
+#endif
/* function pointer of sendchar to be used by print utility */
void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t));
-/* print string stored in data memory(SRAM)
- * print_S("hello world");
- * This consumes precious SRAM memory space for string.
- */
-void print_S(const char *s);
+#elif defined(__arm__)
-void print_lf(void);
-void print_crlf(void);
+#include "mbed/xprintf.h"
+#define print(s) xprintf(s)
+#define println(s) xprintf(s "\r\n")
+
+/* TODO: to select output destinations: UART/USBSerial */
+#define print_set_sendchar(func)
+
+#endif /* __AVR__ */
-/* print string stored in program memory(FLASH)
- * print_P(PSTR("hello world");
- * This consumes relatively abundant FLASH memory area not SRAM.
- */
-#define print_P(s) xputs(s)
/* decimal */
-#define print_dec(i) xprintf("%u", i)
-#define print_decs(i) xprintf("%d", i)
-
+#define print_dec(i) xprintf("%u", i)
+#define print_decs(i) xprintf("%d", i)
/* hex */
-#define print_hex4(i) xprintf("%X", i)
-#define print_hex8(i) xprintf("%02X", i)
-#define print_hex16(i) xprintf("%04X", i)
-#define print_hex32(i) xprintf("%08lX", i)
-
+#define print_hex4(i) xprintf("%X", i)
+#define print_hex8(i) xprintf("%02X", i)
+#define print_hex16(i) xprintf("%04X", i)
+#define print_hex32(i) xprintf("%08lX", i)
/* binary */
-#define print_bin4(i) xprintf("%04b", i)
-#define print_bin8(i) xprintf("%08b", i)
-#define print_bin16(i) xprintf("%016b", i)
-#define print_bin32(i) xprintf("%032lb", i)
+#define print_bin4(i) xprintf("%04b", i)
+#define print_bin8(i) xprintf("%08b", i)
+#define print_bin16(i) xprintf("%016b", i)
+#define print_bin32(i) xprintf("%032lb", i)
+#define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
+#define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
+#define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
+/* print value utility */
+#define print_val_dec(v) xprintf(#v ": %u\n", v)
+#define print_val_decs(v) xprintf(#v ": %d\n", v)
+#define print_val_hex8(v) xprintf(#v ": %X\n", v)
+#define print_val_hex16(v) xprintf(#v ": %02X\n", v)
+#define print_val_hex32(v) xprintf(#v ": %04lX\n", v)
+#define print_val_bin8(v) xprintf(#v ": %08b\n", v)
+#define print_val_bin16(v) xprintf(#v ": %016b\n", v)
+#define print_val_bin32(v) xprintf(#v ": %032lb\n", v)
+#define print_val_bin_reverse8(v) xprintf(#v ": %08b\n", bitrev(v))
+#define print_val_bin_reverse16(v) xprintf(#v ": %016b\n", bitrev16(v))
+#define print_val_bin_reverse32(v) xprintf(#v ": %032lb\n", bitrev32(v))
-#define print_bin_reverse8(i) xprintf("%08b", bitrev(i))
-#define print_bin_reverse16(i) xprintf("%016b", bitrev16(i))
-#define print_bin_reverse32(i) xprintf("%032lb", bitrev32(i))
-
-#ifdef __cplusplus
-}
-#endif
-
-#else
+#else /* NO_PRINT */
+#define xprintf
+#define print
+#define println
#define print_set_sendchar(func)
-#define print_S(s)
-#define print_P(s)
#define print_dec(data)
#define print_decs(data)
#define print_hex4(data)
@@ -132,8 +113,30 @@ void print_crlf(void);
#define print_bin_reverse8(data)
#define print_bin_reverse16(data)
#define print_bin_reverse32(data)
+#define print_val_dec(v)
+#define print_val_decs(v)
+#define print_val_hex8(v)
+#define print_val_hex16(v)
+#define print_val_hex32(v)
+#define print_val_bin8(v)
+#define print_val_bin16(v)
+#define print_val_bin32(v)
+#define print_val_bin_reverse8(v)
+#define print_val_bin_reverse16(v)
+#define print_val_bin_reverse32(v)
-#endif
+#endif /* NO_PRINT */
+
+
+/* Backward compatiblitly for old name */
+#define pdec(data) print_dec(data)
+#define pdec16(data) print_dec(data)
+#define phex(data) print_hex8(data)
+#define phex16(data) print_hex16(data)
+#define pbin(data) print_bin8(data)
+#define pbin16(data) print_bin16(data)
+#define pbin_reverse(data) print_bin_reverse8(data)
+#define pbin_reverse16(data) print_bin_reverse16(data)
#endif
diff --git a/common/progmem.h b/common/progmem.h
new file mode 100644
index 00000000..199b1bed
--- /dev/null
+++ b/common/progmem.h
@@ -0,0 +1,12 @@
+#ifndef PROGMEM_H
+#define PROGMEM_H 1
+
+#if defined(__AVR__)
+# include
+#elif defined(__arm__)
+# define PROGMEM
+# define pgm_read_byte(p) *(p)
+# define pgm_read_word(p) *(p)
+#endif
+
+#endif
diff --git a/common/report.h b/common/report.h
index 71543cc2..62190469 100644
--- a/common/report.h
+++ b/common/report.h
@@ -74,19 +74,19 @@ along with this program. If not, see .
/* key report size(NKRO or boot mode) */
#if defined(PROTOCOL_PJRC) && defined(NKRO_ENABLE)
# include "usb.h"
-# define REPORT_SIZE KBD2_SIZE
-# define REPORT_KEYS (KBD2_SIZE - 2)
-# define REPORT_BITS (KBD2_SIZE - 1)
+# define KEYBOARD_REPORT_SIZE KBD2_SIZE
+# define KEYBOARD_REPORT_KEYS (KBD2_SIZE - 2)
+# define KEYBOARD_REPORT_BITS (KBD2_SIZE - 1)
#elif defined(PROTOCOL_LUFA) && defined(NKRO_ENABLE)
# include "protocol/lufa/descriptor.h"
-# define REPORT_SIZE NKRO_EPSIZE
-# define REPORT_KEYS (NKRO_EPSIZE - 2)
-# define REPORT_BITS (NKRO_EPSIZE - 1)
+# define KEYBOARD_REPORT_SIZE NKRO_EPSIZE
+# define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2)
+# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1)
#else
-# define REPORT_SIZE 8
-# define REPORT_KEYS 6
+# define KEYBOARD_REPORT_SIZE 8
+# define KEYBOARD_REPORT_KEYS 6
#endif
@@ -115,16 +115,16 @@ extern "C" {
*
*/
typedef union {
- uint8_t raw[REPORT_SIZE];
+ uint8_t raw[KEYBOARD_REPORT_SIZE];
struct {
uint8_t mods;
uint8_t reserved;
- uint8_t keys[REPORT_KEYS];
+ uint8_t keys[KEYBOARD_REPORT_KEYS];
};
#ifdef NKRO_ENABLE
struct {
uint8_t mods;
- uint8_t bits[REPORT_BITS];
+ uint8_t bits[KEYBOARD_REPORT_BITS];
} nkro;
#endif
} __attribute__ ((packed)) report_keyboard_t;
diff --git a/common/suspend.c b/common/suspend.c
deleted file mode 100644
index 5b378892..00000000
--- a/common/suspend.c
+++ /dev/null
@@ -1,76 +0,0 @@
-#include "suspend.h"
-#include "matrix.h"
-#include "action.h"
-#include "backlight.h"
-
-
-void suspend_power_down(void)
-{
-#ifdef BACKLIGHT_ENABLE
- backlight_set(0);
-#endif
-#ifndef NO_SUSPEND_POWER_DOWN
- // Enable watchdog to wake from MCU sleep
- cli();
- wdt_reset();
-
- // Watchdog Interrupt and System Reset Mode
- //wdt_enable(WDTO_1S);
- //WDTCSR |= _BV(WDIE);
-
- // Watchdog Interrupt Mode
- wdt_intr_enable(WDTO_120MS);
-
- // TODO: more power saving
- // See PicoPower application note
- // - I/O port input with pullup
- // - prescale clock
- // - BOD disable
- // - Power Reduction Register PRR
- // sleep in power down mode
- set_sleep_mode(SLEEP_MODE_PWR_DOWN);
- sleep_enable();
- sei();
- sleep_cpu();
- sleep_disable();
-
- // Disable watchdog after sleep
- wdt_disable();
-#endif
-}
-
-bool suspend_wakeup_condition(void)
-{
- matrix_scan();
- 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
- clear_keyboard();
-#ifdef BACKLIGHT_ENABLE
- backlight_init();
-#endif
-}
-
-#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;
- led_count++;
- if ((led_count & 0x07) == 0) {
- led_set((led_state ^= (1<
#include
-#include
-#include
-#include
-#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" \
-)
-
-
-void suspend_power_down(void);
+void suspend_idle(uint8_t timeout);
+void suspend_power_down(uint8_t timeout);
bool suspend_wakeup_condition(void);
void suspend_wakeup_init(void);
diff --git a/common/timer.h b/common/timer.h
index 6437473f..fe23f87a 100644
--- a/common/timer.h
+++ b/common/timer.h
@@ -20,24 +20,10 @@ along with this program. If not, see .
#include
-#ifndef TIMER_PRESCALER
-# if F_CPU > 16000000
-# define TIMER_PRESCALER 256
-# elif F_CPU > 2000000
-# define TIMER_PRESCALER 64
-# elif F_CPU > 250000
-# define TIMER_PRESCALER 8
-# else
-# define TIMER_PRESCALER 1
-# endif
+#if defined(__AVR__)
+#include "avr/timer_avr.h"
#endif
-#define TIMER_RAW_FREQ (F_CPU/TIMER_PRESCALER)
-#define TIMER_RAW TCNT0
-#define TIMER_RAW_TOP (TIMER_RAW_FREQ/1000)
-#if (TIMER_RAW_TOP > 255)
-# error "Timer0 can't count 1ms at this clock freq. Use larger prescaler."
-#endif
#define TIMER_DIFF(a, b, max) ((a) >= (b) ? (a) - (b) : (max) - (b) + (a))
#define TIMER_DIFF_8(a, b) TIMER_DIFF(a, b, UINT8_MAX)
diff --git a/common/wait.h b/common/wait.h
new file mode 100644
index 00000000..40d00b0c
--- /dev/null
+++ b/common/wait.h
@@ -0,0 +1,20 @@
+#ifndef WAIT_H
+#define WAIT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(__AVR__)
+# include
+# define wait_ms(ms) _delay_ms(ms)
+# define wait_us(us) _delay_us(us)
+#elif defined(__arm__)
+# include "wait_api.h"
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/doc/keymap.md b/doc/keymap.md
index 11feeac2..9d986a8c 100644
--- a/doc/keymap.md
+++ b/doc/keymap.md
@@ -497,6 +497,13 @@ Number of taps can be configured with `TAPPING_TOGGLE` in `config.h`, `5` by def
+### 3.5 Momentary switching with Modifiers
+This registers modifier key(s) simultaneously with layer switching.
+
+ ACTION_LAYER_MODS(2, MOD_LSFT | MOD_LALT)
+
+
+
## 4. Tapping
Tapping is to press and release a key quickly. Tapping speed is determined with setting of `TAPPING_TERM`, which can be defined in `config.h`, 200ms by default.
diff --git a/protocol.mk b/protocol.mk
index 7f561e62..e057d1d6 100644
--- a/protocol.mk
+++ b/protocol.mk
@@ -9,6 +9,7 @@ endif
ifdef PS2_USE_BUSYWAIT
SRC += protocol/ps2_busywait.c
+ SRC += protocol/ps2_io_avr.c
OPT_DEFS += -DPS2_USE_BUSYWAIT
endif
@@ -23,5 +24,25 @@ ifdef PS2_USE_USART
endif
+ifdef SERIAL_MOUSE_MICROSOFT_ENABLE
+ SRC += $(PROTOCOL_DIR)/serial_mouse_microsoft.c
+ OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MICROSOFT \
+ -DMOUSE_ENABLE
+endif
+
+ifdef SERIAL_MOUSE_MOUSESYSTEMS_ENABLE
+ SRC += $(PROTOCOL_DIR)/serial_mouse_mousesystems.c
+ OPT_DEFS += -DSERIAL_MOUSE_ENABLE -DSERIAL_MOUSE_MOUSESYSTEMS \
+ -DMOUSE_ENABLE
+endif
+
+ifdef SERIAL_MOUSE_USE_SOFT
+ SRC += $(PROTOCOL_DIR)/serial_soft.c
+endif
+
+ifdef SERIAL_MOUSE_USE_UART
+ SRC += $(PROTOCOL_DIR)/serial_uart.c
+endif
+
# Search Path
VPATH += $(TOP_DIR)/protocol
diff --git a/protocol/lufa/lufa.c b/protocol/lufa/lufa.c
index 16a602df..6802f3b6 100644
--- a/protocol/lufa/lufa.c
+++ b/protocol/lufa/lufa.c
@@ -148,10 +148,23 @@ static void Console_Task(void)
*/
void EVENT_USB_Device_Connect(void)
{
+ /* For battery powered device */
+ if (!USB_IsInitialized) {
+ USB_Init();
+ USB_Device_EnableSOFEvents();
+ }
}
void EVENT_USB_Device_Disconnect(void)
{
+ /* For battery powered device */
+/* TODO: This doesn't work. After several plug in/outs can not be enumerated.
+ if (USB_IsInitialized) {
+ USB_Disable(); // Disable all interrupts
+ USB_Controller_Enable();
+ USB_INT_Enable(USB_INT_VBUSTI);
+ }
+*/
}
void EVENT_USB_Device_Reset(void)
@@ -574,7 +587,7 @@ int main(void)
print("Keyboard start.\n");
while (1) {
while (USB_DeviceState == DEVICE_STATE_Suspended) {
- suspend_power_down();
+ suspend_power_down(WDTO_120MS);
if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
USB_Device_SendRemoteWakeup();
}
diff --git a/protocol/mbed/HIDKeyboard.cpp b/protocol/mbed/HIDKeyboard.cpp
new file mode 100644
index 00000000..947077cd
--- /dev/null
+++ b/protocol/mbed/HIDKeyboard.cpp
@@ -0,0 +1,271 @@
+#include
+#include "USBHID.h"
+#include "USBHID_Types.h"
+#include "USBDescriptor.h"
+#include "HIDKeyboard.h"
+
+#define DEFAULT_CONFIGURATION (1)
+
+
+HIDKeyboard::HIDKeyboard(uint16_t vendor_id, uint16_t product_id, uint16_t product_release): USBDevice(vendor_id, product_id, product_release)
+{
+ USBDevice::connect();
+}
+
+bool HIDKeyboard::sendReport(report_keyboard_t report) {
+ USBDevice::write(EP1IN, report.raw, sizeof(report), MAX_PACKET_SIZE_EP1);
+ return true;
+}
+
+uint8_t HIDKeyboard::leds() {
+ return led_state;
+}
+
+bool HIDKeyboard::USBCallback_setConfiguration(uint8_t configuration) {
+ if (configuration != DEFAULT_CONFIGURATION) {
+ return false;
+ }
+
+ // Configure endpoints > 0
+ addEndpoint(EPINT_IN, MAX_PACKET_SIZE_EPINT);
+ //addEndpoint(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+
+ // We activate the endpoint to be able to recceive data
+ //readStart(EPINT_OUT, MAX_PACKET_SIZE_EPINT);
+ return true;
+}
+
+
+uint8_t * HIDKeyboard::stringImanufacturerDesc() {
+ static uint8_t stringImanufacturerDescriptor[] = {
+ 0x18, /*bLength*/
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ 't',0,'m',0,'k',0,'-',0,'k',0,'b',0,'d',0,'.',0,'c',0,'o',0,'m',0 /*bString iManufacturer*/
+ };
+ return stringImanufacturerDescriptor;
+}
+
+uint8_t * HIDKeyboard::stringIproductDesc() {
+ static uint8_t stringIproductDescriptor[] = {
+ 0x0a, /*bLength*/
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ 'm',0,'b',0,'e',0,'d',0 /*bString iProduct*/
+ };
+ return stringIproductDescriptor;
+}
+
+uint8_t * HIDKeyboard::stringIserialDesc() {
+ static uint8_t stringIserialDescriptor[] = {
+ 0x04, /*bLength*/
+ STRING_DESCRIPTOR, /*bDescriptorType 0x03*/
+ '0',0 /*bString iSerial*/
+ };
+ return stringIserialDescriptor;
+}
+
+uint8_t * HIDKeyboard::reportDesc() {
+ static uint8_t reportDescriptor[] = {
+ USAGE_PAGE(1), 0x01, // Generic Desktop
+ USAGE(1), 0x06, // Keyboard
+ COLLECTION(1), 0x01, // Application
+
+ USAGE_PAGE(1), 0x07, // Key Codes
+ USAGE_MINIMUM(1), 0xE0,
+ USAGE_MAXIMUM(1), 0xE7,
+ LOGICAL_MINIMUM(1), 0x00,
+ LOGICAL_MAXIMUM(1), 0x01,
+ REPORT_SIZE(1), 0x01,
+ REPORT_COUNT(1), 0x08,
+ INPUT(1), 0x02, // Data, Variable, Absolute
+
+ REPORT_COUNT(1), 0x01,
+ REPORT_SIZE(1), 0x08,
+ INPUT(1), 0x01, // Constant
+
+ REPORT_COUNT(1), 0x05,
+ REPORT_SIZE(1), 0x01,
+ USAGE_PAGE(1), 0x08, // LEDs
+ USAGE_MINIMUM(1), 0x01,
+ USAGE_MAXIMUM(1), 0x05,
+ OUTPUT(1), 0x02, // Data, Variable, Absolute
+
+ REPORT_COUNT(1), 0x01,
+ REPORT_SIZE(1), 0x03,
+ OUTPUT(1), 0x01, // Constant
+
+
+ REPORT_COUNT(1), 0x06,
+ REPORT_SIZE(1), 0x08,
+ LOGICAL_MINIMUM(1), 0x00,
+ LOGICAL_MAXIMUM(1), 0xFF,
+ USAGE_PAGE(1), 0x07, // Key Codes
+ USAGE_MINIMUM(1), 0x00,
+ USAGE_MAXIMUM(1), 0xFF,
+ INPUT(1), 0x00, // Data, Array
+ END_COLLECTION(0),
+ };
+ reportLength = sizeof(reportDescriptor);
+ return reportDescriptor;
+}
+
+uint16_t HIDKeyboard::reportDescLength() {
+ reportDesc();
+ return reportLength;
+}
+
+#define TOTAL_DESCRIPTOR_LENGTH ((1 * CONFIGURATION_DESCRIPTOR_LENGTH) \
+ + (1 * INTERFACE_DESCRIPTOR_LENGTH) \
+ + (1 * HID_DESCRIPTOR_LENGTH) \
+ + (1 * ENDPOINT_DESCRIPTOR_LENGTH))
+uint8_t * HIDKeyboard::configurationDesc() {
+ static uint8_t configurationDescriptor[] = {
+ CONFIGURATION_DESCRIPTOR_LENGTH,// bLength
+ CONFIGURATION_DESCRIPTOR, // bDescriptorType
+ LSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (LSB)
+ MSB(TOTAL_DESCRIPTOR_LENGTH), // wTotalLength (MSB)
+ 0x01, // bNumInterfaces
+ DEFAULT_CONFIGURATION, // bConfigurationValue
+ 0x00, // iConfiguration
+ C_RESERVED | C_REMOTE_WAKEUP, // bmAttributes
+ C_POWER(100), // bMaxPowerHello World from Mbed
+
+ INTERFACE_DESCRIPTOR_LENGTH, // bLength
+ INTERFACE_DESCRIPTOR, // bDescriptorType
+ 0x00, // bInterfaceNumber
+ 0x00, // bAlternateSetting
+ 0x01, // bNumEndpoints
+ HID_CLASS, // bInterfaceClass
+ 1, // bInterfaceSubClass (boot)
+ 1, // bInterfaceProtocol (keyboard)
+ 0x00, // iInterface
+
+ HID_DESCRIPTOR_LENGTH, // bLength
+ HID_DESCRIPTOR, // bDescriptorType
+ LSB(HID_VERSION_1_11), // bcdHID (LSB)
+ MSB(HID_VERSION_1_11), // bcdHID (MSB)
+ 0x00, // bCountryCode
+ 0x01, // bNumDescriptors
+ REPORT_DESCRIPTOR, // bDescriptorType
+ (uint8_t)(LSB(reportDescLength())), // wDescriptorLength (LSB)
+ (uint8_t)(MSB(reportDescLength())), // wDescriptorLength (MSB)
+
+ ENDPOINT_DESCRIPTOR_LENGTH, // bLength
+ ENDPOINT_DESCRIPTOR, // bDescriptorType
+ PHY_TO_DESC(EP1IN), // bEndpointAddress
+ E_INTERRUPT, // bmAttributes
+ LSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (LSB)
+ MSB(MAX_PACKET_SIZE_EPINT), // wMaxPacketSize (MSB)
+ 1, // bInterval (milliseconds)
+ };
+ return configurationDescriptor;
+}
+
+#if 0
+uint8_t * HIDKeyboard::deviceDesc() {
+ static uint8_t deviceDescriptor[] = {
+ DEVICE_DESCRIPTOR_LENGTH, /* bLength */
+ DEVICE_DESCRIPTOR, /* bDescriptorType */
+ LSB(USB_VERSION_2_0), /* bcdUSB (LSB) */
+ MSB(USB_VERSION_2_0), /* bcdUSB (MSB) */
+ 0x00, /* bDeviceClass */
+ 0x00, /* bDeviceSubClass */
+ 0x00, /* bDeviceprotocol */
+ MAX_PACKET_SIZE_EP0, /* bMaxPacketSize0 */
+ (uint8_t)(LSB(0xfeed)), /* idVendor (LSB) */
+ (uint8_t)(MSB(0xfeed)), /* idVendor (MSB) */
+ (uint8_t)(LSB(0x1bed)), /* idProduct (LSB) */
+ (uint8_t)(MSB(0x1bed)), /* idProduct (MSB) */
+ (uint8_t)(LSB(0x0002)), /* bcdDevice (LSB) */
+ (uint8_t)(MSB(0x0002)), /* bcdDevice (MSB) */
+ 0, /* iManufacturer */
+ 0, /* iProduct */
+ 0, /* iSerialNumber */
+ 0x01 /* bNumConfigurations */
+ };
+ return deviceDescriptor;
+}
+#endif
+
+bool HIDKeyboard::USBCallback_request() {
+ bool success = false;
+ CONTROL_TRANSFER * transfer = getTransferPtr();
+ uint8_t *hidDescriptor;
+
+ // Process additional standard requests
+
+ if ((transfer->setup.bmRequestType.Type == STANDARD_TYPE))
+ {
+ switch (transfer->setup.bRequest)
+ {
+ case GET_DESCRIPTOR:
+ switch (DESCRIPTOR_TYPE(transfer->setup.wValue))
+ {
+ case REPORT_DESCRIPTOR:
+ if ((reportDesc() != NULL) \
+ && (reportDescLength() != 0))
+ {
+ transfer->remaining = reportDescLength();
+ transfer->ptr = reportDesc();
+ transfer->direction = DEVICE_TO_HOST;
+ success = true;
+ }
+ break;
+ case HID_DESCRIPTOR:
+ // Find the HID descriptor, after the configuration descriptor
+ hidDescriptor = findDescriptor(HID_DESCRIPTOR);
+ if (hidDescriptor != NULL)
+ {
+ transfer->remaining = HID_DESCRIPTOR_LENGTH;
+ transfer->ptr = hidDescriptor;
+ transfer->direction = DEVICE_TO_HOST;
+ success = true;
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ // Process class-specific requests
+ if (transfer->setup.bmRequestType.Type == CLASS_TYPE)
+ {
+ switch (transfer->setup.bRequest) {
+ case SET_REPORT:
+ // LED indicator
+ // TODO: check Interface and Report length?
+ // if (transfer->setup.wIndex == INTERFACE_KEYBOAD) { }
+ // if (transfer->setup.wLength == 1)
+
+ transfer->remaining = 1;
+ //transfer->ptr = ?? what ptr should be set when OUT(not used?)
+ transfer->direction = HOST_TO_DEVICE;
+ transfer->notify = true; /* notify with USBCallback_requestCompleted */
+ success = true;
+ default:
+ break;
+ }
+ }
+
+ return success;
+}
+
+void HIDKeyboard::USBCallback_requestCompleted(uint8_t * buf, uint32_t length)
+{
+ if (length > 0) {
+ CONTROL_TRANSFER *transfer = getTransferPtr();
+ if (transfer->setup.bmRequestType.Type == CLASS_TYPE) {
+ switch (transfer->setup.bRequest) {
+ case SET_REPORT:
+ led_state = buf[0];
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
diff --git a/protocol/mbed/HIDKeyboard.h b/protocol/mbed/HIDKeyboard.h
new file mode 100644
index 00000000..c537e5ec
--- /dev/null
+++ b/protocol/mbed/HIDKeyboard.h
@@ -0,0 +1,31 @@
+#ifndef HIDKEYBOARD_H
+
+#include "stdint.h"
+#include "stdbool.h"
+#include "USBHID.h"
+#include "report.h"
+
+
+class HIDKeyboard : public USBDevice {
+public:
+ HIDKeyboard(uint16_t vendor_id = 0xFEED, uint16_t product_id = 0xabed, uint16_t product_release = 0x0001);
+
+ bool sendReport(report_keyboard_t report);
+ uint8_t leds(void);
+protected:
+ uint16_t reportLength;
+ virtual bool USBCallback_setConfiguration(uint8_t configuration);
+ virtual uint8_t * stringImanufacturerDesc();
+ virtual uint8_t * stringIproductDesc();
+ virtual uint8_t * stringIserialDesc();
+ virtual uint16_t reportDescLength();
+ virtual uint8_t * reportDesc();
+ virtual uint8_t * configurationDesc();
+ //virtual uint8_t * deviceDesc();
+ virtual bool USBCallback_request();
+ virtual void USBCallback_requestCompleted(uint8_t * buf, uint32_t length);
+private:
+ uint8_t led_state;
+};
+
+#endif
diff --git a/protocol/mbed/mbed_driver.cpp b/protocol/mbed/mbed_driver.cpp
new file mode 100644
index 00000000..6c7b16e2
--- /dev/null
+++ b/protocol/mbed/mbed_driver.cpp
@@ -0,0 +1,41 @@
+#include "HIDKeyboard.h"
+#include "host.h"
+#include "host_driver.h"
+#include "mbed_driver.h"
+
+HIDKeyboard keyboard;
+
+
+/* Host driver */
+static uint8_t keyboard_leds(void);
+static void send_keyboard(report_keyboard_t *report);
+static void send_mouse(report_mouse_t *report);
+static void send_system(uint16_t data);
+static void send_consumer(uint16_t data);
+
+host_driver_t mbed_driver = {
+ keyboard_leds,
+ send_keyboard,
+ send_mouse,
+ send_system,
+ send_consumer
+};
+
+
+static uint8_t keyboard_leds(void)
+{
+ return keyboard.leds();
+}
+static void send_keyboard(report_keyboard_t *report)
+{
+ keyboard.sendReport(*report);
+}
+static void send_mouse(report_mouse_t *report)
+{
+}
+static void send_system(uint16_t data)
+{
+}
+static void send_consumer(uint16_t data)
+{
+}
diff --git a/protocol/mbed/mbed_driver.h b/protocol/mbed/mbed_driver.h
new file mode 100644
index 00000000..dd1153b4
--- /dev/null
+++ b/protocol/mbed/mbed_driver.h
@@ -0,0 +1,3 @@
+#include "host_driver.h"
+
+extern host_driver_t mbed_driver;
diff --git a/protocol/pjrc/usb_keyboard.c b/protocol/pjrc/usb_keyboard.c
index d1683318..758a4edc 100644
--- a/protocol/pjrc/usb_keyboard.c
+++ b/protocol/pjrc/usb_keyboard.c
@@ -39,7 +39,7 @@ uint8_t keyboard_protocol=1;
// the idle configuration, how often we send the report to the
// host (ms * 4) even when it hasn't changed
// Windows and Linux set 0 while OS X sets 6(24ms) by SET_IDLE request.
-uint8_t keyobard_idle=125;
+uint8_t keyboard_idle=125;
// count until idle timeout
uint8_t usb_keyboard_idle_count=0;
diff --git a/protocol/ps2.h b/protocol/ps2.h
index 703e0c27..2e75d13f 100644
--- a/protocol/ps2.h
+++ b/protocol/ps2.h
@@ -39,8 +39,9 @@ POSSIBILITY OF SUCH DAMAGE.
#define PS2_H
#include
-#include
-#include
+#include "wait.h"
+#include "ps2_io.h"
+#include "print.h"
/*
* Primitive PS/2 Library for AVR
@@ -93,79 +94,27 @@ void ps2_host_set_led(uint8_t usb_led);
uint8_t ps2_enabled(void);
-/* Check port settings for clock and data line */
-#if !(defined(PS2_CLOCK_PORT) && \
- defined(PS2_CLOCK_PIN) && \
- defined(PS2_CLOCK_DDR) && \
- defined(PS2_CLOCK_BIT))
-# error "PS/2 clock port setting is required in config.h"
-#endif
-
-#if !(defined(PS2_DATA_PORT) && \
- defined(PS2_DATA_PIN) && \
- defined(PS2_DATA_DDR) && \
- defined(PS2_DATA_BIT))
-# error "PS/2 data port setting is required in config.h"
-#endif
-
/*--------------------------------------------------------------------
* static functions
*------------------------------------------------------------------*/
-static inline void clock_lo(void)
-{
- PS2_CLOCK_PORT &= ~(1<
-#include
+#include "wait.h"
#include "ps2.h"
+#include "ps2_io.h"
#include "debug.h"
@@ -58,8 +59,11 @@ uint8_t ps2_error = PS2_ERR_NONE;
void ps2_host_init(void)
{
+ clock_init();
+ data_init();
+
// POR(150-2000ms) plus BAT(300-500ms) may take 2.5sec([3]p.20)
- _delay_ms(2500);
+ wait_ms(2500);
inhibit();
}
@@ -71,7 +75,7 @@ uint8_t ps2_host_send(uint8_t data)
/* terminate a transmission if we have */
inhibit();
- _delay_us(100); // 100us [4]p.13, [5]p.50
+ wait_us(100); // 100us [4]p.13, [5]p.50
/* 'Request to Send' and Start bit */
data_lo();
@@ -80,7 +84,7 @@ uint8_t ps2_host_send(uint8_t data)
/* Data bit */
for (uint8_t i = 0; i < 8; i++) {
- _delay_us(15);
+ wait_us(15);
if (data&(1<
+#include
+
+/* Check port settings for clock and data line */
+#if !(defined(PS2_CLOCK_PORT) && \
+ defined(PS2_CLOCK_PIN) && \
+ defined(PS2_CLOCK_DDR) && \
+ defined(PS2_CLOCK_BIT))
+# error "PS/2 clock port setting is required in config.h"
+#endif
+
+#if !(defined(PS2_DATA_PORT) && \
+ defined(PS2_DATA_PIN) && \
+ defined(PS2_DATA_DDR) && \
+ defined(PS2_DATA_BIT))
+# error "PS/2 data port setting is required in config.h"
+#endif
+
+
+/*
+ * Clock
+ */
+void clock_init(void)
+{
+}
+
+void clock_lo(void)
+{
+ PS2_CLOCK_PORT &= ~(1<
+#include "ps2_io.h"
+#include "gpio_api.h"
+
+
+static gpio_t clock;
+static gpio_t data;
+
+/*
+ * Clock
+ */
+void clock_init(void)
+{
+ gpio_init(&clock, P0_9);
+ gpio_mode(&clock, OpenDrain|PullNone);
+}
+
+void clock_lo(void)
+{
+ gpio_dir(&clock, PIN_OUTPUT);
+ gpio_write(&clock, 0);
+}
+void clock_hi(void)
+{
+ gpio_dir(&clock, PIN_OUTPUT);
+ gpio_write(&clock, 1);
+}
+
+bool clock_in(void)
+{
+ gpio_dir(&clock, PIN_INPUT);
+ return gpio_read(&clock);
+}
+
+/*
+ * Data
+ */
+void data_init(void)
+{
+ gpio_init(&data, P0_8);
+ gpio_mode(&data, OpenDrain|PullNone);
+}
+
+void data_lo(void)
+{
+ gpio_dir(&data, PIN_OUTPUT);
+ gpio_write(&data, 0);
+}
+
+void data_hi(void)
+{
+ gpio_dir(&data, PIN_OUTPUT);
+ gpio_write(&data, 1);
+}
+
+bool data_in(void)
+{
+ gpio_dir(&data, PIN_INPUT);
+ return gpio_read(&data);
+}
diff --git a/protocol/serial_mouse.h b/protocol/serial_mouse.h
new file mode 100644
index 00000000..226314fc
--- /dev/null
+++ b/protocol/serial_mouse.h
@@ -0,0 +1,33 @@
+/*
+Copyright 2014 Robin Haberkorn
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#ifndef SERIAL_MOUSE_H
+#define SERIAL_MOUSE_H
+
+#include
+
+#include "serial.h"
+
+static inline uint8_t serial_mouse_init(void)
+{
+ serial_init();
+ return 0;
+}
+
+void serial_mouse_task(void);
+
+#endif
diff --git a/protocol/serial_mouse_microsoft.c b/protocol/serial_mouse_microsoft.c
new file mode 100644
index 00000000..ab74b7cd
--- /dev/null
+++ b/protocol/serial_mouse_microsoft.c
@@ -0,0 +1,124 @@
+/*
+Copyright 2014 Robin Haberkorn
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include
+#include
+#include
+
+#include "serial.h"
+#include "serial_mouse.h"
+#include "report.h"
+#include "host.h"
+#include "timer.h"
+#include "print.h"
+#include "debug.h"
+
+#ifdef MAX
+#undef MAX
+#endif
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+
+static void print_usb_data(const report_mouse_t *report);
+
+void serial_mouse_task(void)
+{
+ /* 3 byte ring buffer */
+ static uint8_t buffer[3];
+ static int buffer_cur = 0;
+
+ static report_mouse_t report = {};
+
+ int16_t rcv;
+
+ rcv = serial_recv2();
+ if (rcv < 0)
+ /* no new data */
+ return;
+
+ if (debug_mouse)
+ xprintf("serial_mouse: byte: %04X\n", rcv);
+
+ /*
+ * If bit 6 is one, this signals the beginning
+ * of a 3 byte sequence/packet.
+ */
+ if (rcv & (1 << 6))
+ buffer_cur = 0;
+
+ buffer[buffer_cur] = (uint8_t)rcv;
+
+ if (buffer_cur == 0 && buffer[buffer_cur] == 0x20) {
+ /*
+ * Logitech extension: This must be a follow-up on
+ * the last 3-byte packet signaling a middle button click
+ */
+ report.buttons |= MOUSE_BTN3;
+ report.x = report.y = 0;
+
+ print_usb_data(&report);
+ host_mouse_send(&report);
+ return;
+ }
+
+ buffer_cur++;
+
+ if (buffer_cur < 3)
+ return;
+ buffer_cur = 0;
+
+ /*
+ * parse 3 byte packet.
+ * NOTE: We only get a complete packet
+ * if the mouse moved or the button states
+ * change.
+ */
+ report.buttons = 0;
+ if (buffer[0] & (1 << 5))
+ report.buttons |= MOUSE_BTN1;
+ if (buffer[0] & (1 << 4))
+ report.buttons |= MOUSE_BTN2;
+
+ report.x = (buffer[0] << 6) | buffer[1];
+ report.y = ((buffer[0] << 4) & 0xC0) | buffer[2];
+
+ /* USB HID uses values from -127 to 127 only */
+ report.x = MAX(report.x, -127);
+ report.y = MAX(report.y, -127);
+
+#if 0
+ if (!report.buttons && !report.x && !report.y) {
+ /*
+ * Microsoft extension: Middle mouse button pressed
+ * FIXME: I don't know how exactly this extension works.
+ */
+ report.buttons |= MOUSE_BTN3;
+ }
+#endif
+
+ print_usb_data(&report);
+ host_mouse_send(&report);
+}
+
+static void print_usb_data(const report_mouse_t *report)
+{
+ if (!debug_mouse)
+ return;
+
+ xprintf("serial_mouse usb: [%02X|%d %d %d %d]\n",
+ report->buttons, report->x, report->y,
+ report->v, report->h);
+}
diff --git a/protocol/serial_mouse_mousesystems.c b/protocol/serial_mouse_mousesystems.c
new file mode 100644
index 00000000..cfe89962
--- /dev/null
+++ b/protocol/serial_mouse_mousesystems.c
@@ -0,0 +1,131 @@
+/*
+Copyright 2014 Robin Haberkorn
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program. If not, see .
+*/
+
+#include
+#include
+#include
+
+#include "serial.h"
+#include "serial_mouse.h"
+#include "report.h"
+#include "host.h"
+#include "timer.h"
+#include "print.h"
+#include "debug.h"
+
+#ifdef MAX
+#undef MAX
+#endif
+#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
+
+//#define SERIAL_MOUSE_CENTER_SCROLL
+
+static void print_usb_data(const report_mouse_t *report);
+
+void serial_mouse_task(void)
+{
+ /* 5 byte ring buffer */
+ static uint8_t buffer[5];
+ static int buffer_cur = 0;
+
+ int16_t rcv;
+
+ report_mouse_t report = {0, 0, 0, 0, 0};
+
+ rcv = serial_recv2();
+ if (rcv < 0)
+ /* no new data */
+ return;
+
+ if (debug_mouse)
+ xprintf("serial_mouse: byte: %04X\n", rcv);
+
+ /*
+ * Synchronization: mouse(4) says that all
+ * bytes but the first one in the packet have
+ * bit 7 == 0, but this is untrue.
+ * Therefore we discard all bytes up to the
+ * first one with the characteristic bit pattern.
+ */
+ if (buffer_cur == 0 && (rcv >> 3) != 0x10)
+ return;
+
+ buffer[buffer_cur++] = (uint8_t)rcv;
+
+ if (buffer_cur < 5)
+ return;
+ buffer_cur = 0;
+
+#ifdef SERIAL_MOUSE_CENTER_SCROLL
+ if ((buffer[0] & 0x7) == 0x5 && (buffer[1] || buffer[2])) {
+ /* USB HID uses only values from -127 to 127 */
+ report.h = MAX((int8_t)buffer[1], -127);
+ report.v = MAX((int8_t)buffer[2], -127);
+
+ print_usb_data(&report);
+ host_mouse_send(&report);
+
+ if (buffer[3] || buffer[4]) {
+ report.h = MAX((int8_t)buffer[3], -127);
+ report.v = MAX((int8_t)buffer[4], -127);
+
+ print_usb_data(&report);
+ host_mouse_send(&report);
+ }
+
+ return;
+ }
+#endif
+
+ /*
+ * parse 5 byte packet.
+ * NOTE: We only get a complete packet
+ * if the mouse moved or the button states
+ * change.
+ */
+ if (!(buffer[0] & (1 << 2)))
+ report.buttons |= MOUSE_BTN1;
+ if (!(buffer[0] & (1 << 1)))
+ report.buttons |= MOUSE_BTN3;
+ if (!(buffer[0] & (1 << 0)))
+ report.buttons |= MOUSE_BTN2;
+
+ /* USB HID uses only values from -127 to 127 */
+ report.x = MAX((int8_t)buffer[1], -127);
+ report.y = MAX(-(int8_t)buffer[2], -127);
+
+ print_usb_data(&report);
+ host_mouse_send(&report);
+
+ if (buffer[3] || buffer[4]) {
+ report.x = MAX((int8_t)buffer[3], -127);
+ report.y = MAX(-(int8_t)buffer[4], -127);
+
+ print_usb_data(&report);
+ host_mouse_send(&report);
+ }
+}
+
+static void print_usb_data(const report_mouse_t *report)
+{
+ if (!debug_mouse)
+ return;
+
+ xprintf("serial_mouse usb: [%02X|%d %d %d %d]\n",
+ report->buttons, report->x, report->y,
+ report->v, report->h);
+}
diff --git a/protocol/serial_soft.c b/protocol/serial_soft.c
index e8870bcd..44822b7e 100644
--- a/protocol/serial_soft.c
+++ b/protocol/serial_soft.c
@@ -122,7 +122,11 @@ void serial_send(uint8_t data)
/* signal state: IDLE: ON, START: OFF, STOP: ON, DATA0: OFF, DATA1: ON */
#ifdef SERIAL_SOFT_BIT_ORDER_MSB
+ #ifdef SERIAL_SOFT_DATA_7BIT
+ uint8_t mask = 0x40;
+ #else
uint8_t mask = 0x80;
+ #endif
#else
uint8_t mask = 0x01;
#endif
@@ -133,7 +137,11 @@ void serial_send(uint8_t data)
SERIAL_SOFT_TXD_OFF();
_delay_us(WAIT_US);
- while (mask) {
+#ifdef SERIAL_SOFT_DATA_7BIT
+ while (mask&0x7F) {
+#else
+ while (mask&0xFF) {
+#endif
if (data&mask) {
SERIAL_SOFT_TXD_ON();
parity ^= 1;
@@ -173,7 +181,11 @@ ISR(SERIAL_SOFT_RXD_VECT)
uint8_t data = 0;
#ifdef SERIAL_SOFT_BIT_ORDER_MSB
+ #ifdef SERIAL_SOFT_DATA_7BIT
+ uint8_t mask = 0x40;
+ #else
uint8_t mask = 0x80;
+ #endif
#else
uint8_t mask = 0x01;
#endif
@@ -197,7 +209,11 @@ ISR(SERIAL_SOFT_RXD_VECT)
#else
mask <<= 1;
#endif
- } while (mask);
+#ifdef SERIAL_SOFT_DATA_7BIT
+ } while (mask&0x7F);
+#else
+ } while (mask&0xFF);
+#endif
#if defined(SERIAL_SOFT_PARITY_EVEN) || defined(SERIAL_SOFT_PARITY_ODD)
/* to center of parity bit */
diff --git a/protocol/serial_uart.c b/protocol/serial_uart.c
index 6c0af881..35df27fd 100644
--- a/protocol/serial_uart.c
+++ b/protocol/serial_uart.c
@@ -41,13 +41,29 @@ POSSIBILITY OF SUCH DAMAGE.
#include "serial.h"
+#if defined(SERIAL_UART_RTS_LO) && defined(SERIAL_UART_RTS_HI)
+ // Buffer state
+ // Empty: RBUF_SPACE == RBUF_SIZE(head==tail)
+ // Last 1 space: RBUF_SPACE == 2
+ // Full: RBUF_SPACE == 1(last cell of rbuf be never used.)
+ #define RBUF_SPACE() (rbuf_head < rbuf_tail ? (rbuf_tail - rbuf_head) : (RBUF_SIZE - rbuf_head + rbuf_tail))
+ // allow to send
+ #define rbuf_check_rts_lo() do { if (RBUF_SPACE() > 2) SERIAL_UART_RTS_LO(); } while (0)
+ // prohibit to send
+ #define rbuf_check_rts_hi() do { if (RBUF_SPACE() <= 2) SERIAL_UART_RTS_HI(); } while (0)
+#else
+ #define rbuf_check_rts_lo()
+ #define rbuf_check_rts_hi()
+#endif
+
+
void serial_init(void)
{
SERIAL_UART_INIT();
}
// RX ring buffer
-#define RBUF_SIZE 8
+#define RBUF_SIZE 256
static uint8_t rbuf[RBUF_SIZE];
static uint8_t rbuf_head = 0;
static uint8_t rbuf_tail = 0;
@@ -61,6 +77,7 @@ uint8_t serial_recv(void)
data = rbuf[rbuf_tail];
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
+ rbuf_check_rts_lo();
return data;
}
@@ -73,6 +90,7 @@ int16_t serial_recv2(void)
data = rbuf[rbuf_tail];
rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE;
+ rbuf_check_rts_lo();
return data;
}
@@ -90,4 +108,5 @@ ISR(SERIAL_UART_RXD_VECT)
rbuf[rbuf_head] = SERIAL_UART_DATA;
rbuf_head = next;
}
+ rbuf_check_rts_hi();
}
diff --git a/protocol/usb_hid/arduino-1.0.1/cores/arduino/WString.h b/protocol/usb_hid/arduino-1.0.1/cores/arduino/WString.h
index d76d2a33..947325e5 100644
--- a/protocol/usb_hid/arduino-1.0.1/cores/arduino/WString.h
+++ b/protocol/usb_hid/arduino-1.0.1/cores/arduino/WString.h
@@ -35,7 +35,7 @@
// -std=c++0x
class __FlashStringHelper;
-#define F(string_literal) (reinterpret_cast<__FlashStringHelper *>(PSTR(string_literal)))
+#define F(string_literal) (reinterpret_cast(PSTR(string_literal)))
// An inherited class for holding the result of a concatenation. These
// result objects are assumed to be writable by subsequent concatenations.
diff --git a/protocol/usb_hid/override_wiring.c b/protocol/usb_hid/override_wiring.c
index 3b3f5e30..1e9a94ce 100644
--- a/protocol/usb_hid/override_wiring.c
+++ b/protocol/usb_hid/override_wiring.c
@@ -1,6 +1,7 @@
/*
* To keep Timer0 for common/timer.c override arduino/wiring.c.
*/
+#define __DELAY_BACKWARD_COMPATIBLE__
#include
#include "common/timer.h"
#include "Arduino.h"
diff --git a/protocol/usb_hid/parser.cpp b/protocol/usb_hid/parser.cpp
index 66e94951..28151f9d 100644
--- a/protocol/usb_hid/parser.cpp
+++ b/protocol/usb_hid/parser.cpp
@@ -1,5 +1,3 @@
-#include
-
#include "parser.h"
#include "usb_hid.h"
diff --git a/protocol/vusb/usbdrv/usbdrv.c b/protocol/vusb/usbdrv/usbdrv.c
index 21ed554f..2e8dd875 100644
--- a/protocol/vusb/usbdrv/usbdrv.c
+++ b/protocol/vusb/usbdrv/usbdrv.c
@@ -67,7 +67,7 @@ optimizing hints:
#if USB_CFG_DESCR_PROPS_STRING_0 == 0
#undef USB_CFG_DESCR_PROPS_STRING_0
#define USB_CFG_DESCR_PROPS_STRING_0 sizeof(usbDescriptorString0)
-PROGMEM char usbDescriptorString0[] = { /* language descriptor */
+const PROGMEM char usbDescriptorString0[] = { /* language descriptor */
4, /* sizeof(usbDescriptorString0): length of descriptor in bytes */
3, /* descriptor type */
0x09, 0x04, /* language index (0x0409 = US-English) */
@@ -77,7 +77,7 @@ PROGMEM char usbDescriptorString0[] = { /* language descriptor */
#if USB_CFG_DESCR_PROPS_STRING_VENDOR == 0 && USB_CFG_VENDOR_NAME_LEN
#undef USB_CFG_DESCR_PROPS_STRING_VENDOR
#define USB_CFG_DESCR_PROPS_STRING_VENDOR sizeof(usbDescriptorStringVendor)
-PROGMEM int usbDescriptorStringVendor[] = {
+const PROGMEM int usbDescriptorStringVendor[] = {
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_VENDOR_NAME_LEN),
USB_CFG_VENDOR_NAME
};
@@ -86,7 +86,7 @@ PROGMEM int usbDescriptorStringVendor[] = {
#if USB_CFG_DESCR_PROPS_STRING_PRODUCT == 0 && USB_CFG_DEVICE_NAME_LEN
#undef USB_CFG_DESCR_PROPS_STRING_PRODUCT
#define USB_CFG_DESCR_PROPS_STRING_PRODUCT sizeof(usbDescriptorStringDevice)
-PROGMEM int usbDescriptorStringDevice[] = {
+const PROGMEM int usbDescriptorStringDevice[] = {
USB_STRING_DESCRIPTOR_HEADER(USB_CFG_DEVICE_NAME_LEN),
USB_CFG_DEVICE_NAME
};
@@ -108,7 +108,7 @@ PROGMEM int usbDescriptorStringSerialNumber[] = {
#if USB_CFG_DESCR_PROPS_DEVICE == 0
#undef USB_CFG_DESCR_PROPS_DEVICE
#define USB_CFG_DESCR_PROPS_DEVICE sizeof(usbDescriptorDevice)
-PROGMEM char usbDescriptorDevice[] = { /* USB device descriptor */
+const PROGMEM char usbDescriptorDevice[] = { /* USB device descriptor */
18, /* sizeof(usbDescriptorDevice): length of descriptor in bytes */
USBDESCR_DEVICE, /* descriptor type */
0x10, 0x01, /* USB version supported */
diff --git a/protocol/vusb/usbdrv/usbdrv.h b/protocol/vusb/usbdrv/usbdrv.h
index 3a78f307..42fe1637 100644
--- a/protocol/vusb/usbdrv/usbdrv.h
+++ b/protocol/vusb/usbdrv/usbdrv.h
@@ -452,43 +452,43 @@ extern
#if !(USB_CFG_DESCR_PROPS_DEVICE & USB_PROP_IS_RAM)
PROGMEM
#endif
-char usbDescriptorDevice[];
+const char usbDescriptorDevice[];
extern
#if !(USB_CFG_DESCR_PROPS_CONFIGURATION & USB_PROP_IS_RAM)
PROGMEM
#endif
-char usbDescriptorConfiguration[];
+const char usbDescriptorConfiguration[];
extern
#if !(USB_CFG_DESCR_PROPS_HID_REPORT & USB_PROP_IS_RAM)
PROGMEM
#endif
-char usbDescriptorHidReport[];
+const char usbDescriptorHidReport[];
extern
#if !(USB_CFG_DESCR_PROPS_STRING_0 & USB_PROP_IS_RAM)
PROGMEM
#endif
-char usbDescriptorString0[];
+const char usbDescriptorString0[];
extern
#if !(USB_CFG_DESCR_PROPS_STRING_VENDOR & USB_PROP_IS_RAM)
PROGMEM
#endif
-int usbDescriptorStringVendor[];
+const int usbDescriptorStringVendor[];
extern
#if !(USB_CFG_DESCR_PROPS_STRING_PRODUCT & USB_PROP_IS_RAM)
PROGMEM
#endif
-int usbDescriptorStringDevice[];
+const int usbDescriptorStringDevice[];
extern
#if !(USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER & USB_PROP_IS_RAM)
PROGMEM
#endif
-int usbDescriptorStringSerialNumber[];
+const int usbDescriptorStringSerialNumber[];
#endif /* __ASSEMBLER__ */
diff --git a/protocol/vusb/vusb.c b/protocol/vusb/vusb.c
index 328885a9..7d0292ed 100644
--- a/protocol/vusb/vusb.c
+++ b/protocol/vusb/vusb.c
@@ -35,6 +35,13 @@ static report_keyboard_t kbuf[KBUF_SIZE];
static uint8_t kbuf_head = 0;
static uint8_t kbuf_tail = 0;
+typedef struct {
+ uint8_t modifier;
+ uint8_t reserved;
+ uint8_t keycode[6];
+} keyboard_report_t;
+
+static keyboard_report_t keyboard_report; // sent to PC
/* transfer keyboard report from buffer */
void vusb_transfer_keyboard(void)
@@ -168,8 +175,8 @@ usbRequest_t *rq = (void *)data;
if(rq->bRequest == USBRQ_HID_GET_REPORT){
debug("GET_REPORT:");
/* we only have one report type, so don't look at wValue */
- usbMsgPtr = (void *)keyboard_report;
- return sizeof(*keyboard_report);
+ usbMsgPtr = (void *)&keyboard_report;
+ return sizeof(keyboard_report);
}else if(rq->bRequest == USBRQ_HID_GET_IDLE){
debug("GET_IDLE: ");
//debug_hex(vusb_idle_rate);
@@ -232,7 +239,7 @@ uchar usbFunctionWrite(uchar *data, uchar len)
*
* from an example in HID spec appendix
*/
-PROGMEM uchar keyboard_hid_report[] = {
+const PROGMEM uchar keyboard_hid_report[] = {
0x05, 0x01, // Usage Page (Generic Desktop),
0x09, 0x06, // Usage (Keyboard),
0xA1, 0x01, // Collection (Application),
@@ -275,7 +282,7 @@ PROGMEM uchar keyboard_hid_report[] = {
* http://www.keil.com/forum/15671/
* http://www.microsoft.com/whdc/device/input/wheel.mspx
*/
-PROGMEM uchar mouse_hid_report[] = {
+const PROGMEM uchar mouse_hid_report[] = {
/* mouse */
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
@@ -358,7 +365,7 @@ PROGMEM uchar mouse_hid_report[] = {
* contains: device, interface, HID and endpoint descriptors
*/
#if USB_CFG_DESCR_PROPS_CONFIGURATION
-PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */
+const PROGMEM char usbDescriptorConfiguration[] = { /* USB configuration descriptor */
9, /* sizeof(usbDescriptorConfiguration): length of descriptor in bytes */
USBDESCR_CONFIG, /* descriptor type */
9 + (9 + 9 + 7) + (9 + 9 + 7), 0,
diff --git a/rules.mk b/rules.mk
index 7a40d1de..83c9da5f 100644
--- a/rules.mk
+++ b/rules.mk
@@ -565,6 +565,7 @@ $(OBJDIR)/%.o : %.cpp
# Assemble: create object files from assembler source files.
$(OBJDIR)/%.o : %.S
@echo
+ mkdir -p $(@D)
@echo $(MSG_ASSEMBLING) $<
$(CC) -c $(ALL_ASFLAGS) $< -o $@
diff --git a/tool/mbed/common.mk b/tool/mbed/common.mk
new file mode 100644
index 00000000..93a927a3
--- /dev/null
+++ b/tool/mbed/common.mk
@@ -0,0 +1,79 @@
+OBJECTS += \
+ $(OBJDIR)/common/action.o \
+ $(OBJDIR)/common/action_tapping.o \
+ $(OBJDIR)/common/action_macro.o \
+ $(OBJDIR)/common/action_layer.o \
+ $(OBJDIR)/common/action_util.o \
+ $(OBJDIR)/common/host.o \
+ $(OBJDIR)/common/keymap.o \
+ $(OBJDIR)/common/keyboard.o \
+ $(OBJDIR)/common/util.o \
+ $(OBJDIR)/common/mbed/suspend.o \
+ $(OBJDIR)/common/mbed/timer.o \
+ $(OBJDIR)/common/mbed/xprintf.o \
+ $(OBJDIR)/common/mbed/bootloader.o \
+
+INCLUDE_PATHS += \
+ -I$(TMK_DIR)/common \
+ -I$(TMK_DIR)/protocol
+
+CC_FLAGS += -include $(CONFIG_H)
+
+
+
+# Option modules
+ifdef BOOTMAGIC_ENABLE
+ $(error Not Supported)
+ OBJECTS += $(OBJDIR)/common/bootmagic.o
+ OBJECTS += $(OBJDIR)/common/mbed/eeprom.o
+ OPT_DEFS += -DBOOTMAGIC_ENABLE
+endif
+
+ifdef MOUSEKEY_ENABLE
+ OBJECTS += $(OBJDIR)/common/mousekey.o
+ OPT_DEFS += -DMOUSEKEY_ENABLE
+ OPT_DEFS += -DMOUSE_ENABLE
+endif
+
+ifdef EXTRAKEY_ENABLE
+ $(error Not Supported)
+ OPT_DEFS += -DEXTRAKEY_ENABLE
+endif
+
+ifdef CONSOLE_ENABLE
+ $(error Not Supported)
+ OPT_DEFS += -DCONSOLE_ENABLE
+else
+ OPT_DEFS += -DNO_PRINT
+ OPT_DEFS += -DNO_DEBUG
+endif
+
+ifdef COMMAND_ENABLE
+ $(error Not Supported)
+ SRC += common/command.c
+ OPT_DEFS += -DCOMMAND_ENABLE
+endif
+
+ifdef NKRO_ENABLE
+ $(error Not Supported)
+ OPT_DEFS += -DNKRO_ENABLE
+endif
+
+ifdef SLEEP_LED_ENABLE
+ $(error Not Supported)
+ SRC += common/sleep_led.c
+ OPT_DEFS += -DSLEEP_LED_ENABLE
+ OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
+endif
+
+ifdef BACKLIGHT_ENABLE
+ $(error Not Supported)
+ SRC += common/backlight.c
+ OPT_DEFS += -DBACKLIGHT_ENABLE
+endif
+
+ifdef KEYMAP_SECTION_ENABLE
+ $(error Not Supported)
+ OPT_DEFS += -DKEYMAP_SECTION_ENABLE
+ EXTRALDFLAGS = -Wl,-L$(TOP_DIR),-Tldscript_keymap_avr5.x
+endif
diff --git a/tool/mbed/gcc.mk b/tool/mbed/gcc.mk
new file mode 100644
index 00000000..032f7c6c
--- /dev/null
+++ b/tool/mbed/gcc.mk
@@ -0,0 +1,80 @@
+###############################################################################
+GCC_BIN =
+AS = $(GCC_BIN)arm-none-eabi-as
+CC = $(GCC_BIN)arm-none-eabi-gcc
+CPP = $(GCC_BIN)arm-none-eabi-g++
+LD = $(GCC_BIN)arm-none-eabi-gcc
+OBJCOPY = $(GCC_BIN)arm-none-eabi-objcopy
+OBJDUMP = $(GCC_BIN)arm-none-eabi-objdump
+SIZE = $(GCC_BIN)arm-none-eabi-size
+CHKSUM = $(TMK_DIR)/tool/mbed/lpc-vector-checksum
+
+CPU = -mcpu=cortex-m0 -mthumb
+
+CC_FLAGS += $(CPU) -c -g -fno-common -fmessage-length=0 -Wall -fno-exceptions -ffunction-sections -fdata-sections
+CC_FLAGS += -MMD -MP
+CC_SYMBOLS = -DTARGET_LPC11U35_401 -DTARGET_M0 -DTARGET_NXP -DTARGET_LPC11UXX -DTOOLCHAIN_GCC_ARM -DTOOLCHAIN_GCC -D__CORTEX_M0 -DARM_MATH_CM0 -DMBED_BUILD_TIMESTAMP=1399108688.49 -D__MBED__=1
+
+LD_FLAGS = -mcpu=cortex-m0 -mthumb -Wl,--gc-sections --specs=nano.specs
+LD_FLAGS += -Wl,-Map=$(OBJDIR)/$(PROJECT).map,--cref
+LD_SYS_LIBS = -lstdc++ -lsupc++ -lm -lc -lgcc -lnosys
+
+ifeq ($(DEBUG), 1)
+ CC_FLAGS += -DDEBUG -O0
+else
+ CC_FLAGS += -DNDEBUG -Os
+endif
+
+all: $(OBJDIR)/$(PROJECT).bin $(OBJDIR)/$(PROJECT).hex size
+
+clean:
+ rm -f $(OBJDIR)/$(PROJECT).bin $(OBJDIR)/$(PROJECT).elf $(OBJDIR)/$(PROJECT).hex $(OBJDIR)/$(PROJECT).map $(OBJDIR)/$(PROJECT).lst $(OBJECTS) $(DEPS)
+ rm -fr $(OBJDIR)
+
+$(OBJDIR)/%.o: %.s
+ mkdir -p $(@D)
+ $(AS) $(CPU) -o $@ $<
+
+$(OBJDIR)/%.o: %.c
+ mkdir -p $(@D)
+ $(CC) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu99 $(INCLUDE_PATHS) -o $@ $<
+
+$(OBJDIR)/%.o: %.cpp
+ mkdir -p $(@D)
+ $(CPP) $(CC_FLAGS) $(CC_SYMBOLS) -std=gnu++98 $(INCLUDE_PATHS) -o $@ $<
+
+
+$(OBJDIR)/$(PROJECT).elf: $(OBJECTS) $(SYS_OBJECTS)
+ $(LD) $(LD_FLAGS) -T$(LINKER_SCRIPT) $(LIBRARY_PATHS) -o $@ $^ $(LIBRARIES) $(LD_SYS_LIBS) $(LIBRARIES) $(LD_SYS_LIBS)
+ @echo ""
+ @echo "*****"
+ @echo "***** You must modify vector checksum value in *.bin and *.hex files."
+ @echo "*****"
+ @echo ""
+
+$(OBJDIR)/$(PROJECT).bin: $(OBJDIR)/$(PROJECT).elf
+ @$(OBJCOPY) -O binary $< $@
+ @echo "Writing vector checksum value into $@ ..."
+ @$(CHKSUM) $@
+ @echo
+
+$(OBJDIR)/$(PROJECT).hex: $(OBJDIR)/$(PROJECT).elf
+ @$(OBJCOPY) -O ihex $< $@
+
+$(OBJDIR)/$(PROJECT).lst: $(OBJDIR)/$(PROJECT).elf
+ @$(OBJDUMP) -Sdh $< > $@
+
+lst: $(OBJDIR)/$(PROJECT).lst
+
+size:
+ $(SIZE) $(OBJDIR)/$(PROJECT).elf
+
+prog: $(OBJDIR)/$(PROJECT).bin
+ @echo "Program..."
+ifneq ($(shell mount | grep 'CRP DISABLD'),)
+ umount /dev/nxpisp >/dev/null 2>&1
+endif
+ dd if=$< of=/dev/nxpisp seek=4
+
+DEPS = $(OBJECTS:.o=.d) $(SYS_OBJECTS:.o=.d)
+-include $(DEPS)
diff --git a/tool/mbed/lpc-vector-checksum.c b/tool/mbed/lpc-vector-checksum.c
new file mode 100644
index 00000000..316a1253
--- /dev/null
+++ b/tool/mbed/lpc-vector-checksum.c
@@ -0,0 +1,99 @@
+/***************************************************************************
+* https://github.com/dhylands/projects/blob/master/lpc/lpc-vector-checksum/lpc-vector-checksum.c
+*
+* Copyright (c) 2012 by Dave Hylands
+* All Rights Reserved
+*
+* Permission is granted to any individual or institution to use, copy,
+* modify, or redistribute this file so long as it is not sold for profit,
+* and that this copyright notice is retained.
+*
+***************************************************************************
+*
+* This program calculates the vector checksum used in LPC17xx binary
+* images.
+*
+* Usage: lpc-vector-checksum file
+*
+***************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+
+/***************************************************************************/
+/**
+* update_vector_checksum
+*
+* The algorithim is to write the checksum such that the checksum of the
+* first 8 words is equal to zero.
+*
+* The LPC1768 uses little-endian, and this particular routine assumes
+* that it's running on a little-endian architecture.
+*/
+static int update_vector_checksum( const char *filename )
+{
+ uint32_t sum;
+ uint32_t header[8];
+ FILE *fs;
+ int i;
+
+ if (( fs = fopen( filename, "r+b" )) == NULL )
+ {
+ fprintf( stderr, "Unable to open '%s' for reading/writing (%d): %s\n",
+ filename, errno, strerror( errno ));
+ return 0;
+ }
+
+ if ( fread( header, sizeof( header ), 1, fs ) != 1 )
+ {
+ fprintf( stderr, "Failed to read header from '%s' (perhaps the file is too small?)",
+ filename );
+ fclose( fs );
+ return 0;
+ }
+
+ sum = 0;
+ for ( i = 0; i < 7; i++ )
+ {
+ sum += header[i];
+ }
+ printf( "sum = 0x%08x, value to write = 0x%08x\n", sum, -sum );
+
+ /* write back the checksum to location 7
+ * http://sigalrm.blogspot.jp/2011/10/cortex-m3-exception-vector-checksum.html
+ */
+ fseek(fs, 0x1c, SEEK_SET);
+ sum = -sum;
+ fwrite(&sum, 4, 1, fs);
+
+ fclose( fs );
+
+ return 1;
+}
+
+/***************************************************************************/
+/**
+* main
+*/
+int main( int argc, char **argv )
+{
+ int arg;
+
+ if ( argc < 2)
+ {
+ fprintf( stderr, "Usage: lpc-vector-checksum file ...\n" );
+ exit( 1 );
+ }
+
+ for ( arg = 1; arg < argc; arg++ )
+ {
+ update_vector_checksum( argv[ arg ]);
+ }
+
+ exit( 0 );
+ return 0;
+}
+
diff --git a/tool/mbed/mbed.mk b/tool/mbed/mbed.mk
new file mode 100644
index 00000000..0f12ee2a
--- /dev/null
+++ b/tool/mbed/mbed.mk
@@ -0,0 +1,99 @@
+OBJECTS += \
+ $(OBJDIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/TOOLCHAIN_GCC_ARM/startup_LPC11xx.o \
+ $(OBJDIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/cmsis_nvic.o \
+ $(OBJDIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/system_LPC11Uxx.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/port_api.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/spi_api.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/analogin_api.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_api.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/gpio_irq_api.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/serial_api.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/i2c_api.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pwmout_api.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/sleep.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/pinmap.o \
+ $(OBJDIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/us_ticker.o \
+ $(OBJDIR)/libraries/mbed/common/board.o \
+ $(OBJDIR)/libraries/mbed/common/mbed_interface.o \
+ $(OBJDIR)/libraries/mbed/common/exit.o \
+ $(OBJDIR)/libraries/mbed/common/rtc_time.o \
+ $(OBJDIR)/libraries/mbed/common/us_ticker_api.o \
+ $(OBJDIR)/libraries/mbed/common/pinmap_common.o \
+ $(OBJDIR)/libraries/mbed/common/error.o \
+ $(OBJDIR)/libraries/mbed/common/gpio.o \
+ $(OBJDIR)/libraries/mbed/common/semihost_api.o \
+ $(OBJDIR)/libraries/mbed/common/wait_api.o \
+ $(OBJDIR)/libraries/mbed/common/RawSerial.o \
+ $(OBJDIR)/libraries/mbed/common/Ticker.o \
+ $(OBJDIR)/libraries/mbed/common/FilePath.o \
+ $(OBJDIR)/libraries/mbed/common/I2C.o \
+ $(OBJDIR)/libraries/mbed/common/FileBase.o \
+ $(OBJDIR)/libraries/mbed/common/retarget.o \
+ $(OBJDIR)/libraries/mbed/common/Serial.o \
+ $(OBJDIR)/libraries/mbed/common/Stream.o \
+ $(OBJDIR)/libraries/mbed/common/FileSystemLike.o \
+ $(OBJDIR)/libraries/mbed/common/CallChain.o \
+ $(OBJDIR)/libraries/mbed/common/InterruptManager.o \
+ $(OBJDIR)/libraries/mbed/common/SerialBase.o \
+ $(OBJDIR)/libraries/mbed/common/BusInOut.o \
+ $(OBJDIR)/libraries/mbed/common/SPISlave.o \
+ $(OBJDIR)/libraries/mbed/common/I2CSlave.o \
+ $(OBJDIR)/libraries/mbed/common/FunctionPointer.o \
+ $(OBJDIR)/libraries/mbed/common/Timer.o \
+ $(OBJDIR)/libraries/mbed/common/SPI.o \
+ $(OBJDIR)/libraries/mbed/common/Timeout.o \
+ $(OBJDIR)/libraries/mbed/common/Ethernet.o \
+ $(OBJDIR)/libraries/mbed/common/TimerEvent.o \
+ $(OBJDIR)/libraries/mbed/common/CAN.o \
+ $(OBJDIR)/libraries/mbed/common/BusOut.o \
+ $(OBJDIR)/libraries/mbed/common/FileLike.o \
+ $(OBJDIR)/libraries/mbed/common/BusIn.o \
+ $(OBJDIR)/libraries/mbed/common/InterruptIn.o \
+ $(OBJDIR)/libraries/mbed/common/LocalFileSystem.o \
+ $(OBJDIR)/libraries/USBDevice/USBHID/USBMouse.o \
+ $(OBJDIR)/libraries/USBDevice/USBHID/USBHID.o \
+ $(OBJDIR)/libraries/USBDevice/USBHID/USBMouseKeyboard.o \
+ $(OBJDIR)/libraries/USBDevice/USBHID/USBKeyboard.o \
+ $(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_KL25Z.o \
+ $(OBJDIR)/libraries/USBDevice/USBDevice/USBDevice.o \
+ $(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_LPC17.o \
+ $(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_LPC40.o \
+ $(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_LPC11U.o \
+ $(OBJDIR)/libraries/USBDevice/USBDevice/USBHAL_STM32F4.o \
+ $(OBJDIR)/libraries/USBDevice/USBAudio/USBAudio.o \
+ $(OBJDIR)/libraries/USBDevice/USBSerial/USBSerial.o \
+ $(OBJDIR)/libraries/USBDevice/USBSerial/USBCDC.o \
+ $(OBJDIR)/libraries/USBDevice/USBMSD/USBMSD.o \
+ $(OBJDIR)/libraries/USBDevice/USBMIDI/USBMIDI.o
+
+INCLUDE_PATHS += \
+ -I$(MBED_DIR)/libraries/mbed/targets \
+ -I$(MBED_DIR)/libraries/mbed/targets/hal \
+ -I$(MBED_DIR)/libraries/mbed/targets/hal/TARGET_NXP \
+ -I$(MBED_DIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX \
+ -I$(MBED_DIR)/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC11UXX/TARGET_LPC11U35_401 \
+ -I$(MBED_DIR)/libraries/mbed/targets/cmsis \
+ -I$(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP \
+ -I$(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX \
+ -I$(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/TOOLCHAIN_GCC_ARM \
+ -I$(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/TOOLCHAIN_GCC_ARM/TARGET_LPC11U35_401 \
+ -I$(MBED_DIR)/libraries/mbed \
+ -I$(MBED_DIR)/libraries/mbed/hal \
+ -I$(MBED_DIR)/libraries/mbed/api \
+ -I$(MBED_DIR)/libraries/mbed/common \
+ -I$(MBED_DIR)/libraries/USBDevice \
+ -I$(MBED_DIR)/libraries/USBDevice/USBHID \
+ -I$(MBED_DIR)/libraries/USBDevice/USBDevice \
+ -I$(MBED_DIR)/libraries/USBDevice/USBAudio \
+ -I$(MBED_DIR)/libraries/USBDevice/USBSerial \
+ -I$(MBED_DIR)/libraries/USBDevice/USBMSD \
+ -I$(MBED_DIR)/libraries/USBDevice/USBMIDI
+
+OBJECTS += \
+ $(OBJDIR)/protocol/mbed/mbed_driver.o \
+ $(OBJDIR)/protocol/mbed/HIDKeyboard.o \
+
+INCLUDE_PATHS += \
+ -I$(TMK_DIR)/protocol/mbed
+
+LINKER_SCRIPT = $(MBED_DIR)/libraries/mbed/targets/cmsis/TARGET_NXP/TARGET_LPC11UXX/TOOLCHAIN_GCC_ARM/TARGET_LPC11U35_401/LPC11U35.ld