diff --git a/docs/keycodes.md b/docs/keycodes.md index 942e0a66160..10652bdb2f4 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -225,6 +225,7 @@ See also: [Quantum Keycodes](quantum_keycodes.md#qmk-keycodes) |`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode | |`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory) | |`QK_MAKE` | |Sends `qmk compile -kb (keyboard) -km (keymap)`, or `qmk flash` if shift is held | +|`QK_REBOOT` |`QK_RBT` |Resets the keyboard. Does not load the bootloader | ## Audio Keys :id=audio-keys diff --git a/docs/quantum_keycodes.md b/docs/quantum_keycodes.md index 46a8b7de194..a1923777efe 100644 --- a/docs/quantum_keycodes.md +++ b/docs/quantum_keycodes.md @@ -14,3 +14,4 @@ On this page we have documented keycodes between `0x00FF` and `0xFFFF` which are |`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode | |`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory) | |`QK_MAKE` | |Sends `qmk compile -kb (keyboard) -km (keymap)`, or `qmk flash` if shift is held | +|`QK_REBOOT` |`QK_RBT` |Resets the keyboard. Does not load the bootloader | diff --git a/keyboards/handwired/onekey/keymaps/reboot/keymap.c b/keyboards/handwired/onekey/keymaps/reboot/keymap.c new file mode 100644 index 00000000000..c3d147a76c1 --- /dev/null +++ b/keyboards/handwired/onekey/keymaps/reboot/keymap.c @@ -0,0 +1,5 @@ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + LAYOUT_ortho_1x1(QK_REBOOT) +}; diff --git a/platforms/arm_atsam/bootloaders/md_boot.c b/platforms/arm_atsam/bootloaders/md_boot.c index 32cf850448e..1cf7aec62cc 100644 --- a/platforms/arm_atsam/bootloaders/md_boot.c +++ b/platforms/arm_atsam/bootloaders/md_boot.c @@ -63,3 +63,7 @@ void bootloader_jump(void) { while (1) ; // Wait on timeout } + +__attribute__((weak)) void mcu_reset(void) { + NVIC_SystemReset(); +} diff --git a/platforms/avr/bootloaders/bootloadhid.c b/platforms/avr/bootloaders/bootloadhid.c index ae58760d7da..b91dca6d278 100644 --- a/platforms/avr/bootloaders/bootloadhid.c +++ b/platforms/avr/bootloaders/bootloadhid.c @@ -31,3 +31,10 @@ __attribute__((weak)) void bootloader_jump(void) { for (;;) ; } + +__attribute__((weak)) void mcu_reset(void) { + // watchdog reset + wdt_enable(WDTO_250MS); + for (;;) + ; +} diff --git a/platforms/avr/bootloaders/caterina.c b/platforms/avr/bootloaders/caterina.c index 82a16a3765f..2b5f613d6d5 100644 --- a/platforms/avr/bootloaders/caterina.c +++ b/platforms/avr/bootloaders/caterina.c @@ -37,3 +37,12 @@ __attribute__((weak)) void bootloader_jump(void) { while (1) { } } + +__attribute__((weak)) void mcu_reset(void) { + // setup watchdog timeout + wdt_enable(WDTO_60MS); + + // wait for watchdog timer to trigger + while (1) { + } +} diff --git a/platforms/avr/bootloaders/custom.c b/platforms/avr/bootloaders/custom.c index 624fbe242a3..72b19f66719 100644 --- a/platforms/avr/bootloaders/custom.c +++ b/platforms/avr/bootloaders/custom.c @@ -15,5 +15,14 @@ */ #include "bootloader.h" +#include __attribute__((weak)) void bootloader_jump(void) {} +__attribute__((weak)) void mcu_reset(void) { + // setup watchdog timeout + wdt_enable(WDTO_60MS); + + // wait for watchdog timer to trigger + while (1) { + } +} diff --git a/platforms/avr/bootloaders/dfu.c b/platforms/avr/bootloaders/dfu.c index 06b2c8963ac..dbbb5f4ab64 100644 --- a/platforms/avr/bootloaders/dfu.c +++ b/platforms/avr/bootloaders/dfu.c @@ -34,8 +34,15 @@ __attribute__((weak)) void bootloader_jump(void) { UCSR1B = 0; _delay_ms(5); // 5 seems to work fine - // watchdog reset reset_key = BOOTLOADER_RESET_KEY; + // watchdog reset + wdt_enable(WDTO_250MS); + for (;;) + ; +} + +__attribute__((weak)) void mcu_reset(void) { + // watchdog reset wdt_enable(WDTO_250MS); for (;;) ; diff --git a/platforms/avr/bootloaders/halfkay.c b/platforms/avr/bootloaders/halfkay.c index 651696f9881..402f5f27786 100644 --- a/platforms/avr/bootloaders/halfkay.c +++ b/platforms/avr/bootloaders/halfkay.c @@ -17,6 +17,7 @@ #include "bootloader.h" #include +#include #include __attribute__((weak)) void bootloader_jump(void) { @@ -126,3 +127,12 @@ __attribute__((weak)) void bootloader_jump(void) { asm volatile("jmp 0x1FC00"); #endif } + +__attribute__((weak)) void mcu_reset(void) { + // setup watchdog timeout + wdt_enable(WDTO_60MS); + + // wait for watchdog timer to trigger + while (1) { + } +} diff --git a/platforms/avr/bootloaders/usbasploader.c b/platforms/avr/bootloaders/usbasploader.c index 008bd16069f..333010eefa3 100644 --- a/platforms/avr/bootloaders/usbasploader.c +++ b/platforms/avr/bootloaders/usbasploader.c @@ -54,3 +54,12 @@ __attribute__((weak)) void bootloader_jump(void) { #endif [bootaddrme] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 8) & 0xff), [bootaddrlo] "M"((((FLASH_SIZE - BOOTLOADER_SIZE) >> 1) >> 0) & 0xff)); } + +__attribute__((weak)) void mcu_reset(void) { + // setup watchdog timeout + wdt_enable(WDTO_15MS); + + // wait for watchdog timer to trigger + while (1) { + } +} diff --git a/platforms/bootloader.h b/platforms/bootloader.h index 25ebd952888..77c6c80287c 100644 --- a/platforms/bootloader.h +++ b/platforms/bootloader.h @@ -19,3 +19,4 @@ along with this program. If not, see . /* give code for your bootloader to come up if needed */ void bootloader_jump(void); +void mcu_reset(void); diff --git a/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.c b/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.c index 8a34e81f257..cba977da776 100644 --- a/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.c +++ b/platforms/chibios/boards/STM32_F103_STM32DUINO/board/board.c @@ -16,9 +16,6 @@ #include -// Value to place in RTC backup register 10 for persistent bootloader mode -#define RTC_BOOTLOADER_FLAG 0x424C - /** * @brief PAL setup. * @details Digital I/O ports static configuration as defined in @p board.h. diff --git a/platforms/chibios/boards/STM32_F103_STM32DUINO/configs/config.h b/platforms/chibios/boards/STM32_F103_STM32DUINO/configs/config.h new file mode 100644 index 00000000000..d8b852cab7e --- /dev/null +++ b/platforms/chibios/boards/STM32_F103_STM32DUINO/configs/config.h @@ -0,0 +1,9 @@ +// Copyright 2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later +#pragma once + +// Value to place in RTC backup register 10 for persistent bootloader mode +#define RTC_BOOTLOADER_FLAG 0x424C + +// Value to place in RTC backup register 10 for instant reboot mode +#define RTC_BOOTLOADER_JUST_UPLOADED 0x424D diff --git a/platforms/chibios/bootloaders/custom.c b/platforms/chibios/bootloaders/custom.c index bba9fc4637d..6c5a433953e 100644 --- a/platforms/chibios/bootloaders/custom.c +++ b/platforms/chibios/bootloaders/custom.c @@ -17,5 +17,6 @@ #include "bootloader.h" __attribute__((weak)) void bootloader_jump(void) {} +__attribute__((weak)) void mcu_reset(void) {} __attribute__((weak)) void enter_bootloader_mode_if_requested(void) {} diff --git a/platforms/chibios/bootloaders/gd32v_dfu.c b/platforms/chibios/bootloaders/gd32v_dfu.c index baa7d1f8823..100fc472f8f 100644 --- a/platforms/chibios/bootloaders/gd32v_dfu.c +++ b/platforms/chibios/bootloaders/gd32v_dfu.c @@ -36,5 +36,12 @@ __attribute__((weak)) void bootloader_jump(void) { *DBGMCU_CMD = DBGMCU_CMD_RESET; } +__attribute__((weak)) void mcu_reset(void) { + // Confirmed by karlk90, there is no actual reset to bootloader. + // This just resets the controller. + *DBGMCU_KEY = DBGMCU_KEY_UNLOCK; + *DBGMCU_CMD = DBGMCU_CMD_RESET; +} + /* Jumping to bootloader is not possible from user code. */ void enter_bootloader_mode_if_requested(void) {} diff --git a/platforms/chibios/bootloaders/halfkay.c b/platforms/chibios/bootloaders/halfkay.c index 168c2abc230..aa11e6c5f43 100644 --- a/platforms/chibios/bootloaders/halfkay.c +++ b/platforms/chibios/bootloaders/halfkay.c @@ -23,3 +23,5 @@ __attribute__((weak)) void bootloader_jump(void) { wait_ms(100); __BKPT(0); } + +__attribute__((weak)) void mcu_reset(void) {} diff --git a/platforms/chibios/bootloaders/kiibohd.c b/platforms/chibios/bootloaders/kiibohd.c index 911e8070927..09a4d49b787 100644 --- a/platforms/chibios/bootloaders/kiibohd.c +++ b/platforms/chibios/bootloaders/kiibohd.c @@ -30,3 +30,4 @@ __attribute__((weak)) void bootloader_jump(void) { // request reset SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; } +__attribute__((weak)) void mcu_reset(void) {} diff --git a/platforms/chibios/bootloaders/stm32_dfu.c b/platforms/chibios/bootloaders/stm32_dfu.c index 0e741113670..ff866bd2bc0 100644 --- a/platforms/chibios/bootloaders/stm32_dfu.c +++ b/platforms/chibios/bootloaders/stm32_dfu.c @@ -61,6 +61,9 @@ __attribute__((weak)) void bootloader_jump(void) { NVIC_SystemReset(); } +__attribute__((weak)) void mcu_reset(void) { + NVIC_SystemReset(); +} // not needed at all, but if anybody attempts to invoke it.... void enter_bootloader_mode_if_requested(void) {} @@ -76,6 +79,10 @@ __attribute__((weak)) void bootloader_jump(void) { NVIC_SystemReset(); } +__attribute__((weak)) void mcu_reset(void) { + NVIC_SystemReset(); +} + void enter_bootloader_mode_if_requested(void) { unsigned long *check = MAGIC_ADDR; if (*check == BOOTLOADER_MAGIC) { diff --git a/platforms/chibios/bootloaders/stm32duino.c b/platforms/chibios/bootloaders/stm32duino.c index 53d3ba0adb1..e2db7fa16ca 100644 --- a/platforms/chibios/bootloaders/stm32duino.c +++ b/platforms/chibios/bootloaders/stm32duino.c @@ -21,3 +21,8 @@ __attribute__((weak)) void bootloader_jump(void) { NVIC_SystemReset(); } + +__attribute__((weak)) void mcu_reset(void) { + BKP->DR10 = RTC_BOOTLOADER_JUST_UPLOADED; + NVIC_SystemReset(); +} \ No newline at end of file diff --git a/platforms/chibios/bootloaders/tinyuf2.c b/platforms/chibios/bootloaders/tinyuf2.c index 9ffca5dec82..e08855b6c46 100644 --- a/platforms/chibios/bootloaders/tinyuf2.c +++ b/platforms/chibios/bootloaders/tinyuf2.c @@ -25,6 +25,10 @@ extern uint32_t _board_dfu_dbl_tap[]; #define DBL_TAP_REG _board_dfu_dbl_tap[0] +__attribute__((weak)) void mcu_reset(void) { + NVIC_SystemReset(); +} + __attribute__((weak)) void bootloader_jump(void) { DBL_TAP_REG = DBL_TAP_MAGIC; NVIC_SystemReset(); diff --git a/platforms/chibios/bootloaders/wb32_dfu.c b/platforms/chibios/bootloaders/wb32_dfu.c index bbc382a2d04..d021b0863b8 100644 --- a/platforms/chibios/bootloaders/wb32_dfu.c +++ b/platforms/chibios/bootloaders/wb32_dfu.c @@ -47,3 +47,7 @@ void enter_bootloader_mode_if_requested(void) { ; } } + +__attribute__((weak)) void mcu_reset(void) { + NVIC_SystemReset(); +} diff --git a/platforms/test/bootloaders/none.c b/platforms/test/bootloaders/none.c index 5155d9ff04f..e88a79ae056 100644 --- a/platforms/test/bootloaders/none.c +++ b/platforms/test/bootloaders/none.c @@ -17,3 +17,4 @@ #include "bootloader.h" void bootloader_jump(void) {} +void mcu_reset(void) {} diff --git a/quantum/quantum.c b/quantum/quantum.c index 673ea91b11f..c0e801a4bb9 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -121,7 +121,7 @@ __attribute__((weak)) void post_process_record_kb(uint16_t keycode, keyrecord_t __attribute__((weak)) void post_process_record_user(uint16_t keycode, keyrecord_t *record) {} -void reset_keyboard(void) { +void shutdown_quantum(void) { clear_keyboard(); #if defined(MIDI_ENABLE) && defined(MIDI_BASIC) process_midi_all_notes_off(); @@ -143,9 +143,18 @@ void reset_keyboard(void) { #ifdef HAPTIC_ENABLE haptic_shutdown(); #endif +} + +void reset_keyboard(void) { + shutdown_quantum(); bootloader_jump(); } +void soft_reset_keyboard(void) { + shutdown_quantum(); + mcu_reset(); +} + /* Convert record into usable keycode via the contained event. */ uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) { #ifdef COMBO_ENABLE @@ -326,6 +335,9 @@ bool process_record_quantum(keyrecord_t *record) { case QK_BOOTLOADER: reset_keyboard(); return false; + case QK_REBOOT: + soft_reset_keyboard(); + return false; #endif #ifndef NO_DEBUG case QK_DEBUG_TOGGLE: @@ -339,6 +351,9 @@ bool process_record_quantum(keyrecord_t *record) { return false; case QK_CLEAR_EEPROM: eeconfig_init(); +#ifndef NO_RESET + soft_reset_keyboard(); +#endif return false; #ifdef VELOCIKEY_ENABLE case VLK_TOG: diff --git a/quantum/quantum.h b/quantum/quantum.h index d021e7c05c1..7829ec7e0cb 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -254,6 +254,7 @@ void post_process_record_kb(uint16_t keycode, keyrecord_t *record); void post_process_record_user(uint16_t keycode, keyrecord_t *record); void reset_keyboard(void); +void soft_reset_keyboard(void); void startup_user(void); void shutdown_user(void); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index c7b4ea593fe..5d5c4ed8c49 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -596,6 +596,7 @@ enum quantum_keycodes { MAGIC_TOGGLE_CONTROL_CAPSLOCK, QK_MAKE, + QK_REBOOT, SECURE_LOCK, SECURE_UNLOCK, @@ -717,6 +718,7 @@ enum quantum_keycodes { #define QK_BOOT QK_BOOTLOADER #define DB_TOGG QK_DEBUG_TOGGLE #define EE_CLR QK_CLEAR_EEPROM +#define QK_RBT QK_REBOOT // Audio Clicky aliases #define CK_TOGG CLICKY_TOGGLE