aboutsummaryrefslogtreecommitdiffstats
path: root/tmk_core
diff options
context:
space:
mode:
Diffstat (limited to 'tmk_core')
-rw-r--r--tmk_core/common.mk7
-rw-r--r--tmk_core/common/action.c4
-rw-r--r--tmk_core/common/action_util.c204
-rw-r--r--tmk_core/common/action_util.h16
-rw-r--r--tmk_core/common/backlight.c3
-rw-r--r--tmk_core/common/eeprom.h2
-rw-r--r--tmk_core/common/progmem.h2
-rw-r--r--tmk_core/common/report.c207
-rw-r--r--tmk_core/common/report.h14
-rw-r--r--tmk_core/common/test/bootloader.c19
-rw-r--r--tmk_core/common/test/eeprom.c98
-rw-r--r--tmk_core/common/test/suspend.c17
-rw-r--r--tmk_core/common/test/timer.c30
-rw-r--r--tmk_core/common/wait.h9
14 files changed, 423 insertions, 209 deletions
diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index edec2acb4..75b810d98 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -3,6 +3,8 @@ ifeq ($(PLATFORM),AVR)
PLATFORM_COMMON_DIR = $(COMMON_DIR)/avr
else ifeq ($(PLATFORM),CHIBIOS)
PLATFORM_COMMON_DIR = $(COMMON_DIR)/chibios
+else
+ PLATFORM_COMMON_DIR = $(COMMON_DIR)/test
endif
TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
@@ -16,6 +18,7 @@ TMK_COMMON_SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/debug.c \
$(COMMON_DIR)/util.c \
$(COMMON_DIR)/eeconfig.c \
+ $(COMMON_DIR)/report.c \
$(PLATFORM_COMMON_DIR)/suspend.c \
$(PLATFORM_COMMON_DIR)/timer.c \
$(PLATFORM_COMMON_DIR)/bootloader.c \
@@ -29,6 +32,10 @@ ifeq ($(PLATFORM),CHIBIOS)
TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
endif
+ifeq ($(PLATFORM),TEST)
+ TMK_COMMON_SRC += $(PLATFORM_COMMON_DIR)/eeprom.c
+endif
+
# Option modules
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index cffc0b9eb..84e661523 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -67,9 +67,11 @@ void action_exec(keyevent_t event)
#if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0))
if (has_oneshot_layer_timed_out()) {
- dprintf("Oneshot layer: timeout\n");
clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED);
}
+ if (has_oneshot_mods_timed_out()) {
+ clear_oneshot_mods();
+ }
#endif
#ifndef NO_ACTION_TAPPING
diff --git a/tmk_core/common/action_util.c b/tmk_core/common/action_util.c
index 77848c092..148162a51 100644
--- a/tmk_core/common/action_util.c
+++ b/tmk_core/common/action_util.c
@@ -25,13 +25,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
extern keymap_config_t keymap_config;
-static inline void add_key_byte(uint8_t code);
-static inline void del_key_byte(uint8_t code);
-#ifdef NKRO_ENABLE
-static inline void add_key_bit(uint8_t code);
-static inline void del_key_bit(uint8_t code);
-#endif
-
static uint8_t real_mods = 0;
static uint8_t weak_mods = 0;
static uint8_t macro_mods = 0;
@@ -50,6 +43,10 @@ static int8_t cb_count = 0;
//report_keyboard_t keyboard_report = {};
report_keyboard_t *keyboard_report = &(report_keyboard_t){};
+extern inline void add_key(uint8_t key);
+extern inline void del_key(uint8_t key);
+extern inline void clear_keys(void);
+
#ifndef NO_ACTION_ONESHOT
static int8_t oneshot_mods = 0;
static int8_t oneshot_locked_mods = 0;
@@ -134,7 +131,7 @@ void send_keyboard_report(void) {
}
#endif
keyboard_report->mods |= oneshot_mods;
- if (has_anykey()) {
+ if (has_anykey(keyboard_report)) {
clear_oneshot_mods();
}
}
@@ -143,38 +140,6 @@ void send_keyboard_report(void) {
host_keyboard_send(keyboard_report);
}
-/* key */
-void add_key(uint8_t key)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- add_key_bit(key);
- return;
- }
-#endif
- add_key_byte(key);
-}
-
-void del_key(uint8_t key)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- del_key_bit(key);
- return;
- }
-#endif
- del_key_byte(key);
-}
-
-void clear_keys(void)
-{
- // not clear mods
- for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
- keyboard_report->raw[i] = 0;
- }
-}
-
-
/* modifier */
uint8_t get_mods(void) { return real_mods; }
void add_mods(uint8_t mods) { real_mods |= mods; }
@@ -221,166 +186,7 @@ uint8_t get_oneshot_mods(void)
/*
* inspect keyboard state
*/
-uint8_t has_anykey(void)
-{
- uint8_t cnt = 0;
- for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
- if (keyboard_report->raw[i])
- cnt++;
- }
- return cnt;
-}
-
uint8_t has_anymod(void)
{
return bitpop(real_mods);
}
-
-uint8_t get_first_key(void)
-{
-#ifdef NKRO_ENABLE
- if (keyboard_protocol && keymap_config.nkro) {
- uint8_t i = 0;
- for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
- ;
- return i<<3 | biton(keyboard_report->nkro.bits[i]);
- }
-#endif
-#ifdef USB_6KRO_ENABLE
- uint8_t i = cb_head;
- do {
- if (keyboard_report->keys[i] != 0) {
- break;
- }
- i = RO_INC(i);
- } while (i != cb_tail);
- return keyboard_report->keys[i];
-#else
- return keyboard_report->keys[0];
-#endif
-}
-
-
-
-/* local functions */
-static inline void add_key_byte(uint8_t code)
-{
-#ifdef USB_6KRO_ENABLE
- int8_t i = cb_head;
- int8_t empty = -1;
- if (cb_count) {
- do {
- if (keyboard_report->keys[i] == code) {
- return;
- }
- if (empty == -1 && keyboard_report->keys[i] == 0) {
- empty = i;
- }
- i = RO_INC(i);
- } while (i != cb_tail);
- if (i == cb_tail) {
- if (cb_tail == cb_head) {
- // buffer is full
- if (empty == -1) {
- // pop head when has no empty space
- cb_head = RO_INC(cb_head);
- cb_count--;
- }
- else {
- // left shift when has empty space
- uint8_t offset = 1;
- i = RO_INC(empty);
- do {
- if (keyboard_report->keys[i] != 0) {
- keyboard_report->keys[empty] = keyboard_report->keys[i];
- keyboard_report->keys[i] = 0;
- empty = RO_INC(empty);
- }
- else {
- offset++;
- }
- i = RO_INC(i);
- } while (i != cb_tail);
- cb_tail = RO_SUB(cb_tail, offset);
- }
- }
- }
- }
- // add to tail
- keyboard_report->keys[cb_tail] = code;
- cb_tail = RO_INC(cb_tail);
- cb_count++;
-#else
- int8_t i = 0;
- int8_t empty = -1;
- for (; i < KEYBOARD_REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- break;
- }
- if (empty == -1 && keyboard_report->keys[i] == 0) {
- empty = i;
- }
- }
- if (i == KEYBOARD_REPORT_KEYS) {
- if (empty != -1) {
- keyboard_report->keys[empty] = code;
- }
- }
-#endif
-}
-
-static inline void del_key_byte(uint8_t code)
-{
-#ifdef USB_6KRO_ENABLE
- uint8_t i = cb_head;
- if (cb_count) {
- do {
- if (keyboard_report->keys[i] == code) {
- keyboard_report->keys[i] = 0;
- cb_count--;
- if (cb_count == 0) {
- // reset head and tail
- cb_tail = cb_head = 0;
- }
- if (i == RO_DEC(cb_tail)) {
- // left shift when next to tail
- do {
- cb_tail = RO_DEC(cb_tail);
- if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
- break;
- }
- } while (cb_tail != cb_head);
- }
- break;
- }
- i = RO_INC(i);
- } while (i != cb_tail);
- }
-#else
- for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
- if (keyboard_report->keys[i] == code) {
- keyboard_report->keys[i] = 0;
- }
- }
-#endif
-}
-
-#ifdef NKRO_ENABLE
-static inline void add_key_bit(uint8_t code)
-{
- 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);
- }
-}
-
-static inline void del_key_bit(uint8_t code)
-{
- 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);
- }
-}
-#endif
diff --git a/tmk_core/common/action_util.h b/tmk_core/common/action_util.h
index dd0c4c2bf..345893151 100644
--- a/tmk_core/common/action_util.h
+++ b/tmk_core/common/action_util.h
@@ -29,9 +29,17 @@ extern report_keyboard_t *keyboard_report;
void send_keyboard_report(void);
/* key */
-void add_key(uint8_t key);
-void del_key(uint8_t key);
-void clear_keys(void);
+inline void add_key(uint8_t key) {
+ add_key_to_report(keyboard_report, key);
+}
+
+inline void del_key(uint8_t key) {
+ del_key_from_report(keyboard_report, key);
+}
+
+inline void clear_keys(void) {
+ clear_keys_from_report(keyboard_report);
+}
/* modifier */
uint8_t get_mods(void);
@@ -82,9 +90,7 @@ uint8_t get_oneshot_layer_state(void);
bool has_oneshot_layer_timed_out(void);
/* inspect */
-uint8_t has_anykey(void);
uint8_t has_anymod(void);
-uint8_t get_first_key(void);
#ifdef __cplusplus
}
diff --git a/tmk_core/common/backlight.c b/tmk_core/common/backlight.c
index 0e0ad2d15..d03bfe931 100644
--- a/tmk_core/common/backlight.c
+++ b/tmk_core/common/backlight.c
@@ -28,6 +28,9 @@ void backlight_init(void)
eeconfig_init();
}
backlight_config.raw = eeconfig_read_backlight();
+ if (backlight_config.level > BACKLIGHT_LEVELS) {
+ backlight_config.level = BACKLIGHT_LEVELS;
+ }
backlight_set(backlight_config.enable ? backlight_config.level : 0);
}
diff --git a/tmk_core/common/eeprom.h b/tmk_core/common/eeprom.h
index 2cc2ccee3..3696d0df3 100644
--- a/tmk_core/common/eeprom.h
+++ b/tmk_core/common/eeprom.h
@@ -4,6 +4,8 @@
#if defined(__AVR__)
#include <avr/eeprom.h>
#else
+#include <stdint.h>
+
uint8_t eeprom_read_byte (const uint8_t *__p);
uint16_t eeprom_read_word (const uint16_t *__p);
uint32_t eeprom_read_dword (const uint32_t *__p);
diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h
index 5b2765625..a09f91be8 100644
--- a/tmk_core/common/progmem.h
+++ b/tmk_core/common/progmem.h
@@ -3,7 +3,7 @@
#if defined(__AVR__)
# include <avr/pgmspace.h>
-#elif defined(__arm__)
+#else
# define PROGMEM
# define pgm_read_byte(p) *((unsigned char*)p)
# define pgm_read_word(p) *((uint16_t*)p)
diff --git a/tmk_core/common/report.c b/tmk_core/common/report.c
new file mode 100644
index 000000000..74c6d3fdd
--- /dev/null
+++ b/tmk_core/common/report.c
@@ -0,0 +1,207 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "report.h"
+#include "host.h"
+#include "keycode_config.h"
+#include "debug.h"
+#include "util.h"
+
+uint8_t has_anykey(report_keyboard_t* keyboard_report)
+{
+ uint8_t cnt = 0;
+ for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
+ if (keyboard_report->raw[i])
+ cnt++;
+ }
+ return cnt;
+}
+
+uint8_t get_first_key(report_keyboard_t* keyboard_report)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ uint8_t i = 0;
+ for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++)
+ ;
+ return i<<3 | biton(keyboard_report->nkro.bits[i]);
+ }
+#endif
+#ifdef USB_6KRO_ENABLE
+ uint8_t i = cb_head;
+ do {
+ if (keyboard_report->keys[i] != 0) {
+ break;
+ }
+ i = RO_INC(i);
+ } while (i != cb_tail);
+ return keyboard_report->keys[i];
+#else
+ return keyboard_report->keys[0];
+#endif
+}
+
+void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
+{
+#ifdef USB_6KRO_ENABLE
+ int8_t i = cb_head;
+ int8_t empty = -1;
+ if (cb_count) {
+ do {
+ if (keyboard_report->keys[i] == code) {
+ return;
+ }
+ if (empty == -1 && keyboard_report->keys[i] == 0) {
+ empty = i;
+ }
+ i = RO_INC(i);
+ } while (i != cb_tail);
+ if (i == cb_tail) {
+ if (cb_tail == cb_head) {
+ // buffer is full
+ if (empty == -1) {
+ // pop head when has no empty space
+ cb_head = RO_INC(cb_head);
+ cb_count--;
+ }
+ else {
+ // left shift when has empty space
+ uint8_t offset = 1;
+ i = RO_INC(empty);
+ do {
+ if (keyboard_report->keys[i] != 0) {
+ keyboard_report->keys[empty] = keyboard_report->keys[i];
+ keyboard_report->keys[i] = 0;
+ empty = RO_INC(empty);
+ }
+ else {
+ offset++;
+ }
+ i = RO_INC(i);
+ } while (i != cb_tail);
+ cb_tail = RO_SUB(cb_tail, offset);
+ }
+ }
+ }
+ }
+ // add to tail
+ keyboard_report->keys[cb_tail] = code;
+ cb_tail = RO_INC(cb_tail);
+ cb_count++;
+#else
+ int8_t i = 0;
+ int8_t empty = -1;
+ for (; i < KEYBOARD_REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ break;
+ }
+ if (empty == -1 && keyboard_report->keys[i] == 0) {
+ empty = i;
+ }
+ }
+ if (i == KEYBOARD_REPORT_KEYS) {
+ if (empty != -1) {
+ keyboard_report->keys[empty] = code;
+ }
+ }
+#endif
+}
+
+void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code)
+{
+#ifdef USB_6KRO_ENABLE
+ uint8_t i = cb_head;
+ if (cb_count) {
+ do {
+ if (keyboard_report->keys[i] == code) {
+ keyboard_report->keys[i] = 0;
+ cb_count--;
+ if (cb_count == 0) {
+ // reset head and tail
+ cb_tail = cb_head = 0;
+ }
+ if (i == RO_DEC(cb_tail)) {
+ // left shift when next to tail
+ do {
+ cb_tail = RO_DEC(cb_tail);
+ if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) {
+ break;
+ }
+ } while (cb_tail != cb_head);
+ }
+ break;
+ }
+ i = RO_INC(i);
+ } while (i != cb_tail);
+ }
+#else
+ for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) {
+ if (keyboard_report->keys[i] == code) {
+ keyboard_report->keys[i] = 0;
+ }
+ }
+#endif
+}
+
+#ifdef NKRO_ENABLE
+void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
+{
+ 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);
+ }
+}
+
+void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code)
+{
+ 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);
+ }
+}
+#endif
+
+void add_key_to_report(report_keyboard_t* keyboard_report, int8_t key)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ add_key_bit(keyboard_report, key);
+ return;
+ }
+#endif
+ add_key_byte(keyboard_report, key);
+}
+
+void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key)
+{
+#ifdef NKRO_ENABLE
+ if (keyboard_protocol && keymap_config.nkro) {
+ del_key_bit(keyboard_report, key);
+ return;
+ }
+#endif
+ del_key_byte(keyboard_report, key);
+}
+
+void clear_keys_from_report(report_keyboard_t* keyboard_report)
+{
+ // not clear mods
+ for (int8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) {
+ keyboard_report->raw[i] = 0;
+ }
+} \ No newline at end of file
diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h
index 8fb28b6ce..899fc524c 100644
--- a/tmk_core/common/report.h
+++ b/tmk_core/common/report.h
@@ -174,6 +174,20 @@ typedef struct {
(key == KC_WWW_REFRESH ? AC_REFRESH : \
(key == KC_WWW_FAVORITES ? AC_BOOKMARKS : 0)))))))))))))))))))))
+uint8_t has_anykey(report_keyboard_t* keyboard_report);
+uint8_t get_first_key(report_keyboard_t* keyboard_report);
+
+void add_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
+void del_key_byte(report_keyboard_t* keyboard_report, uint8_t code);
+#ifdef NKRO_ENABLE
+void add_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
+void del_key_bit(report_keyboard_t* keyboard_report, uint8_t code);
+#endif
+
+void add_key_to_report(report_keyboard_t* keyboard_report, int8_t key);
+void del_key_from_report(report_keyboard_t* keyboard_report, uint8_t key);
+void clear_keys_from_report(report_keyboard_t* keyboard_report);
+
#ifdef __cplusplus
}
#endif
diff --git a/tmk_core/common/test/bootloader.c b/tmk_core/common/test/bootloader.c
new file mode 100644
index 000000000..5155d9ff0
--- /dev/null
+++ b/tmk_core/common/test/bootloader.c
@@ -0,0 +1,19 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "bootloader.h"
+
+void bootloader_jump(void) {}
diff --git a/tmk_core/common/test/eeprom.c b/tmk_core/common/test/eeprom.c
new file mode 100644
index 000000000..61cc039ef
--- /dev/null
+++ b/tmk_core/common/test/eeprom.c
@@ -0,0 +1,98 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "eeprom.h"
+
+#define EEPROM_SIZE 32
+
+static uint8_t buffer[EEPROM_SIZE];
+
+uint8_t eeprom_read_byte(const uint8_t *addr) {
+ uintptr_t offset = (uintptr_t)addr;
+ return buffer[offset];
+}
+
+void eeprom_write_byte(uint8_t *addr, uint8_t value) {
+ uintptr_t offset = (uintptr_t)addr;
+ buffer[offset] = value;
+}
+
+uint16_t eeprom_read_word(const uint16_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8);
+}
+
+uint32_t eeprom_read_dword(const uint32_t *addr) {
+ const uint8_t *p = (const uint8_t *)addr;
+ return eeprom_read_byte(p) | (eeprom_read_byte(p+1) << 8)
+ | (eeprom_read_byte(p+2) << 16) | (eeprom_read_byte(p+3) << 24);
+}
+
+void eeprom_read_block(void *buf, const void *addr, uint32_t len) {
+ const uint8_t *p = (const uint8_t *)addr;
+ uint8_t *dest = (uint8_t *)buf;
+ while (len--) {
+ *dest++ = eeprom_read_byte(p++);
+ }
+}
+
+void eeprom_write_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_write_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_write_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
+
+void eeprom_update_byte(uint8_t *addr, uint8_t value) {
+ eeprom_write_byte(addr, value);
+}
+
+void eeprom_update_word(uint16_t *addr, uint16_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p, value >> 8);
+}
+
+void eeprom_update_dword(uint32_t *addr, uint32_t value) {
+ uint8_t *p = (uint8_t *)addr;
+ eeprom_write_byte(p++, value);
+ eeprom_write_byte(p++, value >> 8);
+ eeprom_write_byte(p++, value >> 16);
+ eeprom_write_byte(p, value >> 24);
+}
+
+void eeprom_update_block(const void *buf, void *addr, uint32_t len) {
+ uint8_t *p = (uint8_t *)addr;
+ const uint8_t *src = (const uint8_t *)buf;
+ while (len--) {
+ eeprom_write_byte(p++, *src++);
+ }
+}
diff --git a/tmk_core/common/test/suspend.c b/tmk_core/common/test/suspend.c
new file mode 100644
index 000000000..01d1930ea
--- /dev/null
+++ b/tmk_core/common/test/suspend.c
@@ -0,0 +1,17 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+
diff --git a/tmk_core/common/test/timer.c b/tmk_core/common/test/timer.c
new file mode 100644
index 000000000..09ea91a89
--- /dev/null
+++ b/tmk_core/common/test/timer.c
@@ -0,0 +1,30 @@
+/* Copyright 2017 Fred Sundvik
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include "timer.h"
+
+// TODO: the timer should work, but at a much faster rate than realtime
+// It should also have some kind of integration with the testing system
+
+void timer_init(void) {}
+
+void timer_clear(void) {}
+
+uint16_t timer_read(void) { return 0; }
+uint32_t timer_read32(void) { return 0; }
+uint16_t timer_elapsed(uint16_t last) { return 0; }
+uint32_t timer_elapsed32(uint32_t last) { return 0; }
+
diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h
index 82727be01..911c9ddb5 100644
--- a/tmk_core/common/wait.h
+++ b/tmk_core/common/wait.h
@@ -9,13 +9,16 @@ extern "C" {
# include <util/delay.h>
# define wait_ms(ms) _delay_ms(ms)
# define wait_us(us) _delay_us(us)
-#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */
+#elif defined(PROTOCOL_CHIBIOS)
# include "ch.h"
# define wait_ms(ms) chThdSleepMilliseconds(ms)
# define wait_us(us) chThdSleepMicroseconds(us)
-#elif defined(__arm__) /* __AVR__ */
+#elif defined(__arm__)
# include "wait_api.h"
-#endif /* __AVR__ */
+#else // Unit tests
+#define wait_ms(ms)
+#define wait_us(us)
+#endif
#ifdef __cplusplus
}