From 77ddf078f56653047360f56cfc37ce53ac545576 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Sat, 26 Dec 2020 21:09:04 -0500 Subject: [PATCH 01/10] vial: add support for vibl bootloader and vfw package creation --- .gitignore | 1 + bootloader.mk | 6 +++++ tmk_core/rules.mk | 3 +++ util/vial_generate_vfw.py | 49 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 59 insertions(+) create mode 100644 util/vial_generate_vfw.py diff --git a/.gitignore b/.gitignore index 91d283e69b..2285d9ec20 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .dep *.o *.bin +*.vfw *.eep *.elf *.hex diff --git a/bootloader.mk b/bootloader.mk index ab1ced0ea4..0179863429 100644 --- a/bootloader.mk +++ b/bootloader.mk @@ -118,3 +118,9 @@ ifeq ($(strip $(BOOTLOADER)), stm32duino) DFU_ARGS = -d 1EAF:0003 -a2 -R DFU_SUFFIX_ARGS = -v 1EAF -p 0003 endif + +ifeq ($(strip $(BOOTLOADER)), vibl) + DFU_ARGS = + DFU_SUFFIX_ARGS = + VIBL = 1 +endif diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index a7053d185c..45b026e73b 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -293,6 +293,9 @@ gccversion : $(DFU_SUFFIX) $(DFU_SUFFIX_ARGS) -a $(BUILD_DIR)/$(TARGET).bin 1>/dev/null ;\ fi $(COPY) $(BUILD_DIR)/$(TARGET).bin $(TARGET).bin; + if [ ! -z "$(VIBL)" ]; then \ + python3 util/vial_generate_vfw.py $(TARGET).bin $(TARGET).vfw $(CONFIG_H) ;\ + fi BEGIN = gccversion sizebefore diff --git a/util/vial_generate_vfw.py b/util/vial_generate_vfw.py new file mode 100644 index 0000000000..d4a713116f --- /dev/null +++ b/util/vial_generate_vfw.py @@ -0,0 +1,49 @@ +import sys +import re +import struct +import hashlib +import time + + +def main(): + inp = sys.argv[1] + out = sys.argv[2] + configs = sys.argv[3:] + + # identify keyboard UID + uid = None + for config in configs: + with open(config, "r") as inf: + for line in inf: + uid = re.findall(r"#define.*VIAL_KEYBOARD_UID.*{(.*)}", line) + if uid: + break + if not uid: + print("Cannot identify keyboard UID from configuration files {}, ensure that you have VIAL_KEYBOARD_UID defined!".format(configs)) + return 1 + + uid = uid[0].split(",") + uid = [int(x, 16) for x in uid] + uid = struct.pack("BBBBBBBB", *uid) + + # read firmware binary + with open(sys.argv[1], "rb") as inf: + firmware = inf.read() + + with open(out, "wb") as outf: + outf.write(b"VIALFW00") + outf.write(uid) + outf.write(struct.pack(" Date: Sun, 27 Dec 2020 08:03:10 -0500 Subject: [PATCH 02/10] vial: add security-related features --- common_features.mk | 6 +++++- quantum/dynamic_keymap.c | 10 +++++++++ quantum/quantum.c | 10 +++++++++ quantum/via.c | 17 ++++++++++++++- quantum/vial.c | 46 ++++++++++++++++++++++++++++++++++++++++ quantum/vial.h | 3 +++ 6 files changed, 90 insertions(+), 2 deletions(-) diff --git a/common_features.mk b/common_features.mk index 97c16e7b66..2270571d7e 100644 --- a/common_features.mk +++ b/common_features.mk @@ -367,7 +367,7 @@ endif ifeq ($(strip $(VIAL_ENABLE)), yes) SRC += $(QUANTUM_DIR)/vial.c EXTRAINCDIRS += $(KEYMAP_OUTPUT) - OPT_DEFS += -DVIAL_ENABLE + OPT_DEFS += -DVIAL_ENABLE -DNO_DEBUG $(QUANTUM_DIR)/vial.c: $(KEYMAP_OUTPUT)/vial_generated_keyboard_definition.h @@ -375,6 +375,10 @@ $(KEYMAP_OUTPUT)/vial_generated_keyboard_definition.h: $(KEYMAP_PATH)/vial.json python3 util/vial_generate_definition.py $(KEYMAP_PATH)/vial.json $(KEYMAP_OUTPUT)/vial_generated_keyboard_definition.h endif +ifeq ($(strip $(VIAL_INSECURE)), yes) + OPT_DEFS += -DVIAL_INSECURE +endif + ifeq ($(strip $(VIAL_ENCODERS_ENABLE)), yes) OPT_DEFS += -DVIAL_ENCODERS_ENABLE endif diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c index 12fe7a26f6..77a382305b 100644 --- a/quantum/dynamic_keymap.c +++ b/quantum/dynamic_keymap.c @@ -22,6 +22,10 @@ #include "dynamic_keymap.h" #include "via.h" // for default VIA_EEPROM_ADDR_END +#ifdef VIAL_ENABLE +#include "vial.h" +#endif + #ifndef DYNAMIC_KEYMAP_MACRO_COUNT # define DYNAMIC_KEYMAP_MACRO_COUNT 16 #endif @@ -183,6 +187,12 @@ extern uint16_t g_vial_magic_keycode_override; // This overrides the one in quantum/keymap_common.c uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { +#ifdef VIAL_ENABLE + /* Disable any keycode processing while unlocking */ + if (vial_unlock_in_progress) + return KC_NO; +#endif + #ifdef VIAL_ENCODERS_ENABLE if (key.row == 254 && key.col == 254) return g_vial_magic_keycode_override; diff --git a/quantum/quantum.c b/quantum/quantum.c index dab6c9172f..dbe4822927 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -46,6 +46,10 @@ extern backlight_config_t backlight_config; # include "haptic.h" #endif +#ifdef VIAL_ENABLE +# include "vial.h" +#endif + #ifdef AUDIO_ENABLE # ifndef GOODBYE_SONG # define GOODBYE_SONG SONG(GOODBYE_SOUND) @@ -121,6 +125,12 @@ __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) { +#ifdef VIAL_ENABLE + /* Until keyboard is unlocked, disable processing of the RESET keycode */ + if (!vial_unlocked) + return; +#endif + clear_keyboard(); #if defined(MIDI_ENABLE) && defined(MIDI_BASIC) process_midi_all_notes_off(); diff --git a/quantum/via.c b/quantum/via.c index ee102d180c..1afac67264 100644 --- a/quantum/via.c +++ b/quantum/via.c @@ -243,6 +243,11 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { break; } case id_switch_matrix_state: { +#ifdef VIAL_ENABLE + /* We don't need this wannabe keylogger */ + goto skip; +#endif + #if ((MATRIX_COLS / 8 + 1) * MATRIX_ROWS <= 28) uint8_t i = 1; for (uint8_t row = 0; row < MATRIX_ROWS; row++) { @@ -362,6 +367,11 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { break; } case id_dynamic_keymap_macro_set_buffer: { +#ifdef VIAL_ENABLE + /* Until keyboard is unlocked, don't allow changing macros */ + if (!vial_unlocked) + goto skip; +#endif uint16_t offset = (command_data[0] << 8) | command_data[1]; uint16_t size = command_data[2]; // size <= 28 if (size <= 28) @@ -395,6 +405,11 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { break; } case id_bootloader_jump: { +#ifdef VIAL_ENABLE + /* Until keyboard is unlocked, don't allow jumping to bootloader */ + if (!vial_unlocked) + goto skip; +#endif // Need to send data back before the jump // Informs host that the command is handled raw_hid_send(data, length); @@ -416,7 +431,7 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { break; } } - +skip: // Return the same buffer, optionally with values changed // (i.e. returning state to the host, or the unhandled state). raw_hid_send(data, length); diff --git a/quantum/vial.c b/quantum/vial.c index 8fcad65c6d..6d6f2a8d74 100644 --- a/quantum/vial.c +++ b/quantum/vial.c @@ -23,14 +23,29 @@ #include "dynamic_keymap.h" #include "quantum.h" +#define VIAL_UNLOCK_COUNTER_MAX 50 + enum { vial_get_keyboard_id = 0x00, vial_get_size = 0x01, vial_get_def = 0x02, vial_get_encoder = 0x03, vial_set_encoder = 0x04, + vial_get_lock = 0x05, + vial_unlock_start = 0x06, + vial_unlock_poll = 0x07, }; +#ifdef VIAL_INSECURE +#pragma message "Building Vial-enabled firmware in insecure mode." +int vial_unlocked = 1; +#else +int vial_unlocked = 0; +#endif +int vial_unlock_in_progress = 0; +static int vial_unlock_counter = 0; +static uint16_t vial_unlock_timer; + void vial_handle_cmd(uint8_t *msg, uint8_t length) { /* All packets must be fixed 32 bytes */ if (length != RAW_EPSIZE) @@ -87,6 +102,37 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { break; } #endif + case vial_get_lock: { + msg[0] = !vial_unlocked; + break; + } + case vial_unlock_start: { + vial_unlock_in_progress = 1; + vial_unlock_counter = VIAL_UNLOCK_COUNTER_MAX; + vial_unlock_timer = timer_read(); + break; + } + case vial_unlock_poll: { + if (vial_unlock_in_progress) { + /* TODO: check specific keys instead of 0,0 */ + if (timer_elapsed(vial_unlock_timer) > 100 && MATRIX_IS_ON(0, 0)) { + vial_unlock_timer = timer_read(); + + vial_unlock_counter--; + if (vial_unlock_counter == 0) { + /* ok unlock succeeded */ + vial_unlock_in_progress = 0; + vial_unlocked = 1; + } + } else { + vial_unlock_counter = VIAL_UNLOCK_COUNTER_MAX; + } + } + msg[0] = vial_unlocked; + msg[1] = vial_unlock_in_progress; + msg[2] = vial_unlock_counter; + break; + } } } diff --git a/quantum/vial.h b/quantum/vial.h index e0d89817f9..875bcb6355 100644 --- a/quantum/vial.h +++ b/quantum/vial.h @@ -26,3 +26,6 @@ void vial_handle_cmd(uint8_t *data, uint8_t length); #ifdef VIAL_ENCODERS_ENABLE void vial_encoder_update(uint8_t index, bool clockwise); #endif + +extern int vial_unlocked; +extern int vial_unlock_in_progress; From 0fd15c51f3ee8a063c22c83e41dcc038745e8505 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Mon, 28 Dec 2020 16:28:26 -0500 Subject: [PATCH 03/10] vial/unlock: specify keys to hold --- quantum/vial.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/quantum/vial.c b/quantum/vial.c index 6d6f2a8d74..f900bdf0ab 100644 --- a/quantum/vial.c +++ b/quantum/vial.c @@ -46,6 +46,11 @@ int vial_unlock_in_progress = 0; static int vial_unlock_counter = 0; static uint16_t vial_unlock_timer; +static uint8_t vial_unlock_combo_rows[] = VIAL_UNLOCK_COMBO_ROWS; +static uint8_t vial_unlock_combo_cols[] = VIAL_UNLOCK_COMBO_COLS; +#define VIAL_UNLOCK_NUM_KEYS (sizeof(vial_unlock_combo_rows)/sizeof(vial_unlock_combo_rows[0])) +_Static_assert(VIAL_UNLOCK_NUM_KEYS < 15, "Max 15 unlock keys"); + void vial_handle_cmd(uint8_t *msg, uint8_t length) { /* All packets must be fixed 32 bytes */ if (length != RAW_EPSIZE) @@ -103,7 +108,16 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { } #endif case vial_get_lock: { + /* Reset message to all FF's */ + memset(msg, 0xFF, length); + /* First byte of message contains the status: whether board is unlocked */ msg[0] = !vial_unlocked; + msg[1] = 0; + /* Rest of the message are keys in the matrix that should be held to unlock the board */ + for (size_t i = 0; i < VIAL_UNLOCK_NUM_KEYS; ++i) { + msg[2 + i * 2] = vial_unlock_combo_rows[i]; + msg[2 + i * 2 + 1] = vial_unlock_combo_cols[i]; + } break; } case vial_unlock_start: { @@ -114,8 +128,11 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { } case vial_unlock_poll: { if (vial_unlock_in_progress) { - /* TODO: check specific keys instead of 0,0 */ - if (timer_elapsed(vial_unlock_timer) > 100 && MATRIX_IS_ON(0, 0)) { + int holding = 1; + for (size_t i = 0; i < VIAL_UNLOCK_NUM_KEYS; ++i) + holding &= matrix_is_on(vial_unlock_combo_rows[i], vial_unlock_combo_cols[i]); + + if (timer_elapsed(vial_unlock_timer) > 100 && holding) { vial_unlock_timer = timer_read(); vial_unlock_counter--; From 1b670b3feae36ddc5ade7efef4d8722c5868a954 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Tue, 29 Dec 2020 15:02:02 -0500 Subject: [PATCH 04/10] vial: allow re-locking keyboard --- quantum/vial.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/quantum/vial.c b/quantum/vial.c index f900bdf0ab..dccba4240b 100644 --- a/quantum/vial.c +++ b/quantum/vial.c @@ -34,6 +34,7 @@ enum { vial_get_lock = 0x05, vial_unlock_start = 0x06, vial_unlock_poll = 0x07, + vial_lock = 0x08, }; #ifdef VIAL_INSECURE @@ -150,6 +151,10 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { msg[2] = vial_unlock_counter; break; } + case vial_lock: { + vial_unlocked = 0; + break; + } } } From cc59ab21c5489484e0adc969b76e7b33267f85b0 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Tue, 29 Dec 2020 15:36:12 -0500 Subject: [PATCH 05/10] via/vial: kill all rawhid handling while unlocking --- quantum/via.c | 9 ++++++++- quantum/via.h | 1 + quantum/vial.c | 12 ------------ quantum/vial.h | 12 ++++++++++++ 4 files changed, 21 insertions(+), 13 deletions(-) diff --git a/quantum/via.c b/quantum/via.c index 1afac67264..3191e965d3 100644 --- a/quantum/via.c +++ b/quantum/via.c @@ -218,6 +218,13 @@ __attribute__((weak)) void raw_hid_receive_kb(uint8_t *data, uint8_t length) { void raw_hid_receive(uint8_t *data, uint8_t length) { uint8_t *command_id = &(data[0]); uint8_t *command_data = &(data[1]); + +#ifdef VIAL_ENABLE + /* When unlock is in progress, only command we react to is unlock_poll */ + if (vial_unlock_in_progress && (data[0] != id_vial_prefix || data[1] != vial_unlock_poll)) + goto skip; +#endif + switch (*command_id) { case id_get_protocol_version: { command_data[0] = VIA_PROTOCOL_VERSION >> 8; @@ -419,7 +426,7 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { break; } #ifdef VIAL_ENABLE - case 0xFE: { + case id_vial_prefix: { vial_handle_cmd(data, length); break; } diff --git a/quantum/via.h b/quantum/via.h index 373843f901..c17fcd515f 100644 --- a/quantum/via.h +++ b/quantum/via.h @@ -78,6 +78,7 @@ enum via_command_id { id_dynamic_keymap_get_layer_count = 0x11, id_dynamic_keymap_get_buffer = 0x12, id_dynamic_keymap_set_buffer = 0x13, + id_vial_prefix = 0xFE, id_unhandled = 0xFF, }; diff --git a/quantum/vial.c b/quantum/vial.c index dccba4240b..3512f1ecf1 100644 --- a/quantum/vial.c +++ b/quantum/vial.c @@ -25,18 +25,6 @@ #define VIAL_UNLOCK_COUNTER_MAX 50 -enum { - vial_get_keyboard_id = 0x00, - vial_get_size = 0x01, - vial_get_def = 0x02, - vial_get_encoder = 0x03, - vial_set_encoder = 0x04, - vial_get_lock = 0x05, - vial_unlock_start = 0x06, - vial_unlock_poll = 0x07, - vial_lock = 0x08, -}; - #ifdef VIAL_INSECURE #pragma message "Building Vial-enabled firmware in insecure mode." int vial_unlocked = 1; diff --git a/quantum/vial.h b/quantum/vial.h index 875bcb6355..514ac815d0 100644 --- a/quantum/vial.h +++ b/quantum/vial.h @@ -29,3 +29,15 @@ void vial_encoder_update(uint8_t index, bool clockwise); extern int vial_unlocked; extern int vial_unlock_in_progress; + +enum { + vial_get_keyboard_id = 0x00, + vial_get_size = 0x01, + vial_get_def = 0x02, + vial_get_encoder = 0x03, + vial_set_encoder = 0x04, + vial_get_lock = 0x05, + vial_unlock_start = 0x06, + vial_unlock_poll = 0x07, + vial_lock = 0x08, +}; From b0a3e0d0af30713b7effb489d10380e7232a2d12 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Tue, 29 Dec 2020 19:26:09 -0500 Subject: [PATCH 06/10] vial: support VIAL_INSECURE define --- quantum/vial.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/quantum/vial.c b/quantum/vial.c index 3512f1ecf1..33aa75b5bb 100644 --- a/quantum/vial.c +++ b/quantum/vial.c @@ -35,10 +35,12 @@ int vial_unlock_in_progress = 0; static int vial_unlock_counter = 0; static uint16_t vial_unlock_timer; +#ifndef VIAL_INSECURE static uint8_t vial_unlock_combo_rows[] = VIAL_UNLOCK_COMBO_ROWS; static uint8_t vial_unlock_combo_cols[] = VIAL_UNLOCK_COMBO_COLS; #define VIAL_UNLOCK_NUM_KEYS (sizeof(vial_unlock_combo_rows)/sizeof(vial_unlock_combo_rows[0])) _Static_assert(VIAL_UNLOCK_NUM_KEYS < 15, "Max 15 unlock keys"); +#endif void vial_handle_cmd(uint8_t *msg, uint8_t length) { /* All packets must be fixed 32 bytes */ @@ -102,11 +104,13 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { /* First byte of message contains the status: whether board is unlocked */ msg[0] = !vial_unlocked; msg[1] = 0; +#ifndef VIAL_INSECURE /* Rest of the message are keys in the matrix that should be held to unlock the board */ for (size_t i = 0; i < VIAL_UNLOCK_NUM_KEYS; ++i) { msg[2 + i * 2] = vial_unlock_combo_rows[i]; msg[2 + i * 2 + 1] = vial_unlock_combo_cols[i]; } +#endif break; } case vial_unlock_start: { @@ -116,6 +120,7 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { break; } case vial_unlock_poll: { +#ifndef VIAL_INSECURE if (vial_unlock_in_progress) { int holding = 1; for (size_t i = 0; i < VIAL_UNLOCK_NUM_KEYS; ++i) @@ -134,13 +139,16 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { vial_unlock_counter = VIAL_UNLOCK_COUNTER_MAX; } } +#endif msg[0] = vial_unlocked; msg[1] = vial_unlock_in_progress; msg[2] = vial_unlock_counter; break; } case vial_lock: { +#ifndef VIAL_INSECURE vial_unlocked = 0; +#endif break; } } From 377af7bcfc157c72d130adf220d5aedd6d1cba9a Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Tue, 29 Dec 2020 19:30:29 -0500 Subject: [PATCH 07/10] vial/lock: flip around the lock/unlock logic --- quantum/vial.c | 4 ++-- quantum/vial.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/quantum/vial.c b/quantum/vial.c index 33aa75b5bb..cb0296ffd5 100644 --- a/quantum/vial.c +++ b/quantum/vial.c @@ -98,11 +98,11 @@ void vial_handle_cmd(uint8_t *msg, uint8_t length) { break; } #endif - case vial_get_lock: { + case vial_get_unlock_status: { /* Reset message to all FF's */ memset(msg, 0xFF, length); /* First byte of message contains the status: whether board is unlocked */ - msg[0] = !vial_unlocked; + msg[0] = vial_unlocked; msg[1] = 0; #ifndef VIAL_INSECURE /* Rest of the message are keys in the matrix that should be held to unlock the board */ diff --git a/quantum/vial.h b/quantum/vial.h index 514ac815d0..74163a23cd 100644 --- a/quantum/vial.h +++ b/quantum/vial.h @@ -36,7 +36,7 @@ enum { vial_get_def = 0x02, vial_get_encoder = 0x03, vial_set_encoder = 0x04, - vial_get_lock = 0x05, + vial_get_unlock_status = 0x05, vial_unlock_start = 0x06, vial_unlock_poll = 0x07, vial_lock = 0x08, From 276d4be4954ed5f11a79d75b2e7e5a1a80f43b06 Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Tue, 29 Dec 2020 19:42:07 -0500 Subject: [PATCH 08/10] via: fix compile when vial is not enabled --- quantum/via.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quantum/via.c b/quantum/via.c index 3191e965d3..9772ea2b5e 100644 --- a/quantum/via.c +++ b/quantum/via.c @@ -438,7 +438,9 @@ void raw_hid_receive(uint8_t *data, uint8_t length) { break; } } +#ifdef VIAL_ENABLE skip: +#endif // Return the same buffer, optionally with values changed // (i.e. returning state to the host, or the unhandled state). raw_hid_send(data, length); From 52429b5d3d44c9c605e380af7814d8c27677396b Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Fri, 1 Jan 2021 04:47:28 -0500 Subject: [PATCH 09/10] add STM32_F103_vibl board and bootloader --- bootloader.mk | 4 + .../chibios/STM32_F103_vibl/board/board.c | 70 ++++++++ .../chibios/STM32_F103_vibl/board/board.h | 166 ++++++++++++++++++ .../chibios/STM32_F103_vibl/board/board.mk | 9 + platforms/chibios/ld/STM32_F103_vibl.ld | 86 +++++++++ 5 files changed, 335 insertions(+) create mode 100644 platforms/chibios/STM32_F103_vibl/board/board.c create mode 100644 platforms/chibios/STM32_F103_vibl/board/board.h create mode 100644 platforms/chibios/STM32_F103_vibl/board/board.mk create mode 100644 platforms/chibios/ld/STM32_F103_vibl.ld diff --git a/bootloader.mk b/bootloader.mk index 0179863429..1155d45594 100644 --- a/bootloader.mk +++ b/bootloader.mk @@ -120,6 +120,10 @@ ifeq ($(strip $(BOOTLOADER)), stm32duino) endif ifeq ($(strip $(BOOTLOADER)), vibl) + MCU_LDSCRIPT = STM32_F103_vibl + BOARD = STM32_F103_vibl + PROGRAM_CMD = echo 'CLI flashing not supported' >&2 + DFU_ARGS = DFU_SUFFIX_ARGS = VIBL = 1 diff --git a/platforms/chibios/STM32_F103_vibl/board/board.c b/platforms/chibios/STM32_F103_vibl/board/board.c new file mode 100644 index 0000000000..be4108c586 --- /dev/null +++ b/platforms/chibios/STM32_F103_vibl/board/board.c @@ -0,0 +1,70 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#include "hal.h" + +#ifdef VIAL_ENABLE +#include "vial.h" +#endif + +#define RTC_BOOTLOADER_FLAG 0x7662 /* Flag whether to jump into bootloader, "vb" */ +#define RTC_INSECURE_FLAG 0x4953 /* Flag to indicate qmk that we want to boot into insecure mode, "IS" */ + +/** + * @brief PAL setup. + * @details Digital I/O ports static configuration as defined in @p board.h. + * This variable is used by the HAL when initializing the PAL driver. + */ +#if HAL_USE_PAL || defined(__DOXYGEN__) +const PALConfig pal_default_config = +{ + {VAL_GPIOAODR, VAL_GPIOACRL, VAL_GPIOACRH}, + {VAL_GPIOBODR, VAL_GPIOBCRL, VAL_GPIOBCRH}, + {VAL_GPIOCODR, VAL_GPIOCCRL, VAL_GPIOCCRH}, + {VAL_GPIODODR, VAL_GPIODCRL, VAL_GPIODCRH}, + {VAL_GPIOEODR, VAL_GPIOECRL, VAL_GPIOECRH}, +}; +#endif + +/* + * Early initialization code. + * This initialization must be performed just after stack setup and before + * any other initialization. + */ +void __early_init(void) { + stm32_clock_init(); +} + +/* + * Board-specific initialization code. + */ +void boardInit(void) { + //JTAG-DP Disabled and SW-DP Enabled + AFIO->MAPR |= AFIO_MAPR_SWJ_CFG_JTAGDISABLE; + +#ifdef VIAL_ENABLE + if (BKP->DR10 == RTC_INSECURE_FLAG) { + vial_unlocked = 1; + } +#endif + BKP->DR10 = 0; +} + +void bootloader_jump(void) { + //Set backup register DR10 to enter bootloader on reset + BKP->DR10 = RTC_BOOTLOADER_FLAG; + NVIC_SystemReset(); +} diff --git a/platforms/chibios/STM32_F103_vibl/board/board.h b/platforms/chibios/STM32_F103_vibl/board/board.h new file mode 100644 index 0000000000..4d120b6d90 --- /dev/null +++ b/platforms/chibios/STM32_F103_vibl/board/board.h @@ -0,0 +1,166 @@ +/* + ChibiOS - Copyright (C) 2006..2015 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/* + * Setup for a Generic STM32F103 board. + */ + +/* + * Board identifier. + */ +#define BOARD_STM32_F103_STM32DUINO +#define BOARD_NAME "STM32F103CBT6 board - vibl bootloader" + +/* + * Board frequencies. + */ +#define STM32_LSECLK 32768 +#define STM32_HSECLK 8000000 + +/* + * MCU type, supported types are defined in ./os/hal/platforms/hal_lld.h. + */ +#define STM32F103xB + +/* + * IO pins assignments + */ + +/* on-board */ + +#define GPIOA_LED 8 +#define GPIOD_OSC_IN 0 +#define GPIOD_OSC_OUT 1 + +/* In case your board has a "USB enable" hardware + controlled by a pin, define it here. (It could be just + a 1.5k resistor connected to D+ line.) +*/ +/* +#define GPIOB_USB_DISC 10 +*/ + +/* + * I/O ports initial setup, this configuration is established soon after reset + * in the initialization code. + * + * The digits have the following meaning: + * 0 - Analog input. + * 1 - Push Pull output 10MHz. + * 2 - Push Pull output 2MHz. + * 3 - Push Pull output 50MHz. + * 4 - Digital input. + * 5 - Open Drain output 10MHz. + * 6 - Open Drain output 2MHz. + * 7 - Open Drain output 50MHz. + * 8 - Digital input with PullUp or PullDown resistor depending on ODR. + * 9 - Alternate Push Pull output 10MHz. + * A - Alternate Push Pull output 2MHz. + * B - Alternate Push Pull output 50MHz. + * C - Reserved. + * D - Alternate Open Drain output 10MHz. + * E - Alternate Open Drain output 2MHz. + * F - Alternate Open Drain output 50MHz. + * Please refer to the STM32 Reference Manual for details. + */ + +/* + * Port A setup. + * Everything input with pull-up except: + * PA2 - Alternate output (USART2 TX). + * PA3 - Normal input (USART2 RX). + * PA9 - Alternate output (USART1 TX). + * PA10 - Normal input (USART1 RX). + */ +#define VAL_GPIOACRL 0x88884B88 /* PA7...PA0 */ +#define VAL_GPIOACRH 0x888884B8 /* PA15...PA8 */ +#define VAL_GPIOAODR 0xFFFFFFFF + +/* + * Port B setup. + * Everything input with pull-up except: + * PB10 - Push Pull output (USB switch). + */ +#define VAL_GPIOBCRL 0x88888888 /* PB7...PB0 */ +#define VAL_GPIOBCRH 0x88888388 /* PB15...PB8 */ +#define VAL_GPIOBODR 0xFFFFFFFF + +/* + * Port C setup. + * Everything input with pull-up except: + * PC13 - Push Pull output (LED). + */ +#define VAL_GPIOCCRL 0x88888888 /* PC7...PC0 */ +#define VAL_GPIOCCRH 0x88388888 /* PC15...PC8 */ +#define VAL_GPIOCODR 0xFFFFFFFF + +/* + * Port D setup. + * Everything input with pull-up except: + * PD0 - Normal input (XTAL). + * PD1 - Normal input (XTAL). + */ +#define VAL_GPIODCRL 0x88888844 /* PD7...PD0 */ +#define VAL_GPIODCRH 0x88888888 /* PD15...PD8 */ +#define VAL_GPIODODR 0xFFFFFFFF + +/* + * Port E setup. + * Everything input with pull-up except: + */ +#define VAL_GPIOECRL 0x88888888 /* PE7...PE0 */ +#define VAL_GPIOECRH 0x88888888 /* PE15...PE8 */ +#define VAL_GPIOEODR 0xFFFFFFFF + +/* + * USB bus activation macro, required by the USB driver. + */ +/* The point is that most of the generic STM32F103* boards + have a 1.5k resistor connected on one end to the D+ line + and on the other end to some pin. Or even a slightly more + complicated "USB enable" circuit, controlled by a pin. + That should go here. + + However on some boards (e.g. one that I have), there's no + such hardware. In which case it's better to not do anything. +*/ +/* +#define usb_lld_connect_bus(usbp) palClearPad(GPIOB, GPIOB_USB_DISC) +*/ +#define usb_lld_connect_bus(usbp) palSetPadMode(GPIOA, 12, PAL_MODE_INPUT); + +/* + * USB bus de-activation macro, required by the USB driver. + */ +/* +#define usb_lld_disconnect_bus(usbp) palSetPad(GPIOB, GPIOB_USB_DISC) +*/ +#define usb_lld_disconnect_bus(usbp) palSetPadMode(GPIOA, 12, PAL_MODE_OUTPUT_PUSHPULL); palClearPad(GPIOA, 12); + +#if !defined(_FROM_ASM_) +#ifdef __cplusplus +extern "C" { +#endif + void boardInit(void); +#ifdef __cplusplus +} +#endif +#endif /* _FROM_ASM_ */ + +#endif /* _BOARD_H_ */ diff --git a/platforms/chibios/STM32_F103_vibl/board/board.mk b/platforms/chibios/STM32_F103_vibl/board/board.mk new file mode 100644 index 0000000000..842e335905 --- /dev/null +++ b/platforms/chibios/STM32_F103_vibl/board/board.mk @@ -0,0 +1,9 @@ +# List of all the board related files. +BOARDSRC = $(BOARD_PATH)/board/board.c + +# Required include directories +BOARDINC = $(BOARD_PATH)/board + +# Shared variables +ALLCSRC += $(BOARDSRC) +ALLINC += $(BOARDINC) diff --git a/platforms/chibios/ld/STM32_F103_vibl.ld b/platforms/chibios/ld/STM32_F103_vibl.ld new file mode 100644 index 0000000000..149302f686 --- /dev/null +++ b/platforms/chibios/ld/STM32_F103_vibl.ld @@ -0,0 +1,86 @@ +/* + ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* + * STM32F103xC memory setup for use with the WM1 mass-storage device bootloader. + */ +MEMORY +{ + /* 128k total flash, -4k for bootloader, -8k for eeprom emulation */ + flash0 : org = 0x08001000, len = 128k - 4k - 8k + flash1 : org = 0x00000000, len = 0 + flash2 : org = 0x00000000, len = 0 + flash3 : org = 0x00000000, len = 0 + flash4 : org = 0x00000000, len = 0 + flash5 : org = 0x00000000, len = 0 + flash6 : org = 0x00000000, len = 0 + flash7 : org = 0x00000000, len = 0 + ram0 : org = 0x20000000, len = 20k + ram1 : org = 0x00000000, len = 0 + ram2 : org = 0x00000000, len = 0 + ram3 : org = 0x00000000, len = 0 + ram4 : org = 0x00000000, len = 0 + ram5 : org = 0x00000000, len = 0 + ram6 : org = 0x00000000, len = 0 + ram7 : org = 0x00000000, len = 0 +} + +/* For each data/text section two region are defined, a virtual region + and a load region (_LMA suffix).*/ + +/* Flash region to be used for exception vectors.*/ +REGION_ALIAS("VECTORS_FLASH", flash0); +REGION_ALIAS("VECTORS_FLASH_LMA", flash0); + +/* Flash region to be used for constructors and destructors.*/ +REGION_ALIAS("XTORS_FLASH", flash0); +REGION_ALIAS("XTORS_FLASH_LMA", flash0); + +/* Flash region to be used for code text.*/ +REGION_ALIAS("TEXT_FLASH", flash0); +REGION_ALIAS("TEXT_FLASH_LMA", flash0); + +/* Flash region to be used for read only data.*/ +REGION_ALIAS("RODATA_FLASH", flash0); +REGION_ALIAS("RODATA_FLASH_LMA", flash0); + +/* Flash region to be used for various.*/ +REGION_ALIAS("VARIOUS_FLASH", flash0); +REGION_ALIAS("VARIOUS_FLASH_LMA", flash0); + +/* Flash region to be used for RAM(n) initialization data.*/ +REGION_ALIAS("RAM_INIT_FLASH_LMA", flash0); + +/* RAM region to be used for Main stack. This stack accommodates the processing + of all exceptions and interrupts.*/ +REGION_ALIAS("MAIN_STACK_RAM", ram0); + +/* RAM region to be used for the process stack. This is the stack used by + the main() function.*/ +REGION_ALIAS("PROCESS_STACK_RAM", ram0); + +/* RAM region to be used for data segment.*/ +REGION_ALIAS("DATA_RAM", ram0); +REGION_ALIAS("DATA_RAM_LMA", flash0); + +/* RAM region to be used for BSS segment.*/ +REGION_ALIAS("BSS_RAM", ram0); + +/* RAM region to be used for the default heap.*/ +REGION_ALIAS("HEAP_RAM", ram0); + +/* Generic rules inclusion.*/ +INCLUDE rules.ld From edb24a5bd407dce839d332e3de87837178cc9a5e Mon Sep 17 00:00:00 2001 From: Ilya Zhuravlev Date: Fri, 1 Jan 2021 04:58:02 -0500 Subject: [PATCH 10/10] dynamic_keymap: add bounds check to dynamic_keymap_get/set_keycode --- quantum/dynamic_keymap.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c index 77a382305b..69693ad7a5 100644 --- a/quantum/dynamic_keymap.c +++ b/quantum/dynamic_keymap.c @@ -94,6 +94,9 @@ void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t c } uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) { + if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) + return KC_NO; + void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); // Big endian, so we can read/write EEPROM directly from host if we want uint16_t keycode = eeprom_read_byte(address) << 8; @@ -102,6 +105,9 @@ uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) } void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) { + if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) + return; + void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); // Big endian, so we can read/write EEPROM directly from host if we want eeprom_update_byte(address, (uint8_t)(keycode >> 8));