diff --git a/tmk_core/common.mk b/tmk_core/common.mk
index 1efd5d8f..9cfe6d5a 100644
--- a/tmk_core/common.mk
+++ b/tmk_core/common.mk
@@ -9,6 +9,7 @@ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/print.c \
$(COMMON_DIR)/debug.c \
$(COMMON_DIR)/util.c \
+ $(COMMON_DIR)/hook.c \
$(COMMON_DIR)/avr/suspend.c \
$(COMMON_DIR)/avr/xprintf.S \
$(COMMON_DIR)/avr/timer.c \
diff --git a/tmk_core/common/action.c b/tmk_core/common/action.c
index 339b3ee6..b9040f5b 100644
--- a/tmk_core/common/action.c
+++ b/tmk_core/common/action.c
@@ -26,6 +26,7 @@ along with this program. If not, see .
#include "action_macro.h"
#include "action_util.h"
#include "action.h"
+#include "hook.h"
#ifdef DEBUG_ACTION
#include "debug.h"
@@ -39,6 +40,7 @@ void action_exec(keyevent_t event)
if (!IS_NOEVENT(event)) {
dprint("\n---- action_exec: start -----\n");
dprint("EVENT: "); debug_event(event); dprintln();
+ hook_matrix_change(event);
}
keyrecord_t record = { .event = event };
diff --git a/tmk_core/common/action_layer.c b/tmk_core/common/action_layer.c
index e6db388d..8b70eb82 100644
--- a/tmk_core/common/action_layer.c
+++ b/tmk_core/common/action_layer.c
@@ -3,6 +3,7 @@
#include "action.h"
#include "util.h"
#include "action_layer.h"
+#include "hook.h"
#ifdef DEBUG_ACTION
#include "debug.h"
@@ -62,6 +63,7 @@ static void layer_state_set(uint32_t state)
dprint("layer_state: ");
layer_debug(); dprint(" to ");
layer_state = state;
+ hook_layer_change(layer_state);
layer_debug(); dprintln();
clear_keyboard_but_mods(); // To avoid stuck keys
}
diff --git a/tmk_core/common/bootmagic.c b/tmk_core/common/bootmagic.c
index 61236bec..eb06d787 100644
--- a/tmk_core/common/bootmagic.c
+++ b/tmk_core/common/bootmagic.c
@@ -10,6 +10,7 @@
#include "action_layer.h"
#include "eeconfig.h"
#include "bootmagic.h"
+#include "hook.h"
keymap_config_t keymap_config;
@@ -41,6 +42,9 @@ void bootmagic(void)
bootloader_jump();
}
+ /* user-defined checks */
+ hook_bootmagic();
+
/* debug enable */
debug_config.raw = eeconfig_read_debug();
if (bootmagic_scan_key(BOOTMAGIC_KEY_DEBUG_ENABLE)) {
diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c
index c8888f3c..8a533ab6 100644
--- a/tmk_core/common/chibios/bootloader.c
+++ b/tmk_core/common/chibios/bootloader.c
@@ -42,5 +42,6 @@ void bootloader_jump(void) {
#endif /* defined(KIIBOHD_BOOTLOADER) */
#else /* neither STM32 nor KINETIS */
+__attribute__((weak))
void bootloader_jump(void) {}
#endif
\ No newline at end of file
diff --git a/tmk_core/common/chibios/sleep_led.c b/tmk_core/common/chibios/sleep_led.c
index 50cf4eb7..4c35cfcb 100644
--- a/tmk_core/common/chibios/sleep_led.c
+++ b/tmk_core/common/chibios/sleep_led.c
@@ -4,11 +4,27 @@
#include "led.h"
#include "sleep_led.h"
-#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
-/* All right, we go the "software" way: LP timer, toggle LED in interrupt.
+/* All right, we go the "software" way: timer, toggle LED in interrupt.
* Based on hasu's code for AVRs.
+ * Use LP timer on Kinetises, TIM14 on STM32F0.
*/
+#if defined(KL2x) || defined(K20x)
+
+/* Use Low Power Timer (LPTMR) */
+#define TIMER_INTERRUPT_VECTOR KINETIS_LPTMR0_IRQ_VECTOR
+#define RESET_COUNTER LPTMR0->CSR |= LPTMRx_CSR_TCF
+
+#elif defined(STM32F0XX)
+
+/* Use TIM14 manually */
+#define TIMER_INTERRUPT_VECTOR STM32_TIM14_HANDLER
+#define RESET_COUNTER STM32_TIM14->SR &= ~STM32_TIM_SR_UIF
+
+#endif
+
+#if defined(KL2x) || defined(K20x) || defined(STM32F0XX) /* common parts for timers/interrupts */
+
/* Breathing Sleep LED brighness(PWM On period) table
* (64[steps] * 4[duration]) / 64[PWM periods/s] = 4 second breath cycle
*
@@ -22,8 +38,8 @@ static const uint8_t breathing_table[64] = {
15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
-/* Low Power Timer interrupt handler */
-OSAL_IRQ_HANDLER(KINETIS_LPTMR0_IRQ_VECTOR) {
+/* interrupt handler */
+OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) {
OSAL_IRQ_PROLOGUE();
/* Software PWM
@@ -55,11 +71,16 @@ OSAL_IRQ_HANDLER(KINETIS_LPTMR0_IRQ_VECTOR) {
}
/* Reset the counter */
- LPTMR0->CSR |= LPTMRx_CSR_TCF;
+ RESET_COUNTER;
OSAL_IRQ_EPILOGUE();
}
+#endif /* common parts for known platforms */
+
+
+#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
+
/* LPTMR clock options */
#define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
#define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
@@ -144,7 +165,48 @@ void sleep_led_toggle(void) {
LPTMR0->CSR ^= LPTMRx_CSR_TEN;
}
-#else /* platform selection: not on familiar Kinetis chips */
+#elif defined(STM32F0XX) /* platform selection: STM32F0XX */
+
+/* Initialise the timer */
+void sleep_led_init(void) {
+ /* enable clock */
+ rccEnableTIM14(FALSE); /* low power enable = FALSE */
+ rccResetTIM14();
+
+ /* prescale */
+ /* Assuming 48MHz internal clock */
+ /* getting cca 65484 irqs/sec */
+ STM32_TIM14->PSC = 733;
+
+ /* auto-reload */
+ /* 0 => interrupt every time */
+ STM32_TIM14->ARR = 3;
+
+ /* enable counter update event interrupt */
+ STM32_TIM14->DIER |= STM32_TIM_DIER_UIE;
+
+ /* register interrupt vector */
+ nvicEnableVector(STM32_TIM14_NUMBER, 2); /* vector, priority */
+}
+
+void sleep_led_enable(void) {
+ /* Enable the timer */
+ STM32_TIM14->CR1 = STM32_TIM_CR1_CEN | STM32_TIM_CR1_URS;
+ /* URS => update event only on overflow; setting UG bit disabled */
+}
+
+void sleep_led_disable(void) {
+ /* Disable the timer */
+ STM32_TIM14->CR1 = 0;
+}
+
+void sleep_led_toggle(void) {
+ /* Toggle the timer */
+ STM32_TIM14->CR1 ^= STM32_TIM_CR1_CEN;
+}
+
+
+#else /* platform selection: not on familiar chips */
void sleep_led_init(void) {
}
diff --git a/tmk_core/common/hook.c b/tmk_core/common/hook.c
new file mode 100644
index 00000000..204407b7
--- /dev/null
+++ b/tmk_core/common/hook.c
@@ -0,0 +1,61 @@
+/*
+Copyright 2016 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 .
+*/
+
+#include "keyboard.h"
+#include "hook.h"
+
+/* -------------------------------------------------
+ * Definitions of hardware-independent default hooks
+ * ------------------------------------------------- */
+
+/* Called on layer state change event. */
+/* Default behaviour: do nothing. */
+__attribute__((weak))
+void hook_layer_change(uint8_t layer_state) {
+ (void)layer_state;
+}
+
+/* Called periodically from the matrix scan loop (very often!) */
+/* Default behaviour: do nothing. */
+__attribute__((weak))
+void hook_keyboard_loop(void) {}
+
+/* Called on matrix state change event (every keypress => often!) */
+/* Default behaviour: do nothing. */
+__attribute__((weak))
+void hook_matrix_change(keyevent_t event) {
+ (void)event;
+}
+
+/* Called on indicator LED update event (when reported from host). */
+/* Default behaviour: calls led_set (for compatibility). */
+__attribute__((weak))
+void hook_keyboard_leds_change(uint8_t led_status) {
+ keyboard_set_leds(led_status);
+}
+
+/* Called once, on checking the bootmagic combos. */
+/* Default behaviour: do nothing. */
+__attribute__((weak))
+void hook_bootmagic(void) {
+ /* An example: */
+ // #include "bootmagic.h"
+ // #include "keymap.h"
+ // if(bootmagic_scan_keycode(KC_W)) {
+ // // do something
+ // }
+}
diff --git a/tmk_core/common/hook.h b/tmk_core/common/hook.h
new file mode 100644
index 00000000..ff569d49
--- /dev/null
+++ b/tmk_core/common/hook.h
@@ -0,0 +1,74 @@
+/*
+Copyright 2016 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 _HOOKS_H_
+#define _HOOKS_H_
+
+#include "keyboard.h"
+#include "led.h"
+
+/* -------------------------------------
+ * Hardware / one-off hooks
+ * ------------------------------------- */
+
+/* Called once, before initialising USB. */
+/* Default behaviour: do nothing. */
+void hook_early_init(void);
+
+/* Called once, after USB is connected and keyboard initialised. */
+/* Default behaviour: do nothing. */
+void hook_late_init(void);
+
+/* Called once, on getting SUSPEND event from USB. */
+/* Default behaviour: do nothing. */
+void hook_usb_suspend_entry(void);
+
+/* Called repeatedly during the SUSPENDed state. */
+/* Default behaviour: power down and periodically check
+ * the matrix, cause wakeup if needed. */
+void hook_usb_suspend_loop(void);
+
+/* Called once, on getting WAKE event from USB. */
+/* Default behaviour: disables sleep LED breathing and restores
+ * the "normal" indicator LED status by default. */
+void hook_usb_wakeup(void);
+
+/* Called once, on checking the bootmagic combos. */
+/* Default behaviour: do nothing. */
+void hook_bootmagic(void);
+
+/* -------------------------------------
+ * Keyboard / periodic hooks
+ * ------------------------------------- */
+
+/* Called periodically from the keyboard loop (very often!) */
+/* Default behaviour: do nothing. */
+void hook_keyboard_loop(void);
+
+/* Called on matrix state change event (every keypress => often!) */
+/* Default behaviour: do nothing. */
+void hook_matrix_change(keyevent_t event);
+
+/* Called on layer state change event. */
+/* Default behaviour: do nothing. */
+void hook_layer_change(uint8_t layer_state);
+
+/* Called on indicator LED update event (when reported from host). */
+/* Default behaviour: calls keyboard_set_leds (for compatibility). */
+void hook_keyboard_leds_change(uint8_t led_status);
+
+#endif /* _HOOKS_H_ */
diff --git a/tmk_core/common/keyboard.c b/tmk_core/common/keyboard.c
index eb7b096b..707351bc 100644
--- a/tmk_core/common/keyboard.c
+++ b/tmk_core/common/keyboard.c
@@ -30,6 +30,7 @@ along with this program. If not, see .
#include "bootmagic.h"
#include "eeconfig.h"
#include "backlight.h"
+#include "hook.h"
#ifdef MOUSEKEY_ENABLE
# include "mousekey.h"
#endif
@@ -128,11 +129,13 @@ void keyboard_task(void)
if (debug_matrix) matrix_print();
for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_change & ((matrix_row_t)1</bootloader_defs.h`. Also, a patch to upstream ChibiOS is needed (supplied), because it `ResetHandler` needs adjusting.
-- Sleep LED works, but at the moment only on/off, i.e. no breathing.
+- Jumping to (the built-in) bootloaders on STM32 works, but it is not entirely pleasant, since it is very much MCU dependent. So, one needs to dig out the right address to jump to, and either pass it to the compiler in the `Makefile`, or better, define it in `/bootloader_defs.h`. An additional startup code is also needed; the best way to deal with this is to define custom board files. (Example forthcoming.)
+
+### Experimental pre-ChibiOS 4 support
+- As an alternative to the mentioned flabbergast branch above, you can use the [master branch of ChibiOS](https://github.com/ChibiOS/ChibiOS).
+- Note that the Kinetis support has moved to the [ChibiOS-Contrib repository](https://github.com/ChibiOS/ChibiOS-Contrib), so you need to put that into your repository in the same way as you did for the main ChibiOS repository.
+- You also need to define CHIBIOS_CONTRIB in your makefile and point it to the right directory.
+- You need to add some new options to chconf.h, or you will get compiler errors. Just copy the new options from samples provided by the ChibiOS-Contrib repository.
### Immediate todo
-- host-wakeup packet sending during suspend
-- power saving for suspend?
-- PWM for sleep led
+- power saving for suspend
### Not tested, but possibly working
@@ -27,14 +36,14 @@ Also pay attention to `-O0` (enabled for debugging); for deployment use `-O2`.
### Tried with
-- ChibiOS 3.0.1, 3.0.2 and ST F072RB DISCOVERY board.
-- Need to test on other STM32 chips (F3, F4) to make it as much chip-independent as possible.
-- ChibiOS with Kinetis patches and Teensy LC and 3.0.
+- Infinity, WhiteFox keyboards
+- all ARM-based Teensies
+- some STM32-based boards (e.g. ST-F072RB-DISCOVERY board, STM32F042 breakout board, Maple Mini (STM32F103-based))
-## ChibiOS-supported MCUs (as of 3.0.2)
+## ChibiOS-supported MCUs
- Pretty much all STM32 chips.
-- There is some support for K20x and KL2x Freescale chips (i.e. Teensy 3.x/LC, mchck, FRDM-KL2{5,6}Z, FRDM-K20D50M), but again, no official USB stack yet. However the `kinetis` branch of [my ChibiOS fork](https://github.com/flabbergast/ChibiOS). With this fork, TMK work normally on all the ARM Teensies.
+- There is some support for K20x and KL2x Freescale chips (i.e. Teensy 3.x/LC, mchck, FRDM-KL2{5,6}Z, FRDM-K20D50M), but again, no official USB stack yet. However the `kinetis` branch of [flabbergast's ChibiOS fork](https://github.com/flabbergast/ChibiOS). With this fork, TMK work normally on all the ARM Teensies.
- There is also support for AVR8, but the USB stack is not implemented for them yet, and also the kernel itself takes about 1k of RAM. I think people managed to get ChibiOS running on atmega32[8p/u4] though.
- I've seen community support for Nordic NRF51822 (the chip in Adafruit's Bluefruit bluetooth-low-energy boards), but not sure about the extent.
@@ -43,7 +52,6 @@ Also pay attention to `-O0` (enabled for debugging); for deployment use `-O2`.
- STM32F0x2 chips can do crystal-less USB, but they still need a 3.3V voltage regulator.
- The BOOT0 pin should be tied to GND.
- For a hardware way of accessing the in-built DFU bootloader, in addition to the reset button, put another button between the BOOT0 pin and 3V3.
-- For breathing the caps lock LED during the suspended state ("sleep LED"), it is desirable to have that LED on a hardware PWM pin (there's usually plenty of those, look for TIMERs in the datasheet). However this is not strictly necessary, because instead of direct output of a timer to a pin (better of course), it is easy to define timer callbacks in ChibiOS that turn on/off an arbitrary pin.
diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c
index d588e4de..9c5254fa 100644
--- a/tmk_core/protocol/chibios/main.c
+++ b/tmk_core/protocol/chibios/main.c
@@ -35,6 +35,7 @@
#include "sleep_led.h"
#endif
#include "suspend.h"
+#include "hook.h"
/* -------------------------
@@ -58,6 +59,22 @@ host_driver_t chibios_driver = {
send_consumer
};
+/* Default hooks definitions. */
+__attribute__((weak))
+void hook_early_init(void) {}
+
+__attribute__((weak))
+void hook_late_init(void) {}
+
+__attribute__((weak))
+void hook_usb_suspend_loop(void) {
+ /* Do this in the suspended state */
+ suspend_power_down(); // on AVR this deep sleeps for 15ms
+ /* Remote wakeup */
+ if((USB_DRIVER.status & 2) && suspend_wakeup_condition()) {
+ send_remote_wakeup(&USB_DRIVER);
+ }
+}
/* TESTING
* Amber LED blinker thread, times are in milliseconds.
@@ -91,6 +108,8 @@ int main(void) {
// TESTING
// chThdCreateStatic(waBlinkerThread, sizeof(waBlinkerThread), NORMALPRIO, blinkerThread, NULL);
+ hook_early_init();
+
/* Init USB */
init_usb_driver(&USB_DRIVER);
@@ -120,21 +139,18 @@ int main(void) {
print("Keyboard start.\n");
+ hook_late_init();
+
/* Main loop */
while(true) {
if(USB_DRIVER.state == USB_SUSPENDED) {
print("[s]");
while(USB_DRIVER.state == USB_SUSPENDED) {
- /* Do this in the suspended state */
- suspend_power_down(); // on AVR this deep sleeps for 15ms
- /* Remote wakeup */
- if((USB_DRIVER.status & 2) && suspend_wakeup_condition()) {
- send_remote_wakeup(&USB_DRIVER);
- }
+ hook_usb_suspend_loop();
}
/* Woken up */
- // variables has been already cleared by the wakeup hook
+ // variables have been already cleared
send_keyboard_report();
#ifdef MOUSEKEY_ENABLE
mousekey_send();
diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c
index e2c9d9bf..106ce087 100644
--- a/tmk_core/protocol/chibios/usb_main.c
+++ b/tmk_core/protocol/chibios/usb_main.c
@@ -27,6 +27,25 @@
#include "sleep_led.h"
#include "led.h"
#endif
+#include "hook.h"
+
+/* TMK hooks */
+__attribute__((weak))
+void hook_usb_wakeup(void) {
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_disable();
+ // NOTE: converters may not accept this
+ led_set(host_keyboard_leds());
+#endif /* SLEEP_LED_ENABLE */
+}
+
+ __attribute__((weak))
+void hook_usb_suspend_entry(void) {
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_enable();
+#endif /* SLEEP_LED_ENABLE */
+}
+
/* ---------------------------------------------------------
* Global interface variables and declarations
@@ -795,19 +814,13 @@ static void usb_event_cb(USBDriver *usbp, usbevent_t event) {
case USB_EVENT_SUSPEND:
//TODO: from ISR! print("[S]");
-#ifdef SLEEP_LED_ENABLE
- sleep_led_enable();
-#endif /* SLEEP_LED_ENABLE */
+ hook_usb_suspend_entry();
return;
case USB_EVENT_WAKEUP:
//TODO: from ISR! print("[W]");
suspend_wakeup_init();
-#ifdef SLEEP_LED_ENABLE
- sleep_led_disable();
- // NOTE: converters may not accept this
- led_set(host_keyboard_leds());
-#endif /* SLEEP_LED_ENABLE */
+ hook_usb_wakeup();
return;
case USB_EVENT_STALLED:
diff --git a/tmk_core/protocol/lufa/lufa.c b/tmk_core/protocol/lufa/lufa.c
index 345630aa..beec6b2b 100644
--- a/tmk_core/protocol/lufa/lufa.c
+++ b/tmk_core/protocol/lufa/lufa.c
@@ -48,6 +48,7 @@
#include "sleep_led.h"
#endif
#include "suspend.h"
+#include "hook.h"
#include "descriptor.h"
#include "lufa.h"
@@ -180,21 +181,13 @@ void EVENT_USB_Device_Reset(void)
void EVENT_USB_Device_Suspend()
{
print("[S]");
-#ifdef SLEEP_LED_ENABLE
- sleep_led_enable();
-#endif
+ hook_usb_suspend_entry();
}
void EVENT_USB_Device_WakeUp()
{
print("[W]");
- suspend_wakeup_init();
-
-#ifdef SLEEP_LED_ENABLE
- sleep_led_disable();
- // NOTE: converters may not accept this
- led_set(host_keyboard_leds());
-#endif
+ hook_usb_wakeup();
}
#ifdef CONSOLE_ENABLE
@@ -592,6 +585,7 @@ int main(void) __attribute__ ((weak));
int main(void)
{
setup_mcu();
+ hook_early_init();
keyboard_setup();
setup_usb();
sei();
@@ -614,13 +608,11 @@ int main(void)
#endif
print("Keyboard start.\n");
+ hook_late_init();
while (1) {
while (USB_DeviceState == DEVICE_STATE_Suspended) {
print("[s]");
- suspend_power_down();
- if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
- USB_Device_SendRemoteWakeup();
- }
+ hook_usb_suspend_loop();
}
keyboard_task();
@@ -630,3 +622,39 @@ int main(void)
#endif
}
}
+
+
+/* hooks */
+__attribute__((weak))
+void hook_early_init(void) {}
+
+__attribute__((weak))
+void hook_late_init(void) {}
+
+ __attribute__((weak))
+void hook_usb_suspend_entry(void)
+{
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_enable();
+#endif
+}
+
+__attribute__((weak))
+void hook_usb_suspend_loop(void)
+{
+ suspend_power_down();
+ if (USB_Device_RemoteWakeupEnabled && suspend_wakeup_condition()) {
+ USB_Device_SendRemoteWakeup();
+ }
+}
+
+__attribute__((weak))
+void hook_usb_wakeup(void)
+{
+ suspend_wakeup_init();
+#ifdef SLEEP_LED_ENABLE
+ sleep_led_disable();
+ // NOTE: converters may not accept this
+ led_set(host_keyboard_leds());
+#endif
+}
diff --git a/tmk_core/tool/chibios/chibios.mk b/tmk_core/tool/chibios/chibios.mk
index 77689fc3..2dabd515 100644
--- a/tmk_core/tool/chibios/chibios.mk
+++ b/tmk_core/tool/chibios/chibios.mk
@@ -35,7 +35,7 @@ endif
# Enable this if you want link time optimizations (LTO)
ifeq ($(USE_LTO),)
- USE_LTO = yes
+ USE_LTO = no
endif
# If enabled, this option allows to compile the application in THUMB mode.
@@ -83,21 +83,44 @@ endif
#
# Imported source files and paths
-CHIBIOS = $(TMK_DIR)/tool/chibios/chibios
-# Startup files.
-include $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk
+CHIBIOS ?= $(TMK_DIR)/tool/chibios/chibios
+# Startup files. Try a few different locations, for compability with old versions and
+# for things hardware in the contrib repository
+STARTUP_MK = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk
+ifeq ("$(wildcard $(STARTUP_MK))","")
+ STARTUP_MK = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk
+ ifeq ("$(wildcard $(STARTUP_MK))","")
+ STARTUP_MK = $(CHIBIOS_CONTRIB)/os/common/startup/ARMCMx/compilers/GCC/mk/startup_$(MCU_STARTUP).mk
+ endif
+endif
+include $(STARTUP_MK)
# HAL-OSAL files (optional).
include $(CHIBIOS)/os/hal/hal.mk
-include $(CHIBIOS)/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)/platform.mk
-ifneq ("$(wildcard $(TARGET_DIR)/boards/$(BOARD))","")
- include $(TARGET_DIR)/boards/$(BOARD)/board.mk
-else
- include $(CHIBIOS)/os/hal/boards/$(BOARD)/board.mk
+
+PLATFORM_MK = $(CHIBIOS)/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)/platform.mk
+ifeq ("$(wildcard $(PLATFORM_MK))","")
+PLATFORM_MK = $(CHIBIOS_CONTRIB)/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)/platform.mk
endif
+include $(PLATFORM_MK)
+
+
+BOARD_MK = $(TARGET_DIR)/boards/$(BOARD)/board.mk
+ifeq ("$(wildcard $(BOARD_MK))","")
+ BOARD_MK = $(CHIBIOS)/os/hal/boards/$(BOARD)/board.mk
+ ifeq ("$(wildcard $(BOARD_MK))","")
+ BOARD_MK = $(CHIBIOS_CONTRIB)/os/hal/boards/$(BOARD)/board.mk
+ endif
+endif
+include $(BOARD_MK)
include $(CHIBIOS)/os/hal/osal/rt/osal.mk
# RTOS files (optional).
include $(CHIBIOS)/os/rt/rt.mk
-include $(CHIBIOS)/os/rt/ports/ARMCMx/compilers/GCC/mk/port_v$(ARMV)m.mk
+# Compability with old version
+PORT_V = $(CHIBIOS)/os/rt/ports/ARMCMx/compilers/GCC/mk/port_v$(ARMV)m.mk
+ifeq ("$(wildcard $(PORT_V))","")
+PORT_V = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC/mk/port_v$(ARMV)m.mk
+endif
+include $(PORT_V)
# Other files (optional).
# Define linker script file here
@@ -175,7 +198,7 @@ CP = $(TRGT)objcopy
AS = $(TRGT)gcc -x assembler-with-cpp
AR = $(TRGT)ar
OD = $(TRGT)objdump
-SZ = $(TRGT)size
+SZ = $(TRGT)size -A
HEX = $(CP) -O ihex
BIN = $(CP) -O binary
@@ -228,4 +251,7 @@ endif
##############################################################################
RULESPATH = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC
+ifeq ("$(wildcard $(RULESPATH)/rules.mk)","")
+RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC
+endif
include $(RULESPATH)/rules.mk
diff --git a/tmk_core/tool/chibios/common.mk b/tmk_core/tool/chibios/common.mk
index 7e3cccc9..1531c575 100644
--- a/tmk_core/tool/chibios/common.mk
+++ b/tmk_core/tool/chibios/common.mk
@@ -10,6 +10,7 @@ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/print.c \
$(COMMON_DIR)/debug.c \
$(COMMON_DIR)/util.c \
+ $(COMMON_DIR)/hook.c \
$(COMMON_DIR)/chibios/suspend.c \
$(COMMON_DIR)/chibios/printf.c \
$(COMMON_DIR)/chibios/timer.c \
@@ -80,6 +81,6 @@ endif
OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null)
# Bootloader address
-ifdef BOOTLOADER_ADDRESS
- OPT_DEFS += -DBOOTLOADER_ADDRESS=$(BOOTLOADER_ADDRESS)
+ifdef STM32_BOOTLOADER_ADDRESS
+ OPT_DEFS += -DSTM32_BOOTLOADER_ADDRESS=$(STM32_BOOTLOADER_ADDRESS)
endif
diff --git a/tmk_core/tool/mbed/common.mk b/tmk_core/tool/mbed/common.mk
index a0aa8717..2905d07d 100644
--- a/tmk_core/tool/mbed/common.mk
+++ b/tmk_core/tool/mbed/common.mk
@@ -10,6 +10,7 @@ OBJECTS += \
$(OBJDIR)/common/print.o \
$(OBJDIR)/common/debug.o \
$(OBJDIR)/common/util.o \
+ $(OBJDIR)/common/hook.o \
$(OBJDIR)/common/mbed/suspend.o \
$(OBJDIR)/common/mbed/timer.o \
$(OBJDIR)/common/mbed/xprintf.o \