From 4d4f7684e684bec319f166121463a88cd4a62703 Mon Sep 17 00:00:00 2001 From: fredizzimo Date: Fri, 1 Jul 2016 17:04:53 +0300 Subject: [PATCH] Add ChibiOS support for QMK (#465) * Modularity and gcc warnings fixes. * Add ChibiOS support (USB stack + support files). * Make usb_main more USB_DRIVER #define independent. * Move chibios to tool. * Implement jump-to-bootloader. * Small updates. * Fix bootloader-jump compiling. * Move AVR specific sleep_led.c into avr. * Add basic sleep_led for chibios. * Update chibios README. * NKRO fixes. * Rename some Makefile defines. * Move STM32 bootloader address config to separate .h file. * Add ARM Teensies bootloader code. * Fix chibios/usb_main GET_REPORT handing. * Add missing #include to keymap.c. * Make bootmagic.c code portable (_delay_ms -> wait_ms). * Move declaration of keymap_config. Should really not declare variables in .h files - since it's included in different .c files, a proper linker then complains that the same variable is declared more than once (once for each .c file that the offending .h is included in). * Add eeprom support for chibios/kinetis. * Rename chibios example keyboard. * Move chibios/cortex selection to local Makefiles. * Chibios: use WFI in idle. WIP suspend stuff. * ChibiOS/kinetis: sending remote wakeup. * ChibiOS/STM32: send remote wakeup. * Fix report size of boot protocol. * Fix drop key stroke Keyboard report should be checked if its transfer finishs successfully. Otherwise key stroke can be missing when other key event occurs before the last report transfer is done. Boot protocol 10ms interval probably causes this problem in case it receives key events in a row within the period. NKRO protocol suffers less or nothing due to its interval 1ms. * Chibios/usb_main: rename a variable for clarity. * Add correct chibios/bootloader_jump for infinity KB. * ChibiOS: make reset request more CMSISy. * Chibios: Add breathing sleep LED on Kinetis MCUs. * ChibiOS: Update infinity bootloader code to match updated ChibiOS. * ChibiOS: prettify/document sleep_led code. * Chibios: Remove the wait in the main loop. * Add maple mini code. * Do timeout when writing to CONSOLE EP queue. Fixes TMK bug #266. * Chibios: add 'core/protocol' to the makefiles' search path. * Chibios: Update to new USB API. * Chibios: add more guards for transmitting (fix a deadlock bug). * Add update for chibios in README * Chibios: Fix a HardFault bug (wait after start). * Chibios: cleanup usb_main code. * Chibios: Revert common.mk change (fix AVR linking problem). * core: Fix chibios user compile options Compile options can be defined in project Makefile such as UDEFS, UADEFS, UINCDIR, ULIBDIR and ULIBS. * Sysv format for ChibiOS arm-none-eabi-size Some new patches to ChibiOS puts heap as it's own section. So the berkeley format is now useless, as the heap will be included in the BSS report. The sysv format displays the bss size correctly. * Fix hard-coded path of CHIBIOS * Add support for new version of ChibiOS and Contrib The Kinetis support has moved to a separate Contrib repository in the newest version of Chibios. There has also been some structure changes. So this adds support for those, while maintaining back- wards compability. * Update ChibiOS instructions * Chibios: implement sleep LED for STM32. * Chibios: Update the main chibios README. * Chibios: fix STM32_BOOTLOADER_ADDRESS name. * Chibios: make the default bootloader_jump redefinable (weak). * Chibios: disable LTO (link-time optimisation). With LTO enabled, sometimes things fail for mysterious reasons (e.g. bootloader jump on WF with LEDs enabled), just because the linker optimisation is too aggressive. * Chibios: add default location for chibios-contrib. * ChibiOS: update mk to match chibios/master. * ChibiOS: update instructions.md. * Add chibi_onekey example. * Add comments to chibi_onekey Makefile. * Rename some Makefile defines. * Move STM32 bootloader address config to separate .h file. * Rename chibios example keyboard. * Move chibios/cortex selection to local Makefiles. * Add Teensy LC onekey example. * Chibios: use WFI in idle. WIP suspend stuff. * Update chibi/teensy instructions. * Update chibios/Teensy instructions. * Add infinity_chibios * Add keymap_hasu.c * Infinity_chibios: select correct bootloader_jump. * Infinity_chibios: improve comments. * Add generic STM32F103C8T6 example. * Add maple mini code. * STM32F103x fixes. * Add maple mini pinout pic. * Chibios: updates for 3.0.4 git. * Chibios: rename example stm32_onekey -> stm32_f072_onekey. * Chibios: add makefiles for Teensy 3.x examples. * Chibios: update Teensy 3.x instructions. * Chibios: Tsy LC is cortex-m0plus. * Chibios: add more guards for transmitting (fix a deadlock bug). * Change README for chibios * Chibios: update examples to current chibios git. Match the changes in mainline chibios: - update chconf.h - update supplied ld scripts structure - update Teensy instructions (switch to official chibios and introduce contrib) * Add ChibiOS and ChibiOS-Contrib submodules Also fix the makefile path for them. * Moves chibios keyboards to keyboards folder * First version of ChibiOS compilation Only the stm32_f072_onkey keyboard is ported at the moment. It compiles, but still doesn't link. * More chibios fixes It now compiles without warnings and links * Move the teensy_lc_onekey to the keyboards folder * Clean up the make file rule structure * Remove keymap_fn_to_action * Update more ChibiOS keyboards to QMK Most of them does not compile at the moment though. * Use older version of Chibios libraries The newest ones have problems with compilation * Remove USB_UNCONFIGURED event It isn't present in the older version of ChibiOS * Fix the infinity_chibios compilation * Fix potentially uninitialized variable * Add missing include * Fix the ChibiOS makefile * Fix some Chibios keyboard compilation * Revert the rules.mk file back to master version * Combine the chibios and AVR makefiles With just the required overrides in the respective platform specific one. * Slight makefile restrucuring Platform specific compiler options * Move avr specific targets out of the main rules * Fix ChibiOS objcopy The ChibiOS objcopy needs different parameters, so the parameters are moved to the corresponding platform rule file * Fix the objcopy for real this time The comands were moved around, so chibios used avr and the ohter way around. Also change the objsize output format * Fix the thumb flags * Fix the infinity hasu keymap * Per platform cpp flags * Add gcc-arm-none-eabi package to travis * Add arm-none-eabi-newlib to travis * Fix the name of the libnewlib-arm-none-eabi lib * Fix the ChibiOS paths So that they are properly relative, and builds don't generate extra folders * Fix the board path of stm32_f103_onekey * Only consider folders with Makefiles as subproject --- .gitmodules | 6 + .travis.yml | 5 +- Makefile | 31 +- keyboards/infinity_chibios/MEMO.txt | 385 +++++ keyboards/infinity_chibios/Makefile | 70 + keyboards/infinity_chibios/bootloader_defs.h | 1 + keyboards/infinity_chibios/chconf.h | 524 +++++++ keyboards/infinity_chibios/config.h | 75 + keyboards/infinity_chibios/halconf.h | 353 +++++ keyboards/infinity_chibios/infinity_chibios.c | 17 + keyboards/infinity_chibios/infinity_chibios.h | 66 + .../infinity_chibios/keymaps/default/keymap.c | 48 + .../infinity_chibios/keymaps/hasu/keymap.c | 199 +++ keyboards/infinity_chibios/led.c | 24 + keyboards/infinity_chibios/matrix.c | 128 ++ keyboards/infinity_chibios/mcuconf.h | 55 + keyboards/planck/out.txt | 66 + keyboards/stm32_f072_onekey/Makefile | 50 + keyboards/stm32_f072_onekey/bootloader_defs.h | 7 + keyboards/stm32_f072_onekey/chconf.h | 524 +++++++ keyboards/stm32_f072_onekey/config.h | 76 + keyboards/stm32_f072_onekey/halconf.h | 353 +++++ .../keymaps/default/keymap.c | 25 + keyboards/stm32_f072_onekey/led.c | 34 + keyboards/stm32_f072_onekey/matrix.c | 163 ++ keyboards/stm32_f072_onekey/mcuconf.h | 171 ++ .../stm32_f072_onekey/stm32_f072_onekey.c | 1 + .../stm32_f072_onekey/stm32_f072_onekey.h | 5 + keyboards/stm32_f103_onekey/Makefile | 64 + .../boards/GENERIC_STM32_F103/board.c | 49 + .../boards/GENERIC_STM32_F103/board.h | 166 ++ .../boards/GENERIC_STM32_F103/board.mk | 5 + .../GENERIC_STM32_F103/mini_stm32_mapping.png | Bin 0 -> 162908 bytes .../boards/maple_mini_mapping.png | Bin 0 -> 237977 bytes keyboards/stm32_f103_onekey/bootloader_defs.h | 10 + keyboards/stm32_f103_onekey/chconf.h | 524 +++++++ keyboards/stm32_f103_onekey/config.h | 75 + keyboards/stm32_f103_onekey/flash.sh | 2 + keyboards/stm32_f103_onekey/halconf.h | 353 +++++ .../keymaps/default/keymap.c | 25 + .../ld/STM32F103x8_stm32duino_bootloader.ld | 88 ++ keyboards/stm32_f103_onekey/led.c | 43 + keyboards/stm32_f103_onekey/matrix.c | 177 +++ keyboards/stm32_f103_onekey/mcuconf.h | 209 +++ .../stm32_f103_onekey/stm32_f103_onekey.c | 1 + .../stm32_f103_onekey/stm32_f103_onekey.h | 4 + keyboards/teensy_lc_onekey/Makefile | 62 + keyboards/teensy_lc_onekey/Makefile.3.0 | 77 + keyboards/teensy_lc_onekey/Makefile.3.2 | 77 + keyboards/teensy_lc_onekey/chconf.h | 524 +++++++ keyboards/teensy_lc_onekey/config.h | 75 + keyboards/teensy_lc_onekey/halconf.h | 187 +++ keyboards/teensy_lc_onekey/instructions.md | 82 + .../teensy_lc_onekey/keymaps/default/keymap.c | 32 + keyboards/teensy_lc_onekey/ld/MKL26Z64.ld | 105 ++ keyboards/teensy_lc_onekey/led.c | 32 + keyboards/teensy_lc_onekey/matrix.c | 163 ++ keyboards/teensy_lc_onekey/mcuconf.h | 55 + keyboards/teensy_lc_onekey/teensy_lc_onekey.c | 1 + keyboards/teensy_lc_onekey/teensy_lc_onekey.h | 4 + lib/chibios | 1 + lib/chibios-contrib | 1 + quantum/keycode_config.h | 2 +- quantum/keymap.h | 11 +- quantum/{keymap.c => keymap_common.c} | 10 +- quantum/matrix.c | 2 + quantum/quantum.c | 2 +- quantum/quantum.h | 8 +- readme.md | 3 + tmk_core/avr.mk | 185 +++ tmk_core/chibios.mk | 154 ++ tmk_core/common.mk | 36 +- tmk_core/common/action_tapping.c | 2 +- tmk_core/common/{ => avr}/sleep_led.c | 0 tmk_core/common/bootmagic.c | 7 +- tmk_core/common/chibios/bootloader.c | 47 + tmk_core/common/chibios/eeprom.c | 588 +++++++ tmk_core/common/chibios/printf.c | 240 +++ tmk_core/common/chibios/printf.h | 111 ++ tmk_core/common/chibios/sleep_led.c | 226 +++ tmk_core/common/chibios/suspend.c | 65 + tmk_core/common/chibios/timer.c | 27 + tmk_core/common/command.c | 23 +- tmk_core/common/{avr => }/eeconfig.c | 2 +- tmk_core/common/eeprom.h | 22 + tmk_core/common/magic.c | 4 +- tmk_core/common/print.c | 8 +- tmk_core/common/print.h | 10 +- tmk_core/common/progmem.h | 4 +- tmk_core/common/report.h | 5 + tmk_core/common/wait.h | 8 +- tmk_core/protocol/chibios.mk | 10 + tmk_core/protocol/chibios/README.md | 55 + tmk_core/protocol/chibios/main.c | 147 ++ tmk_core/protocol/chibios/usb_main.c | 1372 +++++++++++++++++ tmk_core/protocol/chibios/usb_main.h | 139 ++ tmk_core/readme.md | 16 +- tmk_core/rules.mk | 220 +-- tmk_core/tool/chibios/.gitignore | 2 + .../tool/chibios/ch-bootloader-jump.patch | 116 ++ 100 files changed, 10366 insertions(+), 258 deletions(-) create mode 100644 keyboards/infinity_chibios/MEMO.txt create mode 100644 keyboards/infinity_chibios/Makefile create mode 100644 keyboards/infinity_chibios/bootloader_defs.h create mode 100644 keyboards/infinity_chibios/chconf.h create mode 100644 keyboards/infinity_chibios/config.h create mode 100644 keyboards/infinity_chibios/halconf.h create mode 100644 keyboards/infinity_chibios/infinity_chibios.c create mode 100644 keyboards/infinity_chibios/infinity_chibios.h create mode 100644 keyboards/infinity_chibios/keymaps/default/keymap.c create mode 100644 keyboards/infinity_chibios/keymaps/hasu/keymap.c create mode 100644 keyboards/infinity_chibios/led.c create mode 100644 keyboards/infinity_chibios/matrix.c create mode 100644 keyboards/infinity_chibios/mcuconf.h create mode 100644 keyboards/planck/out.txt create mode 100644 keyboards/stm32_f072_onekey/Makefile create mode 100644 keyboards/stm32_f072_onekey/bootloader_defs.h create mode 100644 keyboards/stm32_f072_onekey/chconf.h create mode 100644 keyboards/stm32_f072_onekey/config.h create mode 100644 keyboards/stm32_f072_onekey/halconf.h create mode 100644 keyboards/stm32_f072_onekey/keymaps/default/keymap.c create mode 100644 keyboards/stm32_f072_onekey/led.c create mode 100644 keyboards/stm32_f072_onekey/matrix.c create mode 100644 keyboards/stm32_f072_onekey/mcuconf.h create mode 100644 keyboards/stm32_f072_onekey/stm32_f072_onekey.c create mode 100644 keyboards/stm32_f072_onekey/stm32_f072_onekey.h create mode 100644 keyboards/stm32_f103_onekey/Makefile create mode 100644 keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.c create mode 100644 keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.h create mode 100644 keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.mk create mode 100644 keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/mini_stm32_mapping.png create mode 100644 keyboards/stm32_f103_onekey/boards/maple_mini_mapping.png create mode 100644 keyboards/stm32_f103_onekey/bootloader_defs.h create mode 100644 keyboards/stm32_f103_onekey/chconf.h create mode 100644 keyboards/stm32_f103_onekey/config.h create mode 100755 keyboards/stm32_f103_onekey/flash.sh create mode 100644 keyboards/stm32_f103_onekey/halconf.h create mode 100644 keyboards/stm32_f103_onekey/keymaps/default/keymap.c create mode 100644 keyboards/stm32_f103_onekey/ld/STM32F103x8_stm32duino_bootloader.ld create mode 100644 keyboards/stm32_f103_onekey/led.c create mode 100644 keyboards/stm32_f103_onekey/matrix.c create mode 100644 keyboards/stm32_f103_onekey/mcuconf.h create mode 100644 keyboards/stm32_f103_onekey/stm32_f103_onekey.c create mode 100644 keyboards/stm32_f103_onekey/stm32_f103_onekey.h create mode 100644 keyboards/teensy_lc_onekey/Makefile create mode 100644 keyboards/teensy_lc_onekey/Makefile.3.0 create mode 100644 keyboards/teensy_lc_onekey/Makefile.3.2 create mode 100644 keyboards/teensy_lc_onekey/chconf.h create mode 100644 keyboards/teensy_lc_onekey/config.h create mode 100644 keyboards/teensy_lc_onekey/halconf.h create mode 100644 keyboards/teensy_lc_onekey/instructions.md create mode 100644 keyboards/teensy_lc_onekey/keymaps/default/keymap.c create mode 100644 keyboards/teensy_lc_onekey/ld/MKL26Z64.ld create mode 100644 keyboards/teensy_lc_onekey/led.c create mode 100644 keyboards/teensy_lc_onekey/matrix.c create mode 100644 keyboards/teensy_lc_onekey/mcuconf.h create mode 100644 keyboards/teensy_lc_onekey/teensy_lc_onekey.c create mode 100644 keyboards/teensy_lc_onekey/teensy_lc_onekey.h create mode 160000 lib/chibios create mode 160000 lib/chibios-contrib rename quantum/{keymap.c => keymap_common.c} (94%) create mode 100644 tmk_core/avr.mk create mode 100644 tmk_core/chibios.mk rename tmk_core/common/{ => avr}/sleep_led.c (100%) create mode 100644 tmk_core/common/chibios/bootloader.c create mode 100644 tmk_core/common/chibios/eeprom.c create mode 100644 tmk_core/common/chibios/printf.c create mode 100644 tmk_core/common/chibios/printf.h create mode 100644 tmk_core/common/chibios/sleep_led.c create mode 100644 tmk_core/common/chibios/suspend.c create mode 100644 tmk_core/common/chibios/timer.c rename tmk_core/common/{avr => }/eeconfig.c (98%) create mode 100644 tmk_core/common/eeprom.h create mode 100644 tmk_core/protocol/chibios.mk create mode 100644 tmk_core/protocol/chibios/README.md create mode 100644 tmk_core/protocol/chibios/main.c create mode 100644 tmk_core/protocol/chibios/usb_main.c create mode 100644 tmk_core/protocol/chibios/usb_main.h create mode 100644 tmk_core/tool/chibios/.gitignore create mode 100644 tmk_core/tool/chibios/ch-bootloader-jump.patch diff --git a/.gitmodules b/.gitmodules index e69de29bb2..1576b8dc0b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "lib/chibios"] + path = lib/chibios + url = https://github.com/ChibiOS/ChibiOS.git +[submodule "lib/chibios-contrib"] + path = lib/chibios-contrib + url = https://github.com/ChibiOS/ChibiOS-Contrib.git diff --git a/.travis.yml b/.travis.yml index 955f696794..26deac0ceb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,4 +18,7 @@ addons: - gcc-avr - dfu-programmer - pandoc -after_success: bash util/travis_compiled_push.sh \ No newline at end of file + - gcc-arm-none-eabi + - binutils-arm-none-eabi + - libnewlib-arm-none-eabi +after_success: bash util/travis_compiled_push.sh diff --git a/Makefile b/Makefile index f9b865b9f8..c285dabad4 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,8 @@ ifndef VERBOSE .SILENT: endif +.DEFAULT_GOAL := all + space := $(subst ,, ) starting_makefile := $(subst $(space),_SPACE_,$(abspath $(firstword $(MAKEFILE_LIST)))) mkfile_path := $(subst $(space),_SPACE_,$(abspath $(lastword $(MAKEFILE_LIST)))) @@ -41,6 +43,7 @@ endif TOP_DIR = $(tmk_root) TMK_DIR = tmk_core TMK_PATH = $(TOP_DIR)/$(TMK_DIR) +LIB_PATH = $(TOP_DIR)/lib QUANTUM_DIR = quantum QUANTUM_PATH = $(TOP_DIR)/$(QUANTUM_DIR) @@ -126,6 +129,13 @@ ifdef SUBPROJECT else TARGET ?= $(KEYBOARD)_$(KEYMAP) endif +BUILD_DIR = .build + +# Object files directory +# To put object files in current directory, use a dot (.), do NOT make +# this an empty or blank macro! +OBJDIR = $(BUILD_DIR)/obj_$(TARGET) + ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","") @@ -143,7 +153,7 @@ endif SRC += $(KEYBOARD_FILE) \ $(KEYMAP_FILE) \ $(QUANTUM_DIR)/quantum.c \ - $(QUANTUM_DIR)/keymap.c \ + $(QUANTUM_DIR)/keymap_common.c \ $(QUANTUM_DIR)/keycode_config.c \ $(QUANTUM_DIR)/process_keycode/process_leader.c @@ -208,8 +218,25 @@ VPATH += $(QUANTUM_PATH)/keymap_extras VPATH += $(QUANTUM_PATH)/audio VPATH += $(QUANTUM_PATH)/process_keycode -include $(TMK_PATH)/protocol/lufa.mk + +# We can assume a ChibiOS target When MCU_FAMILY is defined, since it's not used for LUFA +ifdef MCU_FAMILY + PLATFORM=CHIBIOS +else + PLATFORM=AVR +endif + include $(TMK_PATH)/common.mk +ifeq ($(PLATFORM),AVR) + include $(TMK_PATH)/protocol/lufa.mk + include $(TMK_PATH)/avr.mk +else ifeq ($(PLATFORM),CHIBIOS) + include $(TMK_PATH)/protocol/chibios.mk + include $(TMK_PATH)/chibios.mk +else + $(error Unknown platform) +endif + include $(TMK_PATH)/rules.mk GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S") diff --git a/keyboards/infinity_chibios/MEMO.txt b/keyboards/infinity_chibios/MEMO.txt new file mode 100644 index 0000000000..e2886aa002 --- /dev/null +++ b/keyboards/infinity_chibios/MEMO.txt @@ -0,0 +1,385 @@ +flabbergast's TMK/ChibiOS port +============================== +2015/10/16 + + +Build +----- +$ git clone -b chibios https://github.com/flabbergast/tmk_keyboard.git + +$ cd tmk_keyboard +$ git submodule add -f -b kinetis https://github.com/flabbergast/ChibiOS.git tmk_core/tool/chibios/chibios +or +$ cd tmk_keyboard/tmk_core/tool/chibios +$ git clone -b kinetis https://github.com/flabbergast/ChibiOS.git tmk_core/tool/chibios/chibios + +$ cd tmk_keyboard/keyboard/infinity_chibios +$ make + + + + +Chibios Configuration +--------------------- +halconf.h: for HAL configuration + placed in project directory + read in chibios/os/hal/hal.mk + included in chibios/os/hal/include/hal.h +mcuconf.h: for MCU configuration + placed in project directory + included in halconf.h + + +Chibios Term +------------ +PAL = Port Abstraction Layer + palWritePad + palReadPad + palSetPad + chibios/os/hal/include/pal.h + +LLD = Low Level Driver + + +Makefile +-------- + # /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) + MCU_FAMILY = KINETIS + MCU_SERIES = KL2x + + # - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ + # or /ld/ + MCU_LDSCRIPT = MKL26Z64 + + # - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ + MCU_STARTUP = kl2x + + # Board: it should exist either in /os/hal/boards/ + # or /boards + BOARD = PJRC_TEENSY_LC + + MCU = cortex-m0 + + # ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 + ARMV = 6 + + +halconf.h +--------- + + +mcuconf.h +--------- + + +chconf.h +-------- + + +ld script +--------- +--- ../../tmk_core/tool/chibios/chibios/os/common/ports/ARMCMx/compilers/GCC/ld/MKL26Z64.ld 2015-10-15 09:08:58.732904304 +0900 ++++ ld/MKL26Z64.ld 2015-10-15 08:48:06.430215496 +0900 +@@ -27,7 +27,8 @@ + { + flash0 : org = 0x00000000, len = 0xc0 + flashcfg : org = 0x00000400, len = 0x10 +- flash : org = 0x00000410, len = 64k - 0x410 ++ flash : org = 0x00000410, len = 62k - 0x410 ++ eeprom_emu : org = 0x0000F800, len = 2k + ram : org = 0x1FFFF800, len = 8k + } + +@@ -35,6 +36,10 @@ + __ram_size__ = LENGTH(ram); + __ram_end__ = __ram_start__ + __ram_size__; + ++__eeprom_workarea_start__ = ORIGIN(eeprom_emu); ++__eeprom_workarea_size__ = LENGTH(eeprom_emu); ++__eeprom_workarea_end__ = __eeprom_workarea_start__ + __eeprom_workarea_size__; ++ + SECTIONS + { + . = 0; + + + +Configuration/Startup for Infinity 60% +-------------------------------------- +Configuration: + + +Clock: +Inifinity + FEI(FLL Engaged Internal) mode with core clock:48MHz, bus clock:48MHz, flash clock:24MHz + Clock dividor: + SIM_CLKDIV1[OUTDIV1] = 0 divide-by-1 for core clock + SIM_CLKDIV1[OUTDIV2] = 0 divide-by-1 for bus clock + SIM_CLKDIV1[OUTDIV4] = 1 divide-by-2 for flash clock + Internal reference clock: + MCG_C1[IREFS] = 1 Internal Reference Select for clock source for FLL + MCG_C1[IRCLKEN] = 1 Internal Reference Clock Enable + FLL multipilication: + MCG_C4[DMX32] = 1 + MCG_C4[DRST_DRS] = 01 FLL factor 1464 * 32.768kHz = 48MHz + +chibios/os/hal/ports/KINETIS/K20x/hal_lld.c + k20x_clock_init(): called in __early_init() defined in board.c + disable watchdog and configure clock + + configurable macros: + KINETIS_NO_INIT: whether init or not + KINETIS_MCG_MODE: clock mode + KINETIS_MCG_MODE_FEI + KINETIS_MCG_MODE_PEE + hal/ports/KINETIS/K20x/hal_lld.h + + +chibios/os/hal/boards/FREESCALE_FREEDOM_K20D50M/board.h + PALConfig pal_default_config + boardInit() + __early_init() + macro definitions for board infos, freq and mcu type + +chibios/os/hal/boards/FREESCALE_FREEDOM_K20D50M/board.c + +USB + + +Startup +------- + common/ports/ARMCMx/GCC/crt0_v[67]m.s + Reset_Handler: startup code + common/ports/ARMCMx/GCC/crt1.c + __core_init(): weak + __early_init(): weak + __late_init(): weak + __default_exit(): weak + called from Reset_Handler of crt0 + common/ports/ARMCMx/GCC/vector.c + common/ports/ARMCMx/GCC/ld/*.ld + +chibios/os/common/ports/ARMCMx/compilers/GCC/ +├── crt0_v6m.s +├── crt0_v7m.s +├── crt1.c +├── ld +│   ├── MK20DX128BLDR3.ld +│   ├── MK20DX128BLDR4.ld +│   ├── MK20DX128.ld +│   ├── MK20DX256.ld +│   ├── MKL25Z128.ld +│   ├── MKL26Z128.ld +│   ├── MKL26Z64.ld +│   └── STM32L476xG.ld +├── mk +│   ├── startup_k20x5.mk +│   ├── startup_k20x7.mk +│   ├── startup_k20x.mk +│   ├── startup_kl2x.mk +│   └── startup_stm32l4xx.mk +├── rules.ld +├── rules.mk +└── vectors.c + +chibios/os/hal/ +├── boards +│   ├── FREESCALE_FREEDOM_K20D50M +│   │   ├── board.c +│   │   ├── board.h +│   │   └── board.mk +│   ├── MCHCK_K20 +│   │   ├── board.c +│   │   ├── board.h +│   │   └── board.mk +│   ├── PJRC_TEENSY_3 +│   │   ├── board.c +│   │   ├── board.h +│   │   └── board.mk +│   ├── PJRC_TEENSY_3_1 +│   │   ├── board.c +│   │   ├── board.h +│   │   └── board.mk +│   ├── PJRC_TEENSY_LC +│   │   ├── board.c +│   │   ├── board.h +│   │   └── board.mk +│   ├── readme.txt +│   ├── simulator +│   │   ├── board.c +│   │   ├── board.h +│   │   └── board.mk +│   ├── ST_NUCLEO_F030R8 +│   │   ├── board.c +│   │   ├── board.h +│   │   ├── board.mk +│   │   └── cfg +│   │   └── board.chcfg +├── hal.mk +├── include +│   ├── adc.h +│   ├── can.h +│   ├── dac.h +│   ├── ext.h +│   ├── gpt.h +│   ├── hal_channels.h +│   ├── hal_files.h +│   ├── hal.h +│   ├── hal_ioblock.h +│   ├── hal_mmcsd.h +│   ├── hal_queues.h +│   ├── hal_streams.h +│   ├── i2c.h +│   ├── i2s.h +│   ├── icu.h +│   ├── mac.h +│   ├── mii.h +│   ├── mmc_spi.h +│   ├── pal.h +│   ├── pwm.h +│   ├── rtc.h +│   ├── sdc.h +│   ├── serial.h +│   ├── serial_usb.h +│   ├── spi.h +│   ├── st.h +│   ├── uart.h +│   └── usb.h +├── lib +│   └── streams +│   ├── chprintf.c +│   ├── chprintf.h +│   ├── memstreams.c +│   ├── memstreams.h +│   ├── nullstreams.c +│   └── nullstreams.h +├── osal +│   ├── nil +│   │   ├── osal.c +│   │   ├── osal.h +│   │   └── osal.mk +│   ├── os-less +│   │   └── ARMCMx +│   │   ├── osal.c +│   │   ├── osal.h +│   │   └── osal.mk +│   └── rt +│   ├── osal.c +│   ├── osal.h +│   └── osal.mk +├── ports +│   ├── AVR +│   ├── common +│   │   └── ARMCMx +│   │   ├── mpu.h +│   │   ├── nvic.c +│   │   └── nvic.h +│   ├── KINETIS +│   │   ├── K20x +│   │   │   ├── hal_lld.c +│   │   │   ├── hal_lld.h +│   │   │   ├── kinetis_registry.h +│   │   │   ├── platform.dox +│   │   │   ├── platform.mk +│   │   │   ├── pwm_lld.c +│   │   │   ├── pwm_lld.h +│   │   │   ├── spi_lld.c +│   │   │   └── spi_lld.h +│   │   ├── KL2x +│   │   │   ├── hal_lld.c +│   │   │   ├── hal_lld.h +│   │   │   ├── kinetis_registry.h +│   │   │   ├── platform.mk +│   │   │   ├── pwm_lld.c +│   │   │   └── pwm_lld.h +│   │   ├── LLD +│   │   │   ├── adc_lld.c +│   │   │   ├── adc_lld.h +│   │   │   ├── ext_lld.c +│   │   │   ├── ext_lld.h +│   │   │   ├── gpt_lld.c +│   │   │   ├── gpt_lld.h +│   │   │   ├── i2c_lld.c +│   │   │   ├── i2c_lld.h +│   │   │   ├── pal_lld.c +│   │   │   ├── pal_lld.h +│   │   │   ├── serial_lld.c +│   │   │   ├── serial_lld.h +│   │   │   ├── st_lld.c +│   │   │   ├── st_lld.h +│   │   │   ├── usb_lld.c +│   │   │   └── usb_lld.h +│   │   └── README.md +│   ├── LPC +│   ├── simulator +│   └── STM32 +├── src +│   ├── adc.c +│   ├── can.c +│   ├── dac.c +│   ├── ext.c +│   ├── gpt.c +│   ├── hal.c +│   ├── hal_mmcsd.c +│   ├── hal_queues.c +│   ├── i2c.c +│   ├── i2s.c +│   ├── icu.c +│   ├── mac.c +│   ├── mmc_spi.c +│   ├── pal.c +│   ├── pwm.c +│   ├── rtc.c +│   ├── sdc.c +│   ├── serial.c +│   ├── serial_usb.c +│   ├── spi.c +│   ├── st.c +│   ├── uart.c +│   └── usb.c +└── templates + ├── adc_lld.c + ├── adc_lld.h + ├── can_lld.c + ├── can_lld.h + ├── dac_lld.c + ├── dac_lld.h + ├── ext_lld.c + ├── ext_lld.h + ├── gpt_lld.c + ├── gpt_lld.h + ├── halconf.h + ├── hal_lld.c + ├── hal_lld.h + ├── i2c_lld.c + ├── i2c_lld.h + ├── i2s_lld.c + ├── i2s_lld.h + ├── icu_lld.c + ├── icu_lld.h + ├── mac_lld.c + ├── mac_lld.h + ├── mcuconf.h + ├── osal + │   ├── osal.c + │   ├── osal.h + │   └── osal.mk + ├── pal_lld.c + ├── pal_lld.h + ├── platform.mk + ├── pwm_lld.c + ├── pwm_lld.h + ├── rtc_lld.c + ├── rtc_lld.h + ├── sdc_lld.c + ├── sdc_lld.h + ├── serial_lld.c + ├── serial_lld.h + ├── spi_lld.c + ├── spi_lld.h + ├── st_lld.c + ├── st_lld.h + ├── uart_lld.c + ├── uart_lld.h + ├── usb_lld.c + └── usb_lld.h diff --git a/keyboards/infinity_chibios/Makefile b/keyboards/infinity_chibios/Makefile new file mode 100644 index 0000000000..649b43e64d --- /dev/null +++ b/keyboards/infinity_chibios/Makefile @@ -0,0 +1,70 @@ +# project specific files +SRC = matrix.c \ + led.c + +## chip/board settings +# - the next two should match the directories in +# /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) +# - For Teensies, FAMILY = KINETIS and SERIES is either +# KL2x (LC) or K20x (3.0,3.1,3.2). +# - For Infinity KB, SERIES = K20x +MCU_FAMILY = KINETIS +MCU_SERIES = K20x + +# Linker script to use +# - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ +# or /ld/ +# - NOTE: a custom ld script is needed for EEPROM on Teensy LC +# - LDSCRIPT = +# - MKL26Z64 for Teensy LC +# - MK20DX128 for Teensy 3.0 +# - MK20DX256 for Teensy 3.1 and 3.2 +# - MK20DX128BLDR4 for Infinity with Kiibohd bootloader +MCU_LDSCRIPT = MK20DX128BLDR4 + +# Startup code to use +# - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ +# - STARTUP = +# - kl2x for Teensy LC +# - k20x5 for Teensy 3.0 and Infinity KB +# - k20x7 for Teensy 3.1 and 3.2 +MCU_STARTUP = k20x5 + +# Board: it should exist either in /os/hal/boards/ +# or /boards +# - BOARD = +# - PJRC_TEENSY_LC for Teensy LC +# - PJRC_TEENSY_3 for Teensy 3.0 +# - PJRC_TEENSY_3_1 for Teensy 3.1 or 3.2 +# - MCHCK_K20 for Infinity KB +BOARD = MCHCK_K20 + +# Cortex version +# Teensy LC is cortex-m0; Teensy 3.x are cortex-m4 +MCU = cortex-m4 + +# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 +# I.e. 6 for Teensy LC; 7 for Teensy 3.x +ARMV = 7 + +# Vector table for application +# 0x00000000-0x00001000 area is occupied by bootlaoder.*/ +# The CORTEX_VTOR... is needed only for MCHCK/Infinity KB +OPT_DEFS = -DCORTEX_VTOR_INIT=0x00001000 + +# Build Options +# comment out to disable the options. +# +BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration +## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.) +MOUSEKEY_ENABLE ?= yes # Mouse keys +EXTRAKEY_ENABLE ?= yes # Audio control and System control +CONSOLE_ENABLE ?= yes # Console for debug +COMMAND_ENABLE ?= yes # Commands for debug and configuration +SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend +NKRO_ENABLE ?= yes # USB Nkey Rollover +CUSTOM_MATRIX ?= yes # Custom matrix file + +ifndef QUANTUM_DIR + include ../../Makefile +endif \ No newline at end of file diff --git a/keyboards/infinity_chibios/bootloader_defs.h b/keyboards/infinity_chibios/bootloader_defs.h new file mode 100644 index 0000000000..c67153be60 --- /dev/null +++ b/keyboards/infinity_chibios/bootloader_defs.h @@ -0,0 +1 @@ +#define KIIBOHD_BOOTLOADER diff --git a/keyboards/infinity_chibios/chconf.h b/keyboards/infinity_chibios/chconf.h new file mode 100644 index 0000000000..b886c383bb --- /dev/null +++ b/keyboards/infinity_chibios/chconf.h @@ -0,0 +1,524 @@ +/* + 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. +*/ + +/** + * @file templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16 or 32 bits. + */ +#define CH_CFG_ST_RESOLUTION 32 + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#define CH_CFG_ST_FREQUENCY 1000 + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#define CH_CFG_ST_TIMEDELTA 0 + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#define CH_CFG_TIME_QUANTUM 20 + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#define CH_CFG_MEMCORE_SIZE 0 + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#define CH_CFG_NO_IDLE_THREAD FALSE + +/* Use __WFI in the idle thread for waiting. Does lower the power + * consumption. */ +#define CORTEX_ENABLE_WFI_IDLE TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#define CH_CFG_OPTIMIZE_SPEED TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_TM FALSE + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_REGISTRY TRUE + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_WAITEXIT TRUE + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_SEMAPHORES TRUE + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MUTEXES TRUE + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_CONDVARS TRUE + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_EVENTS TRUE + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MESSAGES TRUE + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_MAILBOXES TRUE + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMCORE TRUE + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#define CH_CFG_USE_HEAP TRUE + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMPOOLS TRUE + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#define CH_CFG_USE_DYNAMIC TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_STATISTICS FALSE + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_SYSTEM_STATE_CHECK FALSE + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_CHECKS FALSE + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_ASSERTS FALSE + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_BUFFER_SIZE 128 + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#define CH_DBG_ENABLE_STACK_CHECK FALSE + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_FILL_THREADS FALSE + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#define CH_DBG_THREADS_PROFILING FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p chThdInit() API. + * + * @note It is invoked from within @p chThdInit() and implicitly from all + * the threads creation APIs. + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/keyboards/infinity_chibios/config.h b/keyboards/infinity_chibios/config.h new file mode 100644 index 0000000000..cb90222055 --- /dev/null +++ b/keyboards/infinity_chibios/config.h @@ -0,0 +1,75 @@ +/* +Copyright 2015 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 CONFIG_H +#define CONFIG_H + + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6464 +#define DEVICE_VER 0x0001 +/* in python2: list(u"whatever".encode('utf-16-le')) */ +/* at most 32 characters or the ugly hack in usb_main.c borks */ +#define MANUFACTURER "TMK" +#define USBSTR_MANUFACTURER 'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', '\xc6', '\x00' +#define PRODUCT "Infinity keyboard/TMK" +#define USBSTR_PRODUCT 'I', '\x00', 'n', '\x00', 'f', '\x00', 'i', '\x00', 'n', '\x00', 'i', '\x00', 't', '\x00', 'y', '\x00', ' ', '\x00', 'k', '\x00', 'e', '\x00', 'y', '\x00', 'b', '\x00', 'o', '\x00', 'a', '\x00', 'r', '\x00', 'd', '\x00', '/', '\x00', 'T', '\x00', 'M', '\x00', 'K', '\x00' + +/* key matrix size */ +#define MATRIX_ROWS 9 +#define MATRIX_COLS 7 + +/* define if matrix has ghost */ +//#define MATRIX_HAS_GHOST + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +//#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +//#define LOCKING_RESYNC_ENABLE + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + +/* Keymap for Infiity prototype */ +#define INFINITY_PROTOTYPE + + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +#endif diff --git a/keyboards/infinity_chibios/halconf.h b/keyboards/infinity_chibios/halconf.h new file mode 100644 index 0000000000..53538de149 --- /dev/null +++ b/keyboards/infinity_chibios/halconf.h @@ -0,0 +1,353 @@ +/* + 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. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef _HALCONF_H_ +#define _HALCONF_H_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EXT subsystem. + */ +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) +#define HAL_USE_EXT FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL FALSE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB TRUE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB TRUE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 64 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 64 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 256 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT TRUE +#endif + +#endif /* _HALCONF_H_ */ + +/** @} */ diff --git a/keyboards/infinity_chibios/infinity_chibios.c b/keyboards/infinity_chibios/infinity_chibios.c new file mode 100644 index 0000000000..845eda01b0 --- /dev/null +++ b/keyboards/infinity_chibios/infinity_chibios.c @@ -0,0 +1,17 @@ +/* +Copyright 2012,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 . +*/ +#include "infinity_chibios.h" diff --git a/keyboards/infinity_chibios/infinity_chibios.h b/keyboards/infinity_chibios/infinity_chibios.h new file mode 100644 index 0000000000..a44c68b82d --- /dev/null +++ b/keyboards/infinity_chibios/infinity_chibios.h @@ -0,0 +1,66 @@ +/* +Copyright 2014 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 KEYMAP_COMMON_H +#define KEYMAP_COMMON_H + +#include "quantum.h" + +#ifdef INFINITY_PROTOTYPE + +/* Infinity prototype */ +#define KEYMAP( \ + K00, K10, K20, K30, K40, K50, K60, K70, K80, K01, K11, K21, K31, K41, K86, \ + K51, K61, K71, K81, K02, K12, K22, K32, K42, K52, K62, K72, K82, K03, \ + K13, K23, K33, K43, K53, K63, K73, K83, K04, K14, K24, K34, K44, \ + K54, K64, K74, K84, K05, K15, K25, K35, K45, K55, K65, K75, K85, \ + K06, K16, K26, K36, K46, K56, K66, K76 \ +) { \ + { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06 }, \ + { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16 }, \ + { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26 }, \ + { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36 }, \ + { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46 }, \ + { KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56 }, \ + { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66 }, \ + { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76 }, \ + { KC_##K80, KC_##K81, KC_##K82, KC_##K83, KC_##K84, KC_##K85, KC_##K86 } \ +} + +#else + +/* Infinity production */ +#define KEYMAP( \ + K00, K10, K20, K30, K40, K50, K60, K70, K80, K01, K11, K21, K31, K41, K51, \ + K61, K71, K81, K02, K12, K22, K32, K42, K52, K62, K72, K82, K03, K13, \ + K23, K33, K43, K53, K63, K73, K83, K04, K14, K24, K34, K44, K54, \ + K64, K74, K84, K05, K15, K25, K35, K45, K55, K65, K75, K85, K06, \ + K16, K26, K36, K46, K56, K66, K76, K86 \ +) { \ + { KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06 }, \ + { KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16 }, \ + { KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26 }, \ + { KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_##K35, KC_##K36 }, \ + { KC_##K40, KC_##K41, KC_##K42, KC_##K43, KC_##K44, KC_##K45, KC_##K46 }, \ + { KC_##K50, KC_##K51, KC_##K52, KC_##K53, KC_##K54, KC_##K55, KC_##K56 }, \ + { KC_##K60, KC_##K61, KC_##K62, KC_##K63, KC_##K64, KC_##K65, KC_##K66 }, \ + { KC_##K70, KC_##K71, KC_##K72, KC_##K73, KC_##K74, KC_##K75, KC_##K76 }, \ + { KC_##K80, KC_##K81, KC_##K82, KC_##K83, KC_##K84, KC_##K85, KC_##K86 } \ +} + +#endif + +#endif diff --git a/keyboards/infinity_chibios/keymaps/default/keymap.c b/keyboards/infinity_chibios/keymaps/default/keymap.c new file mode 100644 index 0000000000..2acf728494 --- /dev/null +++ b/keyboards/infinity_chibios/keymaps/default/keymap.c @@ -0,0 +1,48 @@ +#include "infinity_chibios.h" + +const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* Layer 0: Default Layer + * ,-----------------------------------------------------------. + * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| `|BSp| + * |-----------------------------------------------------------| + * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| + * |-----------------------------------------------------------| + * |Contro| A| S| D| F| G| H| J| K| L| ;| '|Enter | + * |-----------------------------------------------------------| + * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn0| + * |-----------------------------------------------------------' + * | |Gui|Alt | Space |Alt |Gui| | | + * `-----------------------------------------------------------' + */ + [0] = + KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS, GRV, \ + TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \ + LCTL,A, S, D, F, G, H, J, K, L, SCLN,QUOT,ENT, \ + LSFT,Z, X, C, V, B, N, M, COMM,DOT, SLSH,RSFT,FN0, \ + NO, LGUI,LALT, SPC, RALT,RGUI,NO, NO), + + /* Layer 1: HHKB mode (HHKB Fn) + * ,-----------------------------------------------------------. + * |Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| + * |-----------------------------------------------------------| + * |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs| + * |-----------------------------------------------------------| + * | |VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter | + * |-----------------------------------------------------------| + * | | | | | | | +| -|End|PgD|Dow| | | + * `-----------------------------------------------------------' + * | |Gui|Alt | Space |Alt |Gui| | | + * `-----------------------------------------------------------' + */ + [1] = + KEYMAP(PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS, UP, TRNS, BSPC, \ + TRNS,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT,PENT, \ + TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PPLS,PMNS,END, PGDN,DOWN,TRNS,TRNS, \ + TRNS,TRNS,TRNS, TRNS, TRNS,TRNS,TRNS,TRNS), +}; + +const uint16_t fn_actions[] = { + [0] = ACTION_LAYER_MOMENTARY(1), +}; + diff --git a/keyboards/infinity_chibios/keymaps/hasu/keymap.c b/keyboards/infinity_chibios/keymaps/hasu/keymap.c new file mode 100644 index 0000000000..e9a212f0eb --- /dev/null +++ b/keyboards/infinity_chibios/keymaps/hasu/keymap.c @@ -0,0 +1,199 @@ +#include "infinity_chibios.h" + +const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + /* Layer 0: Default Layer + * ,-----------------------------------------------------------. + * |Esc| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| `|BSp| + * |-----------------------------------------------------------| + * |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| + * |-----------------------------------------------------------| + * |Contro| A| S| D| F| G| H| J| K| L| ;| '|Enter | + * |-----------------------------------------------------------| + * |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |Fn0| + * |-----------------------------------------------------------' + * | |Gui|Alt | Space |Alt |Gui| | | + * `-----------------------------------------------------------' + */ + [0] = + KEYMAP(ESC, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, MINS,EQL, BSLS,GRV, \ + TAB, Q, W, E, R, T, Y, U, I, O, P, LBRC,RBRC,BSPC, \ + LCTL,A, S, D, F, G, H, J, K, L, FN3, QUOT,FN6, \ + FN7, Z, X, C, V, B, N, M, COMM,DOT, FN2, RSFT,FN1, \ + NO, LGUI,LALT, FN4, FN5, RGUI,NO, NO), + + /* Layer 1: HHKB mode (HHKB Fn) + * ,-----------------------------------------------------------. + * |Pwr| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| + * |-----------------------------------------------------------| + * |Caps | | | | | | | |Psc|Slk|Pus|Up | |Backs| + * |-----------------------------------------------------------| + * | |VoD|VoU|Mut| | | *| /|Hom|PgU|Lef|Rig|Enter | + * |-----------------------------------------------------------| + * | | | | | | | +| -|End|PgD|Dow| | | + * `-----------------------------------------------------------' + * | |Gui|Alt | Space |Alt |Gui| | | + * `-----------------------------------------------------------' + */ + [1] = + KEYMAP(PWR, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + CAPS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,TRNS,PSCR,SLCK,PAUS, UP, TRNS,BSPC, \ + LCTL,VOLD,VOLU,MUTE,TRNS,TRNS,PAST,PSLS,HOME,PGUP,LEFT,RGHT,ENT, \ + LSFT,TRNS,TRNS,TRNS,TRNS,TRNS,PPLS,PMNS,END, PGDN,DOWN,RSFT,TRNS, \ + TRNS,LGUI,LALT, TRNS, RALT,RGUI,TRNS,TRNS), + + /* Layer 2: Vi mode[Slash] + * ,-----------------------------------------------------------. + * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| + * |-----------------------------------------------------------| + * |Tab |Hom|PgD|Up |PgU|End|Hom|PgD|PgUlEnd| | | |Backs| + * |-----------------------------------------------------------| + * |Contro| |Lef|Dow|Rig| |Lef|Dow|Up |Rig| | |Return | + * |-----------------------------------------------------------| + * |Shift | | | | | |Hom|PgD|PgUlEnd|Fn0|Shift | | + * `-----------------------------------------------------------' + * |Gui|Alt | Space |Alt |Gui| + * `-------------------------------------------' + */ + [2] = \ + KEYMAP(GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + TAB, HOME,PGDN,UP, PGUP,END, HOME,PGDN,PGUP,END, NO, NO, NO, BSPC, \ + LCTL,NO, LEFT,DOWN,RGHT,NO, LEFT,DOWN,UP, RGHT,NO, NO, ENT, \ + LSFT,NO, NO, NO, NO, NO, HOME,PGDN,PGUP,END, FN2, RSFT,TRNS, \ + TRNS,LGUI,LALT, SPC, RALT,RGUI,TRNS,TRNS), + + /* Layer 3: Mouse mode(IJKL)[Semicolon] + * ,-----------------------------------------------------------. + * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| + * |-----------------------------------------------------------| + * |Tab | | | | | |MwL|MwD|McU|MwU|MwR|Wbk|Wfr|Alt-T| + * |-----------------------------------------------------------| + * |Contro| | | | | |Mb2|McL|McD|McR|Fn | |Return | + * |-----------------------------------------------------------| + * |Shift | | | | |Mb3|Mb2|Mb1|Mb4|Mb5| |Shift | | + * `-----------------------------------------------------------' + * |Gui |Alt | Mb1 |Fn |Fn | + * `--------------------------------------------' + * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel + */ + [3] = \ + KEYMAP(GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + FN8, NO, NO, NO, NO, NO, WH_L,WH_D,MS_U,WH_U,WH_R,FN9, FN10,FN8, \ + LCTL,ACL0,ACL1,ACL2,ACL2,NO, NO, MS_L,MS_D,MS_R,FN3, NO, ENT, \ + LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,FN9, FN10,NO, RSFT,TRNS, \ + TRNS,LGUI,LALT, BTN1, TRNS,TRNS,TRNS,TRNS), + + /* Layer 4: Mouse mode(IJKL)[Space] + * ,-----------------------------------------------------------. + * |Esc| F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12|Ins|Del| + * |-----------------------------------------------------------| + * |Tab | | | | | |MwL|MwD|McU|MwU|MwR|Wbk|Wfr|Alt-T| + * |-----------------------------------------------------------| + * |Contro| | | | | |Mb2|McL|McD|McR|Mb1| |Return | + * |-----------------------------------------------------------| + * |Shift | | | | |Mb3|Mb2|Mb1|Mb4|Mb5| |Shift | | + * `-----------------------------------------------------------' + * |Gui |Alt | Mb1 |Fn |Fn | + * `--------------------------------------------' + * Mc: Mouse Cursor / Mb: Mouse Button / Mw: Mouse Wheel + */ + [4] = \ + KEYMAP(GRV, F1, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12, INS, DEL, \ + FN8, NO, NO, NO, NO, NO, WH_L,WH_D,MS_U,WH_U,WH_R,BTN4,BTN5,FN8, \ + LCTL,VOLD,VOLU,MUTE,NO, NO, NO, MS_L,MS_D,MS_R,BTN1,NO, ENT, \ + LSFT,NO, NO, NO, NO, BTN3,BTN2,BTN1,FN9, FN10,NO, RSFT,TRNS, \ + TRNS,LGUI,LALT, TRNS, TRNS,TRNS,TRNS,TRNS), + +}; + +/* id for user defined functions */ +enum function_id { + LSHIFT_LPAREN, +}; + +enum macro_id { + HELLO, + VOLUP, + ALT_TAB, +}; + +/* + * Fn action definition + */ +const uint16_t fn_actions[] = { + [0] = ACTION_DEFAULT_LAYER_SET(0), // Default layer(not used) + [1] = ACTION_LAYER_TAP_TOGGLE(1), // HHKB layer(toggle with 5 taps) + [2] = ACTION_LAYER_TAP_KEY(2, KC_SLASH), // Cursor layer with Slash* + [3] = ACTION_LAYER_TAP_KEY(3, KC_SCLN), // Mousekey layer with Semicolon* + [4] = ACTION_LAYER_TAP_KEY(4, KC_SPC), // Mousekey layer with Space + [5] = ACTION_LAYER_MOMENTARY(4), // Mousekey layer(IJKL) + [6] = ACTION_MODS_TAP_KEY(MOD_RCTL, KC_ENT), // RControl with tap Enter + [7] = ACTION_MODS_ONESHOT(MOD_LSFT), // Oneshot Shift + [8] = ACTION_MACRO(ALT_TAB), // Application switching + [9] = ACTION_MODS_KEY(MOD_LALT, KC_LEFT), + [10] = ACTION_MODS_KEY(MOD_LALT, KC_RIGHT), +}; + +/* + * Macro definition + */ +const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) +{ + switch (id) { + case HELLO: + return (record->event.pressed ? + MACRO( I(0), T(H), T(E), T(L), T(L), W(255), T(O), END ) : + MACRO_NONE ); + case VOLUP: + return (record->event.pressed ? + MACRO( D(VOLU), U(VOLU), END ) : + MACRO_NONE ); + case ALT_TAB: + return (record->event.pressed ? + MACRO( D(LALT), D(TAB), END ) : + MACRO( U(TAB), END )); + } + return MACRO_NONE; +} + + + +/* + * user defined action function + */ +void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) +{ + if (record->event.pressed) dprint("P"); else dprint("R"); + dprintf("%d", record->tap.count); + if (record->tap.interrupted) dprint("i"); + dprint("\n"); + + switch (id) { + case LSHIFT_LPAREN: + // Shift parentheses example: LShft + tap '(' + // http://stevelosh.com/blog/2012/10/a-modern-space-cadet/#shift-parentheses + // http://geekhack.org/index.php?topic=41989.msg1304899#msg1304899 + if (record->event.pressed) { + if (record->tap.count > 0 && !record->tap.interrupted) { + if (record->tap.interrupted) { + dprint("tap interrupted\n"); + register_mods(MOD_BIT(KC_LSHIFT)); + } + } else { + register_mods(MOD_BIT(KC_LSHIFT)); + } + } else { + if (record->tap.count > 0 && !(record->tap.interrupted)) { + add_weak_mods(MOD_BIT(KC_LSHIFT)); + send_keyboard_report(); + register_code(KC_9); + unregister_code(KC_9); + del_weak_mods(MOD_BIT(KC_LSHIFT)); + send_keyboard_report(); + record->tap.count = 0; // ad hoc: cancel tap + } else { + unregister_mods(MOD_BIT(KC_LSHIFT)); + } + } + break; + } +} diff --git a/keyboards/infinity_chibios/led.c b/keyboards/infinity_chibios/led.c new file mode 100644 index 0000000000..aed66c7c03 --- /dev/null +++ b/keyboards/infinity_chibios/led.c @@ -0,0 +1,24 @@ +/* +Copyright 2012 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 "hal.h" + +#include "led.h" + + +void led_set(uint8_t usb_led) { +} diff --git a/keyboards/infinity_chibios/matrix.c b/keyboards/infinity_chibios/matrix.c new file mode 100644 index 0000000000..2c68ea83ab --- /dev/null +++ b/keyboards/infinity_chibios/matrix.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include "hal.h" +#include "timer.h" +#include "wait.h" +#include "print.h" +#include "matrix.h" + + +/* + * Infinity Pinusage: + * Column pins are input with internal pull-down. Row pins are output and strobe with high. + * Key is high or 1 when it turns on. + * + * col: { PTD1, PTD2, PTD3, PTD4, PTD5, PTD6, PTD7 } + * row: { PTB0, PTB1, PTB2, PTB3, PTB16, PTB17, PTC4, PTC5, PTD0 } + */ +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; +static bool debouncing = false; +static uint16_t debouncing_time = 0; + + +void matrix_init(void) +{ + /* Column(sense) */ + palSetPadMode(GPIOD, 1, PAL_MODE_INPUT_PULLDOWN); + palSetPadMode(GPIOD, 2, PAL_MODE_INPUT_PULLDOWN); + palSetPadMode(GPIOD, 3, PAL_MODE_INPUT_PULLDOWN); + palSetPadMode(GPIOD, 4, PAL_MODE_INPUT_PULLDOWN); + palSetPadMode(GPIOD, 5, PAL_MODE_INPUT_PULLDOWN); + palSetPadMode(GPIOD, 6, PAL_MODE_INPUT_PULLDOWN); + palSetPadMode(GPIOD, 7, PAL_MODE_INPUT_PULLDOWN); + + /* Row(strobe) */ + palSetPadMode(GPIOB, 0, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(GPIOB, 1, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(GPIOB, 2, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(GPIOB, 3, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(GPIOB, 17, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(GPIOC, 4, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(GPIOC, 5, PAL_MODE_OUTPUT_PUSHPULL); + palSetPadMode(GPIOD, 0, PAL_MODE_OUTPUT_PUSHPULL); + + memset(matrix, 0, MATRIX_ROWS); + memset(matrix_debouncing, 0, MATRIX_ROWS); +} + +uint8_t matrix_scan(void) +{ + for (int row = 0; row < MATRIX_ROWS; row++) { + matrix_row_t data = 0; + + // strobe row + switch (row) { + case 0: palSetPad(GPIOB, 0); break; + case 1: palSetPad(GPIOB, 1); break; + case 2: palSetPad(GPIOB, 2); break; + case 3: palSetPad(GPIOB, 3); break; + case 4: palSetPad(GPIOB, 16); break; + case 5: palSetPad(GPIOB, 17); break; + case 6: palSetPad(GPIOC, 4); break; + case 7: palSetPad(GPIOC, 5); break; + case 8: palSetPad(GPIOD, 0); break; + } + + wait_us(1); // need wait to settle pin state + + // read col data + data = (palReadPort(GPIOD)>>1); + + // un-strobe row + switch (row) { + case 0: palClearPad(GPIOB, 0); break; + case 1: palClearPad(GPIOB, 1); break; + case 2: palClearPad(GPIOB, 2); break; + case 3: palClearPad(GPIOB, 3); break; + case 4: palClearPad(GPIOB, 16); break; + case 5: palClearPad(GPIOB, 17); break; + case 6: palClearPad(GPIOC, 4); break; + case 7: palClearPad(GPIOC, 5); break; + case 8: palClearPad(GPIOD, 0); break; + } + + if (matrix_debouncing[row] != data) { + matrix_debouncing[row] = data; + debouncing = true; + debouncing_time = timer_read(); + } + } + + if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) { + for (int row = 0; row < MATRIX_ROWS; row++) { + matrix[row] = matrix_debouncing[row]; + } + debouncing = false; + } + return 1; +} + +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & (1</os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) +MCU_FAMILY = STM32 +MCU_SERIES = STM32F0xx +# linker script to use +# it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ +# or /ld/ +MCU_LDSCRIPT = STM32F072xB +# startup code to use +# is should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ +MCU_STARTUP = stm32f0xx +# it should exist either in /os/hal/boards/ +# or /boards +BOARD = ST_STM32F072B_DISCOVERY +# Cortex version +# Teensy LC is cortex-m0; Teensy 3.x are cortex-m4 +MCU = cortex-m0 +# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 +ARMV = 6 +# If you want to be able to jump to bootloader from firmware on STM32 MCUs, +# set the correct BOOTLOADER_ADDRESS. Either set it here, or define it in +# ./bootloader_defs.h or in ./boards//bootloader_defs.h (if you have +# a custom board definition that you plan to reuse). +# If you're not setting it here, leave it commented out. +# It is chip dependent, the correct number can be looked up here (page 175): +# http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf +# This also requires a patch to chibios: +# /tmk_core/tool/chibios/ch-bootloader-jump.patch +#STM32_BOOTLOADER_ADDRESS = 0x1FFFC800 + +# Build Options +# comment out to disable the options. +# +#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration +MOUSEKEY_ENABLE ?= yes # Mouse keys +EXTRAKEY_ENABLE ?= yes # Audio control and System control +CONSOLE_ENABLE ?= yes # Console for debug +COMMAND_ENABLE ?= yes # Commands for debug and configuration +SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend +NKRO_ENABLE ?= yes # USB Nkey Rollover +CUSTOM_MATRIX ?= yes # Custom matrix file + +ifndef QUANTUM_DIR + include ../../Makefile +endif diff --git a/keyboards/stm32_f072_onekey/bootloader_defs.h b/keyboards/stm32_f072_onekey/bootloader_defs.h new file mode 100644 index 0000000000..02c48c4e6d --- /dev/null +++ b/keyboards/stm32_f072_onekey/bootloader_defs.h @@ -0,0 +1,7 @@ +/* Address for jumping to bootloader on STM32 chips. */ +/* It is chip dependent, the correct number can be looked up here (page 175): + * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf + * This also requires a patch to chibios: + * /tmk_core/tool/chibios/ch-bootloader-jump.patch + */ +#define STM32_BOOTLOADER_ADDRESS 0x1FFFC800 diff --git a/keyboards/stm32_f072_onekey/chconf.h b/keyboards/stm32_f072_onekey/chconf.h new file mode 100644 index 0000000000..99fa8ce398 --- /dev/null +++ b/keyboards/stm32_f072_onekey/chconf.h @@ -0,0 +1,524 @@ +/* + 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. +*/ + +/** + * @file templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16 or 32 bits. + */ +#define CH_CFG_ST_RESOLUTION 32 + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#define CH_CFG_ST_FREQUENCY 10000 + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#define CH_CFG_ST_TIMEDELTA 2 + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#define CH_CFG_TIME_QUANTUM 0 + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#define CH_CFG_MEMCORE_SIZE 0 + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#define CH_CFG_NO_IDLE_THREAD FALSE + +/* Use __WFI in the idle thread for waiting. Does lower the power + * consumption. */ +#define CORTEX_ENABLE_WFI_IDLE TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#define CH_CFG_OPTIMIZE_SPEED FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_TM FALSE + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_REGISTRY TRUE + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_WAITEXIT TRUE + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_SEMAPHORES TRUE + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MUTEXES TRUE + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_CONDVARS TRUE + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_EVENTS TRUE + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MESSAGES TRUE + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_MAILBOXES TRUE + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMCORE FALSE + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#define CH_CFG_USE_HEAP FALSE + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMPOOLS FALSE + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#define CH_CFG_USE_DYNAMIC FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_STATISTICS FALSE + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_SYSTEM_STATE_CHECK FALSE + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_CHECKS FALSE + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_ASSERTS FALSE + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_BUFFER_SIZE 128 + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#define CH_DBG_ENABLE_STACK_CHECK FALSE + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_FILL_THREADS FALSE + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#define CH_DBG_THREADS_PROFILING FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p chThdInit() API. + * + * @note It is invoked from within @p chThdInit() and implicitly from all + * the threads creation APIs. + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/keyboards/stm32_f072_onekey/config.h b/keyboards/stm32_f072_onekey/config.h new file mode 100644 index 0000000000..bb5251e1de --- /dev/null +++ b/keyboards/stm32_f072_onekey/config.h @@ -0,0 +1,76 @@ +/* +Copyright 2015 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 CONFIG_H +#define CONFIG_H + +#include "config_common.h" + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6464 +#define DEVICE_VER 0x0001 +/* in python2: list(u"whatever".encode('utf-16-le')) */ +/* at most 32 characters or the ugly hack in usb_main.c borks */ +#define MANUFACTURER "TMK" +#define USBSTR_MANUFACTURER 'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', '\xc6', '\x00' +#define PRODUCT "ChibiOS TMK test" +#define USBSTR_PRODUCT 'C', '\x00', 'h', '\x00', 'i', '\x00', 'b', '\x00', 'i', '\x00', 'O', '\x00', 'S', '\x00', ' ', '\x00', 'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', 't', '\x00', 'e', '\x00', 's', '\x00', 't', '\x00' +#define DESCRIPTION "TMK keyboard firmware over ChibiOS" + +/* key matrix size */ +#define MATRIX_ROWS 1 +#define MATRIX_COLS 1 +#define DIODE_DIRECTION COL2ROW + +/* define if matrix has ghost */ +//#define MATRIX_HAS_GHOST + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + + + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +#endif diff --git a/keyboards/stm32_f072_onekey/halconf.h b/keyboards/stm32_f072_onekey/halconf.h new file mode 100644 index 0000000000..1a450d6327 --- /dev/null +++ b/keyboards/stm32_f072_onekey/halconf.h @@ -0,0 +1,353 @@ +/* + 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. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef _HALCONF_H_ +#define _HALCONF_H_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EXT subsystem. + */ +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) +#define HAL_USE_EXT FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL FALSE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB TRUE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 64 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 64 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 256 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT TRUE +#endif + +#endif /* _HALCONF_H_ */ + +/** @} */ diff --git a/keyboards/stm32_f072_onekey/keymaps/default/keymap.c b/keyboards/stm32_f072_onekey/keymaps/default/keymap.c new file mode 100644 index 0000000000..6c48149f83 --- /dev/null +++ b/keyboards/stm32_f072_onekey/keymaps/default/keymap.c @@ -0,0 +1,25 @@ +/* +Copyright 2012,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 . +*/ + +#include "stm32_f072_onekey.h" + +const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + {{KC_CAPS}}, // test with KC_CAPS, KC_A, KC_BTLD +}; + +const uint16_t fn_actions[] = { +}; diff --git a/keyboards/stm32_f072_onekey/led.c b/keyboards/stm32_f072_onekey/led.c new file mode 100644 index 0000000000..18edb8ba89 --- /dev/null +++ b/keyboards/stm32_f072_onekey/led.c @@ -0,0 +1,34 @@ +/* +Copyright 2012 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 "hal.h" + +#include "led.h" + + +void led_set(uint8_t usb_led) +{ + (void)usb_led; + if (usb_led & (1< + +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 "ch.h" +#include "hal.h" + +/* + * scan matrix + */ +#include "print.h" +#include "debug.h" +#include "util.h" +#include "matrix.h" +#include "wait.h" + +#ifndef DEBOUNCE +# define DEBOUNCE 5 +#endif +static uint8_t debouncing = DEBOUNCE; + +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; + +static matrix_row_t read_cols(void); +static void init_cols(void); +static void unselect_rows(void); +static void select_row(uint8_t row); + + +inline +uint8_t matrix_rows(void) +{ + return MATRIX_ROWS; +} + +inline +uint8_t matrix_cols(void) +{ + return MATRIX_COLS; +} + +#define LED_ON() do { palSetPad(GPIOC, GPIOC_LED_BLUE) ;} while (0) +#define LED_OFF() do { palClearPad(GPIOC, GPIOC_LED_BLUE); } while (0) +#define LED_TGL() do { palTogglePad(GPIOC, GPIOC_LED_BLUE); } while (0) + +void matrix_init(void) +{ + // initialize row and col + unselect_rows(); + init_cols(); + + // initialize matrix state: all keys off + for (uint8_t i=0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + matrix_debouncing[i] = 0; + } + + //debug + debug_matrix = true; + LED_ON(); + wait_ms(500); + LED_OFF(); +} + +uint8_t matrix_scan(void) +{ + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + select_row(i); + wait_us(30); // without this wait read unstable value. + matrix_row_t cols = read_cols(); + if (matrix_debouncing[i] != cols) { + matrix_debouncing[i] = cols; + if (debouncing) { + debug("bounce!: "); debug_hex(debouncing); debug("\n"); + } + debouncing = DEBOUNCE; + } + unselect_rows(); + } + + if (debouncing) { + if (--debouncing) { + wait_ms(1); + } else { + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = matrix_debouncing[i]; + } + } + } + + return 1; +} + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1</os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) +MCU_FAMILY = STM32 +MCU_SERIES = STM32F1xx +# linker script to use +# it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ +# or /ld/ +# startup code to use +# is should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ +MCU_STARTUP = stm32f1xx +# it should exist either in /os/hal/boards/ +# or /boards +# Cortex version +# Teensy LC is cortex-m0; Teensy 3.x are cortex-m4 +MCU = cortex-m3 +# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 +ARMV = 7 +# If you want to be able to jump to bootloader from firmware on STM32 MCUs, +# set the correct BOOTLOADER_ADDRESS. Either set it here, or define it in +# ./bootloader_defs.h or in ./boards//bootloader_defs.h (if you have +# a custom board definition that you plan to reuse). +# If you're not setting it here, leave it commented out. +# It is chip dependent, the correct number can be looked up here (page 175): +# http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf +# This also requires a patch to chibios: +# /tmk_core/tool/chibios/ch-bootloader-jump.patch +#STM32_BOOTLOADER_ADDRESS = 0x1FFFC800 + +# Build Options +# comment out to disable the options. +# +#BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration +## BOOTMAGIC is not supported on STM32 chips yet. +MOUSEKEY_ENABLE ?= yes # Mouse keys +EXTRAKEY_ENABLE ?= yes # Audio control and System control +# CONSOLE_ENABLE ?= yes # Console for debug +COMMAND_ENABLE ?= yes # Commands for debug and configuration +SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend +NKRO_ENABLE ?= yes # USB Nkey Rollover +CUSTOM_MATRIX ?= yes # Custom matrix file + +ifndef QUANTUM_DIR + include ../../Makefile +endif diff --git a/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.c b/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.c new file mode 100644 index 0000000000..31319ef575 --- /dev/null +++ b/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.c @@ -0,0 +1,49 @@ +/* + 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" + +/** + * @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) { +} diff --git a/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.h b/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.h new file mode 100644 index 0000000000..7253e77826 --- /dev/null +++ b/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/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_GENERIC_STM32_F103 +#define BOARD_NAME "Generic STM32F103x board" + +/* + * 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 GPIOC_LED 13 +#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/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.mk b/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.mk new file mode 100644 index 0000000000..d692c0ee46 --- /dev/null +++ b/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/board.mk @@ -0,0 +1,5 @@ +# List of all the board related files. +BOARDSRC = $(KEYBOARD_PATH)/boards/GENERIC_STM32_F103/board.c + +# Required include directories +BOARDINC = $(KEYBOARD_PATH)/boards/GENERIC_STM32_F103 diff --git a/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/mini_stm32_mapping.png b/keyboards/stm32_f103_onekey/boards/GENERIC_STM32_F103/mini_stm32_mapping.png new file mode 100644 index 0000000000000000000000000000000000000000..c44a7d9ebcbf5f50ce5ad9a191bcf50cae2b2522 GIT binary patch literal 162908 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%0AV=h$@w01c8Eossb4Iiu7eyPPT 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 QCQyWXy85}Sb4q9e0Fq%&%>V!Z literal 0 HcmV?d00001 diff --git a/keyboards/stm32_f103_onekey/boards/maple_mini_mapping.png b/keyboards/stm32_f103_onekey/boards/maple_mini_mapping.png new file mode 100644 index 0000000000000000000000000000000000000000..12cfa81db26dd38fb16c80ad58c2e7a073957a6c GIT binary patch literal 237977 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

x-0S}Ry=m&38=TG6X>+3E7G6Df>7Vj>-RF~Z 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

bkY?J`4KLhbd6iNW!Be!S*arOp*|LWQod-=5y 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 iglC$Qz!wJKHr5TlXEWX+YN3!0SqU_In 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 |d0OO|GkOz_Zt?l1uDs%Q*BizNS>4C;U5igE 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 literal 0 HcmV?d00001 diff --git a/keyboards/stm32_f103_onekey/bootloader_defs.h b/keyboards/stm32_f103_onekey/bootloader_defs.h new file mode 100644 index 0000000000..0f45203cb6 --- /dev/null +++ b/keyboards/stm32_f103_onekey/bootloader_defs.h @@ -0,0 +1,10 @@ +/* Address for jumping to bootloader on STM32 chips. */ +/* It is chip dependent, the correct number can be looked up here (page 175): + * http://www.st.com/web/en/resource/technical/document/application_note/CD00167594.pdf + * This also requires a patch to chibios: + * /tmk_core/tool/chibios/ch-bootloader-jump.patch + */ + +// STM32F103* does NOT have an USB bootloader in ROM (only serial), +// so setting anything here does not make much sense +// #define STM32_BOOTLOADER_ADDRESS 0x1FFFC800 diff --git a/keyboards/stm32_f103_onekey/chconf.h b/keyboards/stm32_f103_onekey/chconf.h new file mode 100644 index 0000000000..dfb1f9dfb9 --- /dev/null +++ b/keyboards/stm32_f103_onekey/chconf.h @@ -0,0 +1,524 @@ +/* + 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. +*/ + +/** + * @file templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16 or 32 bits. + */ +#define CH_CFG_ST_RESOLUTION 16 + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#define CH_CFG_ST_FREQUENCY 2000 + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#define CH_CFG_ST_TIMEDELTA 2 + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#define CH_CFG_TIME_QUANTUM 0 + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#define CH_CFG_MEMCORE_SIZE 0 + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#define CH_CFG_NO_IDLE_THREAD FALSE + +/* Use __WFI in the idle thread for waiting. Does lower the power + * consumption. */ +#define CORTEX_ENABLE_WFI_IDLE TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#define CH_CFG_OPTIMIZE_SPEED TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_TM FALSE + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_REGISTRY TRUE + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_WAITEXIT TRUE + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_SEMAPHORES TRUE + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MUTEXES TRUE + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_CONDVARS TRUE + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#define CH_CFG_USE_CONDVARS_TIMEOUT FALSE + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_EVENTS TRUE + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MESSAGES TRUE + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_MAILBOXES TRUE + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMCORE TRUE + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#define CH_CFG_USE_HEAP TRUE + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMPOOLS FALSE + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#define CH_CFG_USE_DYNAMIC FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_STATISTICS FALSE + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_SYSTEM_STATE_CHECK FALSE + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_CHECKS FALSE + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_ASSERTS FALSE + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_BUFFER_SIZE 128 + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#define CH_DBG_ENABLE_STACK_CHECK FALSE + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_FILL_THREADS FALSE + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#define CH_DBG_THREADS_PROFILING FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p chThdInit() API. + * + * @note It is invoked from within @p chThdInit() and implicitly from all + * the threads creation APIs. + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/keyboards/stm32_f103_onekey/config.h b/keyboards/stm32_f103_onekey/config.h new file mode 100644 index 0000000000..19b14fe61a --- /dev/null +++ b/keyboards/stm32_f103_onekey/config.h @@ -0,0 +1,75 @@ +/* +Copyright 2015 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 CONFIG_H +#define CONFIG_H + + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6464 +#define DEVICE_VER 0x0001 +/* in python2: list(u"whatever".encode('utf-16-le')) */ +/* at most 32 characters or the ugly hack in usb_main.c borks */ +#define MANUFACTURER "TMK" +#define USBSTR_MANUFACTURER 'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', '\xc6', '\x00' +#define PRODUCT "ChibiOS TMK test" +#define USBSTR_PRODUCT 'C', '\x00', 'h', '\x00', 'i', '\x00', 'b', '\x00', 'i', '\x00', 'O', '\x00', 'S', '\x00', ' ', '\x00', 'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', 't', '\x00', 'e', '\x00', 's', '\x00', 't', '\x00' +#define DESCRIPTION "TMK keyboard firmware over ChibiOS" + +/* key matrix size */ +#define MATRIX_ROWS 1 +#define MATRIX_COLS 1 +#define DIODE_DIRECTION COL2ROW + +/* define if matrix has ghost */ +//#define MATRIX_HAS_GHOST + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + + + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +#endif diff --git a/keyboards/stm32_f103_onekey/flash.sh b/keyboards/stm32_f103_onekey/flash.sh new file mode 100755 index 0000000000..15501dfa57 --- /dev/null +++ b/keyboards/stm32_f103_onekey/flash.sh @@ -0,0 +1,2 @@ +#!/bin/bash +Arduino_STM32_usb_hid/tools/linux/maple_upload ttyACM0 2 1EAF:0003 build/ch.bin diff --git a/keyboards/stm32_f103_onekey/halconf.h b/keyboards/stm32_f103_onekey/halconf.h new file mode 100644 index 0000000000..1a450d6327 --- /dev/null +++ b/keyboards/stm32_f103_onekey/halconf.h @@ -0,0 +1,353 @@ +/* + 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. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef _HALCONF_H_ +#define _HALCONF_H_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EXT subsystem. + */ +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) +#define HAL_USE_EXT FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL FALSE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB TRUE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/*===========================================================================*/ +/* ADC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_WAIT) || defined(__DOXYGEN__) +#define ADC_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p adcAcquireBus() and @p adcReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(ADC_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define ADC_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* CAN driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Sleep mode related APIs inclusion switch. + */ +#if !defined(CAN_USE_SLEEP_MODE) || defined(__DOXYGEN__) +#define CAN_USE_SLEEP_MODE TRUE +#endif + +/*===========================================================================*/ +/* I2C driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables the mutual exclusion APIs on the I2C bus. + */ +#if !defined(I2C_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define I2C_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* MAC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif + +/*===========================================================================*/ +/* MMC_SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + * This option is recommended also if the SPI driver does not + * use a DMA channel and heavily loads the CPU. + */ +#if !defined(MMC_NICE_WAITING) || defined(__DOXYGEN__) +#define MMC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SDC driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Number of initialization attempts before rejecting the card. + * @note Attempts are performed at 10mS intervals. + */ +#if !defined(SDC_INIT_RETRY) || defined(__DOXYGEN__) +#define SDC_INIT_RETRY 100 +#endif + +/** + * @brief Include support for MMC cards. + * @note MMC support is not yet implemented so this option must be kept + * at @p FALSE. + */ +#if !defined(SDC_MMC_SUPPORT) || defined(__DOXYGEN__) +#define SDC_MMC_SUPPORT FALSE +#endif + +/** + * @brief Delays insertions. + * @details If enabled this options inserts delays into the MMC waiting + * routines releasing some extra CPU time for the threads with + * lower priority, this may slow down the driver a bit however. + */ +#if !defined(SDC_NICE_WAITING) || defined(__DOXYGEN__) +#define SDC_NICE_WAITING TRUE +#endif + +/*===========================================================================*/ +/* SERIAL driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Default bit rate. + * @details Configuration parameter, this is the baud rate selected for the + * default configuration. + */ +#if !defined(SERIAL_DEFAULT_BITRATE) || defined(__DOXYGEN__) +#define SERIAL_DEFAULT_BITRATE 38400 +#endif + +/** + * @brief Serial buffers size. + * @details Configuration parameter, you can change the depth of the queue + * buffers depending on the requirements of your application. + * @note The default is 64 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_BUFFERS_SIZE 16 +#endif + +/*===========================================================================*/ +/* SERIAL_USB driver related setting. */ +/*===========================================================================*/ + +/** + * @brief Serial over USB buffers size. + * @details Configuration parameter, the buffer size must be a multiple of + * the USB data endpoint maximum packet size. + * @note The default is 64 bytes for both the transmission and receive + * buffers. + */ +#if !defined(SERIAL_USB_BUFFERS_SIZE) || defined(__DOXYGEN__) +#define SERIAL_USB_BUFFERS_SIZE 256 +#endif + +/*===========================================================================*/ +/* SPI driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_WAIT) || defined(__DOXYGEN__) +#define SPI_USE_WAIT TRUE +#endif + +/** + * @brief Enables the @p spiAcquireBus() and @p spiReleaseBus() APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(SPI_USE_MUTUAL_EXCLUSION) || defined(__DOXYGEN__) +#define SPI_USE_MUTUAL_EXCLUSION TRUE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT TRUE +#endif + +#endif /* _HALCONF_H_ */ + +/** @} */ diff --git a/keyboards/stm32_f103_onekey/keymaps/default/keymap.c b/keyboards/stm32_f103_onekey/keymaps/default/keymap.c new file mode 100644 index 0000000000..c3b0f08403 --- /dev/null +++ b/keyboards/stm32_f103_onekey/keymaps/default/keymap.c @@ -0,0 +1,25 @@ +/* +Copyright 2012,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 . +*/ + +#include "stm32_f103_onekey.h" + +const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + {{KC_CAPS}}, // test with KC_CAPS, KC_A, KC_BTLD +}; + +const uint16_t fn_actions[] = { +}; diff --git a/keyboards/stm32_f103_onekey/ld/STM32F103x8_stm32duino_bootloader.ld b/keyboards/stm32_f103_onekey/ld/STM32F103x8_stm32duino_bootloader.ld new file mode 100644 index 0000000000..00613328ed --- /dev/null +++ b/keyboards/stm32_f103_onekey/ld/STM32F103x8_stm32duino_bootloader.ld @@ -0,0 +1,88 @@ +/* + 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. +*/ + +/* + * ST32F103xB memory setup for use with the maplemini bootloader. + * You will have to + * #define CORTEX_VTOR_INIT 0x5000 + * in your projects chconf.h + */ +MEMORY +{ + flash0 : org = 0x08002000, len = 128k - 0x2000 + 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 diff --git a/keyboards/stm32_f103_onekey/led.c b/keyboards/stm32_f103_onekey/led.c new file mode 100644 index 0000000000..f5c55f7d9b --- /dev/null +++ b/keyboards/stm32_f103_onekey/led.c @@ -0,0 +1,43 @@ +/* +Copyright 2012 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 "hal.h" +#include "led.h" + + +void led_set(uint8_t usb_led) +{ + if (usb_led & (1< + +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 "ch.h" +#include "hal.h" + +/* + * scan matrix + */ +#include "print.h" +#include "debug.h" +#include "util.h" +#include "matrix.h" +#include "wait.h" + +#ifndef DEBOUNCE +# define DEBOUNCE 5 +#endif +static uint8_t debouncing = DEBOUNCE; + +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; + +static matrix_row_t read_cols(void); +static void init_cols(void); +static void unselect_rows(void); +static void select_row(uint8_t row); + + +inline +uint8_t matrix_rows(void) +{ + return MATRIX_ROWS; +} + +inline +uint8_t matrix_cols(void) +{ + return MATRIX_COLS; +} + +/* generic STM32F103C8T6 board */ +#ifdef BOARD_GENERIC_STM32_F103 +#define LED_ON() do { palClearPad(GPIOC, GPIOC_LED) ;} while (0) +#define LED_OFF() do { palSetPad(GPIOC, GPIOC_LED); } while (0) +#define LED_TGL() do { palTogglePad(GPIOC, GPIOC_LED); } while (0) +#endif + +/* Maple Mini */ +#ifdef BOARD_MAPLEMINI_STM32_F103 +#define LED_ON() do { palSetPad(GPIOB, 1) ;} while (0) +#define LED_OFF() do { palClearPad(GPIOB, 1); } while (0) +#define LED_TGL() do { palTogglePad(GPIOB, 1); } while (0) +#endif + +void matrix_init(void) +{ + // initialize row and col + unselect_rows(); + init_cols(); + + // initialize matrix state: all keys off + for (uint8_t i=0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + matrix_debouncing[i] = 0; + } + + //debug + debug_matrix = true; + LED_ON(); + wait_ms(500); + LED_OFF(); +} + +uint8_t matrix_scan(void) +{ + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + select_row(i); + wait_us(30); // without this wait read unstable value. + matrix_row_t cols = read_cols(); + if (matrix_debouncing[i] != cols) { + matrix_debouncing[i] = cols; + if (debouncing) { + debug("bounce!: "); debug_hex(debouncing); debug("\n"); + } + debouncing = DEBOUNCE; + } + unselect_rows(); + } + + if (debouncing) { + if (--debouncing) { + wait_ms(1); + } else { + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = matrix_debouncing[i]; + } + } + } + + return 1; +} + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1</os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) +# - For Teensies, FAMILY = KINETIS and SERIES is either +# KL2x (LC) or K20x (3.0,3.1,3.2). +MCU_FAMILY = KINETIS +MCU_SERIES = KL2x + +# Linker script to use +# - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ +# or /ld/ +# - NOTE: a custom ld script is needed for EEPROM on Teensy LC +# - LDSCRIPT = +# - MKL26Z64 for Teensy LC +# - MK20DX128 for Teensy 3.0 +# - MK20DX256 for Teensy 3.1 and 3.2 +MCU_LDSCRIPT = MKL26Z64 + +# Startup code to use +# - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ +# - STARTUP = +# - kl2x for Teensy LC +# - k20x5 for Teensy 3.0 +# - k20x7 for Teensy 3.1 and 3.2 +MCU_STARTUP = kl2x + +# Board: it should exist either in /os/hal/boards/ +# or /boards +# - BOARD = +# - PJRC_TEENSY_LC for Teensy LC +# - PJRC_TEENSY_3 for Teensy 3.0 +# - PJRC_TEENSY_3_1 for Teensy 3.1 or 3.2 +BOARD = PJRC_TEENSY_LC + +# Cortex version +# Teensy LC is cortex-m0plus; Teensy 3.x are cortex-m4 +MCU = cortex-m0plus + +# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 +# I.e. 6 for Teensy LC; 7 for Teensy 3.x +ARMV = 6 + +# Build Options +# comment out to disable the options. +# +BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration +## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.) +MOUSEKEY_ENABLE ?= yes # Mouse keys +EXTRAKEY_ENABLE ?= yes # Audio control and System control +CONSOLE_ENABLE ?= yes # Console for debug +COMMAND_ENABLE ?= yes # Commands for debug and configuration +SLEEP_LED_ENABLE ?= yes # Breathing sleep LED during USB suspend +NKRO_ENABLE ?= yes # USB Nkey Rollover +CUSTOM_MATRIX ?= yes # Custom matrix file + +ifndef QUANTUM_DIR + include ../../Makefile +endif diff --git a/keyboards/teensy_lc_onekey/Makefile.3.0 b/keyboards/teensy_lc_onekey/Makefile.3.0 new file mode 100644 index 0000000000..dbf12c3631 --- /dev/null +++ b/keyboards/teensy_lc_onekey/Makefile.3.0 @@ -0,0 +1,77 @@ +# Target file name (without extension). +PROJECT = ch + +# Directory common source files exist +TMK_DIR = ../../tmk_core + +# Directory keyboard dependent files exist +TARGET_DIR = . + +# project specific files +SRC = matrix.c \ + led.c + +ifdef KEYMAP + SRC := keymap_$(KEYMAP).c $(SRC) +else + SRC := keymap_plain.c $(SRC) +endif + +CONFIG_H = config.h + +## chip/board settings +# - the next two should match the directories in +# /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) +# - For Teensies, FAMILY = KINETIS and SERIES is either +# KL2x (LC) or K20x (3.0,3.1,3.2). +MCU_FAMILY = KINETIS +MCU_SERIES = K20x + +# Linker script to use +# - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ +# or /ld/ +# - NOTE: a custom ld script is needed for EEPROM on Teensy LC +# - LDSCRIPT = +# - MKL26Z64 for Teensy LC +# - MK20DX128 for Teensy 3.0 +# - MK20DX256 for Teensy 3.1 and 3.2 +MCU_LDSCRIPT = MK20DX128 + +# Startup code to use +# - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ +# - STARTUP = +# - kl2x for Teensy LC +# - k20x5 for Teensy 3.0 +# - k20x7 for Teensy 3.1 and 3.2 +MCU_STARTUP = k20x5 + +# Board: it should exist either in /os/hal/boards/ +# or /boards +# - BOARD = +# - PJRC_TEENSY_LC for Teensy LC +# - PJRC_TEENSY_3 for Teensy 3.0 +# - PJRC_TEENSY_3_1 for Teensy 3.1 or 3.2 +BOARD = PJRC_TEENSY_3 + +# Cortex version +# Teensy LC is cortex-m0; Teensy 3.x are cortex-m4 +MCU = cortex-m4 + +# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 +# I.e. 6 for Teensy LC; 7 for Teensy 3.x +ARMV = 7 + +# Build Options +# comment out to disable the options. +# +BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration +## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.) +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = yes # Console for debug +COMMAND_ENABLE = yes # Commands for debug and configuration +SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend +NKRO_ENABLE = yes # USB Nkey Rollover + +include $(TMK_DIR)/tool/chibios/common.mk +include $(TMK_DIR)/tool/chibios/chibios.mk diff --git a/keyboards/teensy_lc_onekey/Makefile.3.2 b/keyboards/teensy_lc_onekey/Makefile.3.2 new file mode 100644 index 0000000000..41bfa41a0c --- /dev/null +++ b/keyboards/teensy_lc_onekey/Makefile.3.2 @@ -0,0 +1,77 @@ +# Target file name (without extension). +PROJECT = ch + +# Directory common source files exist +TMK_DIR = ../../tmk_core + +# Directory keyboard dependent files exist +TARGET_DIR = . + +# project specific files +SRC = matrix.c \ + led.c + +ifdef KEYMAP + SRC := keymap_$(KEYMAP).c $(SRC) +else + SRC := keymap_plain.c $(SRC) +endif + +CONFIG_H = config.h + +## chip/board settings +# - the next two should match the directories in +# /os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES) +# - For Teensies, FAMILY = KINETIS and SERIES is either +# KL2x (LC) or K20x (3.0,3.1,3.2). +MCU_FAMILY = KINETIS +MCU_SERIES = K20x + +# Linker script to use +# - it should exist either in /os/common/ports/ARMCMx/compilers/GCC/ld/ +# or /ld/ +# - NOTE: a custom ld script is needed for EEPROM on Teensy LC +# - LDSCRIPT = +# - MKL26Z64 for Teensy LC +# - MK20DX128 for Teensy 3.0 +# - MK20DX256 for Teensy 3.1 and 3.2 +MCU_LDSCRIPT = MK20DX256 + +# Startup code to use +# - it should exist in /os/common/ports/ARMCMx/compilers/GCC/mk/ +# - STARTUP = +# - kl2x for Teensy LC +# - k20x5 for Teensy 3.0 +# - k20x7 for Teensy 3.1 and 3.2 +MCU_STARTUP = k20x7 + +# Board: it should exist either in /os/hal/boards/ +# or /boards +# - BOARD = +# - PJRC_TEENSY_LC for Teensy LC +# - PJRC_TEENSY_3 for Teensy 3.0 +# - PJRC_TEENSY_3_1 for Teensy 3.1 or 3.2 +BOARD = PJRC_TEENSY_3_1 + +# Cortex version +# Teensy LC is cortex-m0; Teensy 3.x are cortex-m4 +MCU = cortex-m4 + +# ARM version, CORTEX-M0/M1 are 6, CORTEX-M3/M4/M7 are 7 +# I.e. 6 for Teensy LC; 7 for Teensy 3.x +ARMV = 7 + +# Build Options +# comment out to disable the options. +# +BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration +## (Note that for BOOTMAGIC on Teensy LC you have to use a custom .ld script.) +MOUSEKEY_ENABLE = yes # Mouse keys +EXTRAKEY_ENABLE = yes # Audio control and System control +CONSOLE_ENABLE = yes # Console for debug +COMMAND_ENABLE = yes # Commands for debug and configuration +SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend +NKRO_ENABLE = yes # USB Nkey Rollover + +include $(TMK_DIR)/tool/chibios/common.mk +include $(TMK_DIR)/tool/chibios/chibios.mk diff --git a/keyboards/teensy_lc_onekey/chconf.h b/keyboards/teensy_lc_onekey/chconf.h new file mode 100644 index 0000000000..cb36996c33 --- /dev/null +++ b/keyboards/teensy_lc_onekey/chconf.h @@ -0,0 +1,524 @@ +/* + 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. +*/ + +/** + * @file templates/chconf.h + * @brief Configuration file template. + * @details A copy of this file must be placed in each project directory, it + * contains the application specific kernel settings. + * + * @addtogroup config + * @details Kernel related settings and hooks. + * @{ + */ + +#ifndef CHCONF_H +#define CHCONF_H + +#define _CHIBIOS_RT_CONF_ + +/*===========================================================================*/ +/** + * @name System timers settings + * @{ + */ +/*===========================================================================*/ + +/** + * @brief System time counter resolution. + * @note Allowed values are 16 or 32 bits. + */ +#define CH_CFG_ST_RESOLUTION 32 + +/** + * @brief System tick frequency. + * @details Frequency of the system timer that drives the system ticks. This + * setting also defines the system tick time unit. + */ +#define CH_CFG_ST_FREQUENCY 1000 + +/** + * @brief Time delta constant for the tick-less mode. + * @note If this value is zero then the system uses the classic + * periodic tick. This value represents the minimum number + * of ticks that is safe to specify in a timeout directive. + * The value one is not valid, timeouts are rounded up to + * this value. + */ +#define CH_CFG_ST_TIMEDELTA 0 + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel parameters and options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Round robin interval. + * @details This constant is the number of system ticks allowed for the + * threads before preemption occurs. Setting this value to zero + * disables the preemption for threads with equal priority and the + * round robin becomes cooperative. Note that higher priority + * threads can still preempt, the kernel is always preemptive. + * @note Disabling the round robin preemption makes the kernel more compact + * and generally faster. + * @note The round robin preemption is not supported in tickless mode and + * must be set to zero in that case. + */ +#define CH_CFG_TIME_QUANTUM 20 + +/** + * @brief Managed RAM size. + * @details Size of the RAM area to be managed by the OS. If set to zero + * then the whole available RAM is used. The core memory is made + * available to the heap allocator and/or can be used directly through + * the simplified core memory allocator. + * + * @note In order to let the OS manage the whole RAM the linker script must + * provide the @p __heap_base__ and @p __heap_end__ symbols. + * @note Requires @p CH_CFG_USE_MEMCORE. + */ +#define CH_CFG_MEMCORE_SIZE 0 + +/** + * @brief Idle thread automatic spawn suppression. + * @details When this option is activated the function @p chSysInit() + * does not spawn the idle thread. The application @p main() + * function becomes the idle thread and must implement an + * infinite loop. + */ +#define CH_CFG_NO_IDLE_THREAD FALSE + +/* Use __WFI in the idle thread for waiting. Does lower the power + * consumption. */ +#define CORTEX_ENABLE_WFI_IDLE TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Performance options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief OS optimization. + * @details If enabled then time efficient rather than space efficient code + * is used when two possible implementations exist. + * + * @note This is not related to the compiler optimization options. + * @note The default is @p TRUE. + */ +#define CH_CFG_OPTIMIZE_SPEED TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Subsystem options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Time Measurement APIs. + * @details If enabled then the time measurement APIs are included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_TM FALSE + +/** + * @brief Threads registry APIs. + * @details If enabled then the registry APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_REGISTRY TRUE + +/** + * @brief Threads synchronization APIs. + * @details If enabled then the @p chThdWait() function is included in + * the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_WAITEXIT TRUE + +/** + * @brief Semaphores APIs. + * @details If enabled then the Semaphores APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_SEMAPHORES TRUE + +/** + * @brief Semaphores queuing mode. + * @details If enabled then the threads are enqueued on semaphores by + * priority rather than in FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_SEMAPHORES_PRIORITY FALSE + +/** + * @brief Mutexes APIs. + * @details If enabled then the mutexes APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MUTEXES TRUE + +/** + * @brief Enables recursive behavior on mutexes. + * @note Recursive mutexes are heavier and have an increased + * memory footprint. + * + * @note The default is @p FALSE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_MUTEXES_RECURSIVE FALSE + +/** + * @brief Conditional Variables APIs. + * @details If enabled then the conditional variables APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MUTEXES. + */ +#define CH_CFG_USE_CONDVARS TRUE + +/** + * @brief Conditional Variables APIs with timeout. + * @details If enabled then the conditional variables APIs with timeout + * specification are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_CONDVARS. + */ +#define CH_CFG_USE_CONDVARS_TIMEOUT TRUE + +/** + * @brief Events Flags APIs. + * @details If enabled then the event flags APIs are included in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_EVENTS TRUE + +/** + * @brief Events Flags APIs with timeout. + * @details If enabled then the events APIs with timeout specification + * are included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_EVENTS. + */ +#define CH_CFG_USE_EVENTS_TIMEOUT TRUE + +/** + * @brief Synchronous Messages APIs. + * @details If enabled then the synchronous messages APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MESSAGES TRUE + +/** + * @brief Synchronous Messages queuing mode. + * @details If enabled then messages are served by priority rather than in + * FIFO order. + * + * @note The default is @p FALSE. Enable this if you have special + * requirements. + * @note Requires @p CH_CFG_USE_MESSAGES. + */ +#define CH_CFG_USE_MESSAGES_PRIORITY FALSE + +/** + * @brief Mailboxes APIs. + * @details If enabled then the asynchronous messages (mailboxes) APIs are + * included in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_SEMAPHORES. + */ +#define CH_CFG_USE_MAILBOXES TRUE + +/** + * @brief Core Memory Manager APIs. + * @details If enabled then the core memory manager APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMCORE TRUE + +/** + * @brief Heap Allocator APIs. + * @details If enabled then the memory heap allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_MEMCORE and either @p CH_CFG_USE_MUTEXES or + * @p CH_CFG_USE_SEMAPHORES. + * @note Mutexes are recommended. + */ +#define CH_CFG_USE_HEAP TRUE + +/** + * @brief Memory Pools Allocator APIs. + * @details If enabled then the memory pools allocator APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + */ +#define CH_CFG_USE_MEMPOOLS TRUE + +/** + * @brief Dynamic Threads APIs. + * @details If enabled then the dynamic threads creation APIs are included + * in the kernel. + * + * @note The default is @p TRUE. + * @note Requires @p CH_CFG_USE_WAITEXIT. + * @note Requires @p CH_CFG_USE_HEAP and/or @p CH_CFG_USE_MEMPOOLS. + */ +#define CH_CFG_USE_DYNAMIC TRUE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Debug options + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Debug option, kernel statistics. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_STATISTICS FALSE + +/** + * @brief Debug option, system state check. + * @details If enabled the correct call protocol for system APIs is checked + * at runtime. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_SYSTEM_STATE_CHECK TRUE + +/** + * @brief Debug option, parameters checks. + * @details If enabled then the checks on the API functions input + * parameters are activated. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_CHECKS TRUE + +/** + * @brief Debug option, consistency checks. + * @details If enabled then all the assertions in the kernel code are + * activated. This includes consistency checks inside the kernel, + * runtime anomalies and port-defined checks. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_ENABLE_ASSERTS TRUE + +/** + * @brief Debug option, trace buffer. + * @details If enabled then the trace buffer is activated. + * + * @note The default is @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_MASK CH_DBG_TRACE_MASK_DISABLED + +/** + * @brief Trace buffer entries. + * @note The trace buffer is only allocated if @p CH_DBG_TRACE_MASK is + * different from @p CH_DBG_TRACE_MASK_DISABLED. + */ +#define CH_DBG_TRACE_BUFFER_SIZE 128 + +/** + * @brief Debug option, stack checks. + * @details If enabled then a runtime stack check is performed. + * + * @note The default is @p FALSE. + * @note The stack check is performed in a architecture/port dependent way. + * It may not be implemented or some ports. + * @note The default failure mode is to halt the system with the global + * @p panic_msg variable set to @p NULL. + */ +#define CH_DBG_ENABLE_STACK_CHECK TRUE + +/** + * @brief Debug option, stacks initialization. + * @details If enabled then the threads working area is filled with a byte + * value when a thread is created. This can be useful for the + * runtime measurement of the used stack. + * + * @note The default is @p FALSE. + */ +#define CH_DBG_FILL_THREADS TRUE + +/** + * @brief Debug option, threads profiling. + * @details If enabled then a field is added to the @p thread_t structure that + * counts the system ticks occurred while executing the thread. + * + * @note The default is @p FALSE. + * @note This debug option is not currently compatible with the + * tickless mode. + */ +#define CH_DBG_THREADS_PROFILING FALSE + +/** @} */ + +/*===========================================================================*/ +/** + * @name Kernel hooks + * @{ + */ +/*===========================================================================*/ + +/** + * @brief Threads descriptor structure extension. + * @details User fields added to the end of the @p thread_t structure. + */ +#define CH_CFG_THREAD_EXTRA_FIELDS \ + /* Add threads custom fields here.*/ + +/** + * @brief Threads initialization hook. + * @details User initialization code added to the @p chThdInit() API. + * + * @note It is invoked from within @p chThdInit() and implicitly from all + * the threads creation APIs. + */ +#define CH_CFG_THREAD_INIT_HOOK(tp) { \ + /* Add threads initialization code here.*/ \ +} + +/** + * @brief Threads finalization hook. + * @details User finalization code added to the @p chThdExit() API. + */ +#define CH_CFG_THREAD_EXIT_HOOK(tp) { \ + /* Add threads finalization code here.*/ \ +} + +/** + * @brief Context switch hook. + * @details This hook is invoked just before switching between threads. + */ +#define CH_CFG_CONTEXT_SWITCH_HOOK(ntp, otp) { \ + /* Context switch code here.*/ \ +} + +/** + * @brief ISR enter hook. + */ +#define CH_CFG_IRQ_PROLOGUE_HOOK() { \ + /* IRQ prologue code here.*/ \ +} + +/** + * @brief ISR exit hook. + */ +#define CH_CFG_IRQ_EPILOGUE_HOOK() { \ + /* IRQ epilogue code here.*/ \ +} + +/** + * @brief Idle thread enter hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to activate a power saving mode. + */ +#define CH_CFG_IDLE_ENTER_HOOK() { \ + /* Idle-enter code here.*/ \ +} + +/** + * @brief Idle thread leave hook. + * @note This hook is invoked within a critical zone, no OS functions + * should be invoked from here. + * @note This macro can be used to deactivate a power saving mode. + */ +#define CH_CFG_IDLE_LEAVE_HOOK() { \ + /* Idle-leave code here.*/ \ +} + +/** + * @brief Idle Loop hook. + * @details This hook is continuously invoked by the idle thread loop. + */ +#define CH_CFG_IDLE_LOOP_HOOK() { \ + /* Idle loop code here.*/ \ +} + +/** + * @brief System tick event hook. + * @details This hook is invoked in the system tick handler immediately + * after processing the virtual timers queue. + */ +#define CH_CFG_SYSTEM_TICK_HOOK() { \ + /* System tick event code here.*/ \ +} + +/** + * @brief System halt hook. + * @details This hook is invoked in case to a system halting error before + * the system is halted. + */ +#define CH_CFG_SYSTEM_HALT_HOOK(reason) { \ + /* System halt code here.*/ \ +} + +/** + * @brief Trace hook. + * @details This hook is invoked each time a new record is written in the + * trace buffer. + */ +#define CH_CFG_TRACE_HOOK(tep) { \ + /* Trace code here.*/ \ +} + +/** @} */ + +/*===========================================================================*/ +/* Port-specific settings (override port settings defaulted in chcore.h). */ +/*===========================================================================*/ + +#endif /* CHCONF_H */ + +/** @} */ diff --git a/keyboards/teensy_lc_onekey/config.h b/keyboards/teensy_lc_onekey/config.h new file mode 100644 index 0000000000..19b14fe61a --- /dev/null +++ b/keyboards/teensy_lc_onekey/config.h @@ -0,0 +1,75 @@ +/* +Copyright 2015 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 CONFIG_H +#define CONFIG_H + + +/* USB Device descriptor parameter */ +#define VENDOR_ID 0xFEED +#define PRODUCT_ID 0x6464 +#define DEVICE_VER 0x0001 +/* in python2: list(u"whatever".encode('utf-16-le')) */ +/* at most 32 characters or the ugly hack in usb_main.c borks */ +#define MANUFACTURER "TMK" +#define USBSTR_MANUFACTURER 'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', '\xc6', '\x00' +#define PRODUCT "ChibiOS TMK test" +#define USBSTR_PRODUCT 'C', '\x00', 'h', '\x00', 'i', '\x00', 'b', '\x00', 'i', '\x00', 'O', '\x00', 'S', '\x00', ' ', '\x00', 'T', '\x00', 'M', '\x00', 'K', '\x00', ' ', '\x00', 't', '\x00', 'e', '\x00', 's', '\x00', 't', '\x00' +#define DESCRIPTION "TMK keyboard firmware over ChibiOS" + +/* key matrix size */ +#define MATRIX_ROWS 1 +#define MATRIX_COLS 1 +#define DIODE_DIRECTION COL2ROW + +/* define if matrix has ghost */ +//#define MATRIX_HAS_GHOST + +/* Set 0 if debouncing isn't needed */ +#define DEBOUNCE 5 + +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* key combination for command */ +#define IS_COMMAND() ( \ + keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ +) + + + +/* + * Feature disable options + * These options are also useful to firmware size reduction. + */ + +/* disable debug print */ +//#define NO_DEBUG + +/* disable print */ +//#define NO_PRINT + +/* disable action features */ +//#define NO_ACTION_LAYER +//#define NO_ACTION_TAPPING +//#define NO_ACTION_ONESHOT +//#define NO_ACTION_MACRO +//#define NO_ACTION_FUNCTION + +#endif diff --git a/keyboards/teensy_lc_onekey/halconf.h b/keyboards/teensy_lc_onekey/halconf.h new file mode 100644 index 0000000000..b1d2cd5502 --- /dev/null +++ b/keyboards/teensy_lc_onekey/halconf.h @@ -0,0 +1,187 @@ +/* + 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. +*/ + +/** + * @file templates/halconf.h + * @brief HAL configuration header. + * @details HAL configuration file, this file allows to enable or disable the + * various device drivers from your application. You may also use + * this file in order to override the device drivers default settings. + * + * @addtogroup HAL_CONF + * @{ + */ + +#ifndef _HALCONF_H_ +#define _HALCONF_H_ + +#include "mcuconf.h" + +/** + * @brief Enables the PAL subsystem. + */ +#if !defined(HAL_USE_PAL) || defined(__DOXYGEN__) +#define HAL_USE_PAL TRUE +#endif + +/** + * @brief Enables the ADC subsystem. + */ +#if !defined(HAL_USE_ADC) || defined(__DOXYGEN__) +#define HAL_USE_ADC FALSE +#endif + +/** + * @brief Enables the CAN subsystem. + */ +#if !defined(HAL_USE_CAN) || defined(__DOXYGEN__) +#define HAL_USE_CAN FALSE +#endif + +/** + * @brief Enables the DAC subsystem. + */ +#if !defined(HAL_USE_DAC) || defined(__DOXYGEN__) +#define HAL_USE_DAC FALSE +#endif + +/** + * @brief Enables the EXT subsystem. + */ +#if !defined(HAL_USE_EXT) || defined(__DOXYGEN__) +#define HAL_USE_EXT FALSE +#endif + +/** + * @brief Enables the GPT subsystem. + */ +#if !defined(HAL_USE_GPT) || defined(__DOXYGEN__) +#define HAL_USE_GPT FALSE +#endif + +/** + * @brief Enables the I2C subsystem. + */ +#if !defined(HAL_USE_I2C) || defined(__DOXYGEN__) +#define HAL_USE_I2C FALSE +#endif + +/** + * @brief Enables the I2S subsystem. + */ +#if !defined(HAL_USE_I2S) || defined(__DOXYGEN__) +#define HAL_USE_I2S FALSE +#endif + +/** + * @brief Enables the ICU subsystem. + */ +#if !defined(HAL_USE_ICU) || defined(__DOXYGEN__) +#define HAL_USE_ICU FALSE +#endif + +/** + * @brief Enables the MAC subsystem. + */ +#if !defined(HAL_USE_MAC) || defined(__DOXYGEN__) +#define HAL_USE_MAC FALSE +#endif + +/** + * @brief Enables the MMC_SPI subsystem. + */ +#if !defined(HAL_USE_MMC_SPI) || defined(__DOXYGEN__) +#define HAL_USE_MMC_SPI FALSE +#endif + +/** + * @brief Enables the PWM subsystem. + */ +#if !defined(HAL_USE_PWM) || defined(__DOXYGEN__) +#define HAL_USE_PWM FALSE +#endif + +/** + * @brief Enables the RTC subsystem. + */ +#if !defined(HAL_USE_RTC) || defined(__DOXYGEN__) +#define HAL_USE_RTC FALSE +#endif + +/** + * @brief Enables the SDC subsystem. + */ +#if !defined(HAL_USE_SDC) || defined(__DOXYGEN__) +#define HAL_USE_SDC FALSE +#endif + +/** + * @brief Enables the SERIAL subsystem. + */ +#if !defined(HAL_USE_SERIAL) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL FALSE +#endif + +/** + * @brief Enables the SERIAL over USB subsystem. + */ +#if !defined(HAL_USE_SERIAL_USB) || defined(__DOXYGEN__) +#define HAL_USE_SERIAL_USB FALSE +#endif + +/** + * @brief Enables the SPI subsystem. + */ +#if !defined(HAL_USE_SPI) || defined(__DOXYGEN__) +#define HAL_USE_SPI FALSE +#endif + +/** + * @brief Enables the UART subsystem. + */ +#if !defined(HAL_USE_UART) || defined(__DOXYGEN__) +#define HAL_USE_UART FALSE +#endif + +/** + * @brief Enables the USB subsystem. + */ +#if !defined(HAL_USE_USB) || defined(__DOXYGEN__) +#define HAL_USE_USB TRUE +#endif + +/** + * @brief Enables the WDG subsystem. + */ +#if !defined(HAL_USE_WDG) || defined(__DOXYGEN__) +#define HAL_USE_WDG FALSE +#endif + +/*===========================================================================*/ +/* USB driver related settings. */ +/*===========================================================================*/ + +/** + * @brief Enables synchronous APIs. + * @note Disabling this option saves both code and data space. + */ +#if !defined(USB_USE_WAIT) || defined(__DOXYGEN__) +#define USB_USE_WAIT TRUE +#endif + +#endif /* _HALCONF_H_ */ + +/** @} */ diff --git a/keyboards/teensy_lc_onekey/instructions.md b/keyboards/teensy_lc_onekey/instructions.md new file mode 100644 index 0000000000..16886a015c --- /dev/null +++ b/keyboards/teensy_lc_onekey/instructions.md @@ -0,0 +1,82 @@ +# Teensy LC, 3.0, 3.1, 3.2 support + +These ARM Teensies are now supported through [ChibiOS](http://chibios.org). + +You'll need to install an ARM toolchain, for instance from [gcc ARM embedded](https://launchpad.net/gcc-arm-embedded) website, or using your favourite package manager. After installing, you should be able to run `arm-none-eabi-gcc -v` in the command prompt and get sensible output. This toolchain is used instead of `avr-gcc`, which is only for AVR chips. Naturally you'll also need the usual development tools (e.g. `make`), just as in the AVR setting. + +Next, you'll need ChibiOS. For Teensies, you'll need code from two repositories: [chibios-main](https://github.com/ChibiOS/ChibiOS) and [chibios-contrib](https://github.com/ChibiOS/ChibiOS). If you're not using git, you can just download a [zip of chibios from here](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip), unpack the zip, and rename/move the unpacked directory (named `ChibiOS-`) to `tmk_core/tool/chibios/chibios` (so that the file `tmk_core/tool/chibios/chibios/license.txt` exists). Now the same procedure with a [zip of chibios-contrib from here](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip): unpack and move `ChibiOS-Contrib-` to `tmk_core/tool/chibios/chibios-contrib`. + +(If you're using git, you can just clone the two repos: [chibios](https://github.com/ChibiOS/ChibiOS) and [chibios-contrib](https://github.com/ChibiOS/ChibiOS-Contrib). However - be warned that things may be somewhat out-of-sync (updates at different rates), so you may need to hunt a bit for the right commits.) + +(Why do we need chibios-contrib? Well, the main repo focuses on STM32 chips, and Freescale/NXP Kinetis chips are supported via the Contrib repository.) + +This should be it. Running `make` in `keyboard/teensy_lc_onekey` should create a working firmware in `build/`, called `ch.hex`. + +For more notes about the ChibiOS backend in TMK, see `tmk_core/protocol/chibios/README.md`. + +## About this onekey example + +It's set up for Teensy LC. To use 3.x, you'll need to edit the `Makefile` (and comment out one line in `mcuconf.h`). A sample makefile for Teensy 3.0 is provided as `Makefile.3.0`, can be used without renaming with `make -f Makefile.3.0`. Similarly for Teensy 3.2, there's `Makefile.3.2`. + +## Credits + +TMK itself is written by hasu, original sources [here](https://github.com/tmk/tmk_keyboard). + +The USB support for Kinetis MCUs is due to RedoX. His ChibiOS fork is also [on github](https://github.com/RedoXyde/ChibiOS); but it doesn't include Teensy LC definitions. + +## Features that are not implemented yet + +Currently only the more fancy suspend features are not there (power saving during suspend). The rest should work fine (reports either way are welcome). + +# Matrix programming notes + +The notes below explain what commands can be used to examine and set the status of Teensy pins. + +## ChibiOS pin manipulation basics + +### Pins + +Each pin sits on a "port", each of which comprises at most 32 individual pins. +So for instance "PTC5" from Kinetis manual/datasheet refers to port C (or GPIOA), pin 5. Most functions dealing with pins take 2 parameters which specify the pin -- the first being the port, the second being the pin number. + +Within ChibiOS, there are definitions which simplify this a bit for the Teensies. `TEENSY_PINn_IOPORT` represents the port of the MCU's pin connected Teensy's PIN `n`, and `TEENSY_PINn` represents its MCU's pin number. + +### Mode + +A MCU pin can be in several modes. The basic command to set a pin mode is + + palSetPadMode(TEENSY_PINn_IOPORT, TEENSY_PINn, PAL_MODE_INPUT_PULLUP); + +The last parameter is the mode. For keyboards, the usual ones that are used are `PAL_MODE_INPUT_PULLUP` (input with a pullup), `PAL_MODE_INPUT_PULLDOWN` (input with a pulldown), `PAL_MODE_INPUT` (input floating, a.k.a. Hi-Z), `PAL_MODE_OUTPUT_PUSHPULL` (output in the Arduino sense -- can be then set HIGH or LOW). + +### Setting + +Pins are set HIGH (after they've been put into `OUTPUT_PUSHPULL` mode) by + + palSetPad(TEENSY_PINn_IOPORT, TEENSY_PINn); + +or set LOW by + + palClearPad(TEENSY_PINn_IOPORT, TEENSY_PINn); + +Toggling can be done with + + palTogglePad(TEENSY_PINn_IOPORT, TEENSY_PINn); + +Alternatively, you can use + + palWritePad(TEENSY_PINn_IOPORT, TEENSY_PINn, bit); + +where `bit` is either `PAL_LOW` or `PAL_HIGH` (i.e. `0` or `1`). + +### Reading + +Reading pin status is done with + + palReadPad(TEENSY_PINn_IOPORT, TEENSY_PINn); + +The function returns either `PAL_HIGH` (actually `1`) or `PAL_LOW` (actually `0`). + +### Further docs + +All the commands that are available for pin manipulation through ChibiOS HAL are documented in [ChibiOS PAL driver docs](http://chibios.sourceforge.net/docs3/hal/group___p_a_l.html). diff --git a/keyboards/teensy_lc_onekey/keymaps/default/keymap.c b/keyboards/teensy_lc_onekey/keymaps/default/keymap.c new file mode 100644 index 0000000000..a109b49600 --- /dev/null +++ b/keyboards/teensy_lc_onekey/keymaps/default/keymap.c @@ -0,0 +1,32 @@ +/* +Copyright 2012,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 . +*/ + +#include "keycode.h" +#include "action.h" +#include "action_macro.h" +#include "report.h" +#include "host.h" +#include "print.h" +#include "debug.h" +#include "keymap.h" + +const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + {{KC_A}}, +}; // to test: KC_CAPS, KT_BTLD, KC_A + +const uint16_t fn_actions[] = { +}; diff --git a/keyboards/teensy_lc_onekey/ld/MKL26Z64.ld b/keyboards/teensy_lc_onekey/ld/MKL26Z64.ld new file mode 100644 index 0000000000..fb141f888c --- /dev/null +++ b/keyboards/teensy_lc_onekey/ld/MKL26Z64.ld @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2013-2016 Fabio Utzig, http://fabioutzig.com + * (C) 2016 flabbergast + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * KL26Z64 memory setup. + */ +MEMORY +{ + flash0 : org = 0x00000000, len = 0x100 + flash1 : org = 0x00000400, len = 0x10 + flash2 : org = 0x00000410, len = 62k - 0x410 + flash3 : org = 0x0000F800, len = 2k + flash4 : org = 0x00000000, len = 0 + flash5 : org = 0x00000000, len = 0 + flash6 : org = 0x00000000, len = 0 + flash7 : org = 0x00000000, len = 0 + ram0 : org = 0x1FFFF800, len = 8k + 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 +} + +/* Flash region for the configuration bytes.*/ +SECTIONS +{ + .cfmprotect : ALIGN(4) SUBALIGN(4) + { + KEEP(*(.cfmconfig)) + } > flash1 +} + +/* 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", flash2); +REGION_ALIAS("XTORS_FLASH_LMA", flash2); + +/* Flash region to be used for code text.*/ +REGION_ALIAS("TEXT_FLASH", flash2); +REGION_ALIAS("TEXT_FLASH_LMA", flash2); + +/* Flash region to be used for read only data.*/ +REGION_ALIAS("RODATA_FLASH", flash2); +REGION_ALIAS("RODATA_FLASH_LMA", flash2); + +/* Flash region to be used for various.*/ +REGION_ALIAS("VARIOUS_FLASH", flash2); +REGION_ALIAS("VARIOUS_FLASH_LMA", flash2); + +/* Flash region to be used for RAM(n) initialization data.*/ +REGION_ALIAS("RAM_INIT_FLASH_LMA", flash2); + +/* 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", flash2); + +/* 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); + +__eeprom_workarea_start__ = ORIGIN(flash3); +__eeprom_workarea_size__ = LENGTH(flash3); +__eeprom_workarea_end__ = __eeprom_workarea_start__ + __eeprom_workarea_size__; + +/* Generic rules inclusion.*/ +INCLUDE rules.ld diff --git a/keyboards/teensy_lc_onekey/led.c b/keyboards/teensy_lc_onekey/led.c new file mode 100644 index 0000000000..dfa60c1076 --- /dev/null +++ b/keyboards/teensy_lc_onekey/led.c @@ -0,0 +1,32 @@ +/* +Copyright 2012 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 "hal.h" + +#include "led.h" + + +void led_set(uint8_t usb_led) { + if (usb_led & (1< + +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 "ch.h" +#include "hal.h" + +/* + * scan matrix + */ +#include "print.h" +#include "debug.h" +#include "util.h" +#include "matrix.h" +#include "wait.h" + +#ifndef DEBOUNCE +# define DEBOUNCE 5 +#endif +static uint8_t debouncing = DEBOUNCE; + +/* matrix state(1:on, 0:off) */ +static matrix_row_t matrix[MATRIX_ROWS]; +static matrix_row_t matrix_debouncing[MATRIX_ROWS]; + +static matrix_row_t read_cols(void); +static void init_cols(void); +static void unselect_rows(void); +static void select_row(uint8_t row); + + +inline +uint8_t matrix_rows(void) +{ + return MATRIX_ROWS; +} + +inline +uint8_t matrix_cols(void) +{ + return MATRIX_COLS; +} + +#define LED_ON() do { palSetPad(TEENSY_PIN13_IOPORT, TEENSY_PIN13) ;} while (0) +#define LED_OFF() do { palClearPad(TEENSY_PIN13_IOPORT, TEENSY_PIN13); } while (0) +#define LED_TGL() do { palTogglePad(TEENSY_PIN13_IOPORT, TEENSY_PIN13); } while (0) + +void matrix_init(void) +{ + // initialize row and col + unselect_rows(); + init_cols(); + + // initialize matrix state: all keys off + for (uint8_t i=0; i < MATRIX_ROWS; i++) { + matrix[i] = 0; + matrix_debouncing[i] = 0; + } + + //debug + debug_matrix = true; + LED_ON(); + wait_ms(500); + LED_OFF(); +} + +uint8_t matrix_scan(void) +{ + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + select_row(i); + wait_us(30); // without this wait read unstable value. + matrix_row_t cols = read_cols(); + if (matrix_debouncing[i] != cols) { + matrix_debouncing[i] = cols; + if (debouncing) { + debug("bounce!: "); debug_hex(debouncing); debug("\n"); + } + debouncing = DEBOUNCE; + } + unselect_rows(); + } + + if (debouncing) { + if (--debouncing) { + wait_ms(1); + } else { + for (uint8_t i = 0; i < MATRIX_ROWS; i++) { + matrix[i] = matrix_debouncing[i]; + } + } + } + + return 1; +} + +inline +bool matrix_is_on(uint8_t row, uint8_t col) +{ + return (matrix[row] & ((matrix_row_t)1<. #include #include #include "action.h" +#if defined(__AVR__) #include +#endif #include "keycode.h" #include "action_macro.h" #include "report.h" @@ -30,12 +32,15 @@ along with this program. If not, see . #include "debug.h" #include "keycode_config.h" +// ChibiOS uses RESET in its FlagStatus enumeration +// Therefore define it as QK_RESET here, to avoid name collision +#if defined(PROTOCOL_CHIBIOS) +#define RESET QK_RESET +#endif + /* translates key to keycode */ uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); -/* translates Fn keycode to action */ -action_t keymap_fn_to_action(uint16_t keycode); - extern const uint16_t keymaps[][MATRIX_ROWS][MATRIX_COLS]; extern const uint16_t fn_actions[]; diff --git a/quantum/keymap.c b/quantum/keymap_common.c similarity index 94% rename from quantum/keymap.c rename to quantum/keymap_common.c index 74fd518c9b..76872ac592 100644 --- a/quantum/keymap.c +++ b/quantum/keymap_common.c @@ -19,7 +19,10 @@ along with this program. If not, see . #include "report.h" #include "keycode.h" #include "action_layer.h" +#if defined(__AVR__) #include +#include +#endif #include "action.h" #include "action_macro.h" #include "debug.h" @@ -32,7 +35,6 @@ along with this program. If not, see . extern keymap_config_t keymap_config; -#include #include /* converts key to action */ @@ -46,10 +48,12 @@ action_t action_for_key(uint8_t layer, keypos_t key) action_t action; uint8_t action_layer, when, mod; + // The arm-none-eabi compiler generates out of bounds warnings when using the fn_actions directly for some reason + const uint16_t* actions = fn_actions; switch (keycode) { case KC_FN0 ... KC_FN31: - action.code = pgm_read_word(&fn_actions[FN_INDEX(keycode)]); + action.code = pgm_read_word(&actions[FN_INDEX(keycode)]); break; case KC_A ... KC_EXSEL: case KC_LCTRL ... KC_RGUI: @@ -75,7 +79,7 @@ action_t action_for_key(uint8_t layer, keypos_t key) case QK_FUNCTION ... QK_FUNCTION_MAX: ; // Is a shortcut for function action_layer, pull last 12bits // This means we have 4,096 FN macros at our disposal - action.code = pgm_read_word(&fn_actions[(int)keycode & 0xFFF]); + action.code = pgm_read_word(&actions[(int)keycode & 0xFFF]); break; case QK_MACRO ... QK_MACRO_MAX: action.code = ACTION_MACRO(keycode & 0xFF); diff --git a/quantum/matrix.c b/quantum/matrix.c index f5744658cf..a38c13f15b 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -17,7 +17,9 @@ along with this program. If not, see . */ #include #include +#if defined(__AVR__) #include +#endif #include "wait.h" #include "print.h" #include "debug.h" diff --git a/quantum/quantum.c b/quantum/quantum.c index 270b976e36..d59bd5a3f8 100644 --- a/quantum/quantum.c +++ b/quantum/quantum.c @@ -88,7 +88,7 @@ bool process_record_quantum(keyrecord_t *record) { stop_all_notes(); shutdown_user(); #endif - _delay_ms(250); + wait_ms(250); #ifdef ATREUS_ASTAR *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific #endif diff --git a/quantum/quantum.h b/quantum/quantum.h index 9b5d310bd4..3a0b742028 100644 --- a/quantum/quantum.h +++ b/quantum/quantum.h @@ -1,7 +1,12 @@ #ifndef QUANTUM_H #define QUANTUM_H +#if defined(__AVR__) #include +#include +#include +#endif +#include "wait.h" #include "matrix.h" #include "keymap.h" #ifdef BACKLIGHT_ENABLE @@ -14,12 +19,9 @@ #include "action_layer.h" #include "eeconfig.h" #include -#include -#include #include "bootloader.h" #include "timer.h" #include "config_common.h" -#include #include "led.h" #include "action_util.h" #include diff --git a/readme.md b/readme.md index 6fa67c0474..c24d951d8d 100644 --- a/readme.md +++ b/readme.md @@ -24,6 +24,9 @@ The project also includes community support for [lots of other keyboards](/keybo QMK is developed and maintained by Jack Humbert of OLKB with contributions from the community, and of course, [Hasu](https://github.com/tmk). This repo used to be a fork of [TMK](https://github.com/tmk/tmk_keyboard), and we are incredibly grateful for his founding contributions to the firmware. We've had to break the fork due to purely technical reasons - it simply became too different over time, and we've had to start refactoring some of the basic bits and pieces. We are huge fans of TMK and Hasu :) This documentation is edited and maintained by Erez Zukerman of ErgoDox EZ. If you spot any typos or inaccuracies, please [open an issue](https://github.com/jackhumbert/qmk_firmware/issues/new). +#### 2016/02/10 +core: flabbergast's Chibios protocol was merged from (@72b1668). See [tmk_core/protocol/chibios/README.md](tmk_core/protocol/chibios/README.md). Chibios protocol supports Cortex-M such as STM32 and Kinetis. + The OLKB product firmwares are maintained by [Jack Humbert](https://github.com/jackhumbert), the Ergodox EZ by [Erez Zukerman](https://github.com/ezuk), and the Clueboard by [Zach White](https://github.com/skullydazed). diff --git a/tmk_core/avr.mk b/tmk_core/avr.mk new file mode 100644 index 0000000000..72be5e6da1 --- /dev/null +++ b/tmk_core/avr.mk @@ -0,0 +1,185 @@ +# Hey Emacs, this is a -*- makefile -*- +############################################################################## +# Compiler settings +# +CC = avr-gcc +OBJCOPY = avr-objcopy +OBJDUMP = avr-objdump +SIZE = avr-size +AR = avr-ar rcs +NM = avr-nm +HEX = $(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature +EEP = $(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) + + + +COMPILEFLAGS += -funsigned-char +COMPILEFLAGS += -funsigned-bitfields +COMPILEFLAGS += -ffunction-sections +COMPILEFLAGS += -fdata-sections +COMPILEFLAGS += -fpack-struct +COMPILEFLAGS += -fshort-enums + +CFLAGS += $(COMPILEFLAGS) +CFLAGS += -fno-inline-small-functions +CFLAGS += -fno-strict-aliasing + +CPPFLAGS += $(COMPILEFLAGS) +CPPFLAGS += -fno-exceptions + +LDFLAGS +=-Wl,--gc-sections + +OPT_DEFS += -DF_CPU=$(F_CPU)UL + +MCUFLAGS = -mmcu=$(MCU) + +# List any extra directories to look for libraries here. +# Each directory must be seperated by a space. +# Use forward slashes for directory separators. +# For a directory that has spaces, enclose it in quotes. +EXTRALIBDIRS = + + +#---------------- External Memory Options ---------------- + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# used for variables (.data/.bss) and heap (malloc()). +#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff + +# 64 KB of external RAM, starting after internal RAM (ATmega128!), +# only used for heap (malloc()). +#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff + +EXTMEMOPTS = + +#---------------- Debugging Options ---------------- + +# Debugging format. +# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. +# AVR Studio 4.10 requires dwarf-2. +# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. +DEBUG = dwarf-2 + +# For simulavr only - target MCU frequency. +DEBUG_MFREQ = $(F_CPU) + +# Set the DEBUG_UI to either gdb or insight. +# DEBUG_UI = gdb +DEBUG_UI = insight + +# Set the debugging back-end to either avarice, simulavr. +DEBUG_BACKEND = avarice +#DEBUG_BACKEND = simulavr + +# GDB Init Filename. +GDBINIT_FILE = __avr_gdbinit + +# When using avarice settings for the JTAG +JTAG_DEV = /dev/com1 + +# Debugging port used to communicate between GDB / avarice / simulavr. +DEBUG_PORT = 4242 + +# Debugging host used to communicate between GDB / avarice / simulavr, normally +# just set to localhost unless doing some sort of crazy debugging when +# avarice is running on a different computer. +DEBUG_HOST = localhost + +#============================================================================ +# Autodecct teensy loader +ifneq (, $(shell which teensy-loader-cli 2>/dev/null)) + TEENSY_LOADER_CLI = teensy-loader-cli +else + TEENSY_LOADER_CLI = teensy_loader_cli +endif + +# Program the device. +program: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep + $(PROGRAM_CMD) + +teensy: $(BUILD_DIR)/$(TARGET).hex + $(TEENSY_LOADER_CLI) -mmcu=$(MCU) -w -v $(BUILD_DIR)/$(TARGET).hex + +flip: $(BUILD_DIR)/$(TARGET).hex + batchisp -hardware usb -device $(MCU) -operation erase f + batchisp -hardware usb -device $(MCU) -operation loadbuffer $(BUILD_DIR)/$(TARGET).hex program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + +dfu: $(BUILD_DIR)/$(TARGET).hex sizeafter +ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1))) + dfu-programmer $(MCU) erase --force +else + dfu-programmer $(MCU) erase +endif + dfu-programmer $(MCU) flash $(BUILD_DIR)/$(TARGET).hex + dfu-programmer $(MCU) reset + +dfu-start: + dfu-programmer $(MCU) reset + dfu-programmer $(MCU) start + +flip-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep + $(COPY) $(BUILD_DIR)/$(TARGET).eep $(BUILD_DIR)/$(TARGET)eep.hex + batchisp -hardware usb -device $(MCU) -operation memory EEPROM erase + batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(BUILD_DIR)/$(TARGET)eep.hex program + batchisp -hardware usb -device $(MCU) -operation start reset 0 + $(REMOVE) $(BUILD_DIR)/$(TARGET)eep.hex + +dfu-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep +ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1))) + dfu-programmer $(MCU) flash --eeprom $(BUILD_DIR)/$(TARGET).eep +else + dfu-programmer $(MCU) flash-eeprom $(BUILD_DIR)/$(TARGET).eep +endif + dfu-programmer $(MCU) reset + + +# Generate avr-gdb config/init file which does the following: +# define the reset signal, load the target file, connect to target, and set +# a breakpoint at main(). +gdb-config: + @$(REMOVE) $(GDBINIT_FILE) + @echo define reset >> $(GDBINIT_FILE) + @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) + @echo end >> $(GDBINIT_FILE) + @echo file $(BUILD_DIR)/$(TARGET).elf >> $(GDBINIT_FILE) + @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) +ifeq ($(DEBUG_BACKEND),simulavr) + @echo load >> $(GDBINIT_FILE) +endif + @echo break main >> $(GDBINIT_FILE) + +debug: gdb-config $(BUILD_DIR)/$(TARGET).elf +ifeq ($(DEBUG_BACKEND), avarice) + @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. + @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ + $(BUILD_DIR)/$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) + @$(WINSHELL) /c pause + +else + @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ + $(DEBUG_MFREQ) --port $(DEBUG_PORT) +endif + @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) + + + + +# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. +COFFCONVERT = $(OBJCOPY) --debugging +COFFCONVERT += --change-section-address .data-0x800000 +COFFCONVERT += --change-section-address .bss-0x800000 +COFFCONVERT += --change-section-address .noinit-0x800000 +COFFCONVERT += --change-section-address .eeprom-0x810000 + + + +coff: $(BUILD_DIR)/$(TARGET).elf + @$(SECHO) $(MSG_COFF) $(BUILD_DIR)/$(TARGET).cof + $(COFFCONVERT) -O coff-avr $< $(BUILD_DIR)/$(TARGET).cof + + +extcoff: $(BUILD_DIR)/$(TARGET).elf + @$(SECHO) $(MSG_EXTENDED_COFF) $(BUILD_DIR)/$(TARGET).cof + $(COFFCONVERT) -O coff-ext-avr $< $(BUILD_DIR)/$(TARGET).cof + diff --git a/tmk_core/chibios.mk b/tmk_core/chibios.mk new file mode 100644 index 0000000000..0abb933a8d --- /dev/null +++ b/tmk_core/chibios.mk @@ -0,0 +1,154 @@ +# Hey Emacs, this is a -*- makefile -*- +############################################################################## +# Architecture or project specific options +# + +# Stack size to be allocated to the Cortex-M process stack. This stack is +# the stack used by the main() thread. +ifeq ($(USE_PROCESS_STACKSIZE),) + USE_PROCESS_STACKSIZE = 0x200 +endif + +# Stack size to the allocated to the Cortex-M main/exceptions stack. This +# stack is used for processing interrupts and exceptions. +ifeq ($(USE_EXCEPTIONS_STACKSIZE),) + USE_EXCEPTIONS_STACKSIZE = 0x400 +endif + +# +# Architecture or project specific options +############################################################################## + +############################################################################## +# Project, sources and paths +# + +# Imported source files and paths +CHIBIOS = $(TOP_DIR)/lib/chibios +CHIBIOS_CONTRIB = $(TOP_DIR)/lib/chibios-contrib +# 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 + +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 = $(KEYBOARD_PATH)/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 +# 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). +include $(CHIBIOS)/os/hal/lib/streams/streams.mk + +RULESPATH = $(CHIBIOS)/os/common/ports/ARMCMx/compilers/GCC +ifeq ("$(wildcard $(RULESPATH)/rules.mk)","") +RULESPATH = $(CHIBIOS)/os/common/startup/ARMCMx/compilers/GCC +endif + +# Define linker script file here +ifneq ("$(wildcard $(KEYBOARD_PATH)/ld/$(MCU_LDSCRIPT).ld)","") +LDSCRIPT = $(KEYBOARD_PATH)/ld/$(MCU_LDSCRIPT).ld +else +LDSCRIPT = $(STARTUPLD)/$(MCU_LDSCRIPT).ld +endif + +CHIBISRC = $(STARTUPSRC) \ + $(KERNSRC) \ + $(PORTSRC) \ + $(OSALSRC) \ + $(HALSRC) \ + $(PLATFORMSRC) \ + $(BOARDSRC) \ + $(STREAMSSRC) \ + $(STARTUPASM) \ + $(PORTASM) \ + $(OSALASM) + +SRC += $(patsubst $(TOP_DIR)/%,%,$(CHIBISRC)) + +EXTRAINCDIRS += $(CHIBIOS)/os/license \ + $(STARTUPINC) $(KERNINC) $(PORTINC) $(OSALINC) \ + $(HALINC) $(PLATFORMINC) $(BOARDINC) $(TESTINC) \ + $(STREAMSINC) $(CHIBIOS)/os/various + +# +# Project, sources and paths +############################################################################## + + +############################################################################## +# Compiler settings +# +CC = arm-none-eabi-gcc +OBJCOPY = arm-none-eabi-objcopy +OBJDUMP = arm-none-eabi-objdump +SIZE = arm-none-eabi-size +AR = arm-none-eabi-ar +NM = arm-none-eabi-nm +HEX = $(OBJCOPY) -O $(FORMAT) +EEP = + +THUMBFLAGS = -DTHUMB_PRESENT -mno-thumb-interwork -DTHUMB_NO_INTERWORKING -mthumb -DTHUMB + +COMPILEFLAGS += -fomit-frame-pointer +COMPILEFLAGS += -falign-functions=16 +COMPILEFLAGS += -ffunction-sections +COMPILEFLAGS += -fdata-sections +COMPILEFLAGS += -fno-common +COMPILEFLAGS += $(THUMBFLAGS) + +CFLAGS += $(COMPILEFLAGS) + +ASFLAGS += $(THUMBFLAGS) + +CPPFLAGS += $(COMPILEFLAGS) +CPPFLAGS += -fno-rtti + +LDFLAGS +=-Wl,--gc-sections +LDFLAGS += -mno-thumb-interwork -mthumb +LDSYMBOLS =,--defsym=__process_stack_size__=$(USE_PROCESS_STACKSIZE) +LDSYMBOLS :=$(LDSYMBOLS),--defsym=__main_stack_size__=$(USE_EXCEPTIONS_STACKSIZE) +LDFLAGS += -Wl,--script=$(LDSCRIPT)$(LDSYMBOLS) + +OPT_DEFS += -DPROTOCOL_CHIBIOS + +MCUFLAGS = -mcpu=$(MCU) + +DEBUG = gdb + +# Define ASM defines here +# bootloader definitions may be used in the startup .s file +ifneq ("$(wildcard $(KEYBOARD_PATH)/bootloader_defs.h)","") + OPT_DEFS += -include $(KEYBOARD_PATH)/bootloader_defs.h +else ifneq ("$(wildcard $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h)","") + OPT_DEFS += -include $(KEYBOARD_PATH)/boards/$(BOARD)/bootloader_defs.h +endif + +# List any extra directories to look for libraries here. +EXTRALIBDIRS = $(RULESPATH)/ld \ No newline at end of file diff --git a/tmk_core/common.mk b/tmk_core/common.mk index f2a22e4f8c..d71fba9bc1 100644 --- a/tmk_core/common.mk +++ b/tmk_core/common.mk @@ -1,4 +1,10 @@ COMMON_DIR = common +ifeq ($(PLATFORM),AVR) + PLATFORM_COMMON_DIR = $(COMMON_DIR)/avr +else ifeq ($(PLATFORM),CHIBIOS) + PLATFORM_COMMON_DIR = $(COMMON_DIR)/chibios +endif + SRC += $(COMMON_DIR)/host.c \ $(COMMON_DIR)/keyboard.c \ $(COMMON_DIR)/action.c \ @@ -9,21 +15,29 @@ SRC += $(COMMON_DIR)/host.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 + $(COMMON_DIR)/eeconfig.c \ + $(PLATFORM_COMMON_DIR)/suspend.c \ + $(PLATFORM_COMMON_DIR)/timer.c \ + $(PLATFORM_COMMON_DIR)/bootloader.c \ + +ifeq ($(PLATFORM),AVR) + SRC += $(PLATFORM_COMMON_DIR)/xprintf.S +endif + +ifeq ($(PLATFORM),CHIBIOS) + SRC += $(PLATFORM_COMMON_DIR)/printf.c + SRC += $(PLATFORM_COMMON_DIR)/eeprom.c +endif + # Option modules ifeq ($(strip $(BOOTMAGIC_ENABLE)), yes) OPT_DEFS += -DBOOTMAGIC_ENABLE SRC += $(COMMON_DIR)/bootmagic.c - SRC += $(COMMON_DIR)/avr/eeconfig.c else OPT_DEFS += -DMAGIC_ENABLE SRC += $(COMMON_DIR)/magic.c - SRC += $(COMMON_DIR)/avr/eeconfig.c endif ifeq ($(strip $(MOUSEKEY_ENABLE)), yes) @@ -57,14 +71,13 @@ ifeq ($(strip $(USB_6KRO_ENABLE)), yes) endif ifeq ($(strip $(SLEEP_LED_ENABLE)), yes) - SRC += $(COMMON_DIR)/sleep_led.c + SRC += $(PLATFORM_COMMON_DIR)/sleep_led.c OPT_DEFS += -DSLEEP_LED_ENABLE OPT_DEFS += -DNO_SUSPEND_POWER_DOWN endif ifeq ($(strip $(BACKLIGHT_ENABLE)), yes) SRC += $(COMMON_DIR)/backlight.c - SRC += $(COMMON_DIR)/avr/eeconfig.c OPT_DEFS += -DBACKLIGHT_ENABLE endif @@ -87,6 +100,13 @@ endif # Version string OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null) +# Bootloader address +ifdef STM32_BOOTLOADER_ADDRESS + OPT_DEFS += -DSTM32_BOOTLOADER_ADDRESS=$(STM32_BOOTLOADER_ADDRESS) +endif # Search Path VPATH += $(TMK_PATH)/$(COMMON_DIR) +ifeq ($(PLATFORM),CHIBIOS) +VPATH += $(TMK_PATH)/$(COMMON_DIR)/chibios +endif \ No newline at end of file diff --git a/tmk_core/common/action_tapping.c b/tmk_core/common/action_tapping.c index ff78d7f2ab..e16e11be7f 100644 --- a/tmk_core/common/action_tapping.c +++ b/tmk_core/common/action_tapping.c @@ -257,7 +257,7 @@ bool process_tapping(keyrecord_t *keyp) return true; } } else { - if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n"); + if (!IS_NOEVENT(event)) debug("Tapping: other key just after tap.\n") {}; process_record(keyp); return true; } diff --git a/tmk_core/common/sleep_led.c b/tmk_core/common/avr/sleep_led.c similarity index 100% rename from tmk_core/common/sleep_led.c rename to tmk_core/common/avr/sleep_led.c diff --git a/tmk_core/common/bootmagic.c b/tmk_core/common/bootmagic.c index 30e8a0f20f..90275a18ba 100644 --- a/tmk_core/common/bootmagic.c +++ b/tmk_core/common/bootmagic.c @@ -1,6 +1,6 @@ #include #include -#include +#include "wait.h" #include "matrix.h" #include "bootloader.h" #include "debug.h" @@ -10,6 +10,7 @@ #include "eeconfig.h" #include "bootmagic.h" +keymap_config_t keymap_config; void bootmagic(void) { @@ -19,9 +20,9 @@ void bootmagic(void) } /* do scans in case of bounce */ - print("boogmagic scan: ... "); + print("bootmagic scan: ... "); uint8_t scan = 100; - while (scan--) { matrix_scan(); _delay_ms(10); } + while (scan--) { matrix_scan(); wait_ms(10); } print("done.\n"); /* bootmagic skip */ diff --git a/tmk_core/common/chibios/bootloader.c b/tmk_core/common/chibios/bootloader.c new file mode 100644 index 0000000000..8a533ab6f6 --- /dev/null +++ b/tmk_core/common/chibios/bootloader.c @@ -0,0 +1,47 @@ +#include "bootloader.h" + +#include "ch.h" +#include "hal.h" + +#ifdef STM32_BOOTLOADER_ADDRESS +/* STM32 */ + +#if defined(STM32F0XX) +/* This code should be checked whether it runs correctly on platforms */ +#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) +extern uint32_t __ram0_end__; + +void bootloader_jump(void) { + *((unsigned long *)(SYMVAL(__ram0_end__) - 4)) = 0xDEADBEEF; // set magic flag => reset handler will jump into boot loader + NVIC_SystemReset(); +} + +#else /* defined(STM32F0XX) */ +#error Check that the bootloader code works on your platform and add it to bootloader.c! +#endif /* defined(STM32F0XX) */ + +#elif defined(KL2x) || defined(K20x) /* STM32_BOOTLOADER_ADDRESS */ +/* Kinetis */ + +#if defined(KIIBOHD_BOOTLOADER) +/* Kiibohd Bootloader (MCHCK and Infinity KB) */ +#define SCB_AIRCR_VECTKEY_WRITEMAGIC 0x05FA0000 +const uint8_t sys_reset_to_loader_magic[] = "\xff\x00\x7fRESET TO LOADER\x7f\x00\xff"; +void bootloader_jump(void) { + __builtin_memcpy((void *)VBAT, (const void *)sys_reset_to_loader_magic, sizeof(sys_reset_to_loader_magic)); + // request reset + SCB->AIRCR = SCB_AIRCR_VECTKEY_WRITEMAGIC | SCB_AIRCR_SYSRESETREQ_Msk; +} + +#else /* defined(KIIBOHD_BOOTLOADER) */ +/* Default for Kinetis - expecting an ARM Teensy */ +void bootloader_jump(void) { + chThdSleepMilliseconds(100); + __BKPT(0); +} +#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/eeprom.c b/tmk_core/common/chibios/eeprom.c new file mode 100644 index 0000000000..5ff8ee86f4 --- /dev/null +++ b/tmk_core/common/chibios/eeprom.c @@ -0,0 +1,588 @@ +#include "ch.h" +#include "hal.h" + +#include "eeconfig.h" + +/*************************************/ +/* Hardware backend */ +/* */ +/* Code from PJRC/Teensyduino */ +/*************************************/ + +/* Teensyduino Core Library + * http://www.pjrc.com/teensy/ + * Copyright (c) 2013 PJRC.COM, LLC. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * 1. The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * 2. If the Software is incorporated into a build system that allows + * selection among a list of target devices, then similar target + * devices manufactured by PJRC.COM must be included in the list of + * target devices and selectable in the same manner. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + + +#if defined(K20x) /* chip selection */ +/* Teensy 3.0, 3.1, 3.2; mchck; infinity keyboard */ + +// The EEPROM is really RAM with a hardware-based backup system to +// flash memory. Selecting a smaller size EEPROM allows more wear +// leveling, for higher write endurance. If you edit this file, +// set this to the smallest size your application can use. Also, +// due to Freescale's implementation, writing 16 or 32 bit words +// (aligned to 2 or 4 byte boundaries) has twice the endurance +// compared to writing 8 bit bytes. +// +#define EEPROM_SIZE 32 + +// Writing unaligned 16 or 32 bit data is handled automatically when +// this is defined, but at a cost of extra code size. Without this, +// any unaligned write will cause a hard fault exception! If you're +// absolutely sure all 16 and 32 bit writes will be aligned, you can +// remove the extra unnecessary code. +// +#define HANDLE_UNALIGNED_WRITES + +// Minimum EEPROM Endurance +// ------------------------ +#if (EEPROM_SIZE == 2048) // 35000 writes/byte or 70000 writes/word + #define EEESIZE 0x33 +#elif (EEPROM_SIZE == 1024) // 75000 writes/byte or 150000 writes/word + #define EEESIZE 0x34 +#elif (EEPROM_SIZE == 512) // 155000 writes/byte or 310000 writes/word + #define EEESIZE 0x35 +#elif (EEPROM_SIZE == 256) // 315000 writes/byte or 630000 writes/word + #define EEESIZE 0x36 +#elif (EEPROM_SIZE == 128) // 635000 writes/byte or 1270000 writes/word + #define EEESIZE 0x37 +#elif (EEPROM_SIZE == 64) // 1275000 writes/byte or 2550000 writes/word + #define EEESIZE 0x38 +#elif (EEPROM_SIZE == 32) // 2555000 writes/byte or 5110000 writes/word + #define EEESIZE 0x39 +#endif + +void eeprom_initialize(void) +{ + uint32_t count=0; + uint16_t do_flash_cmd[] = { + 0xf06f, 0x037f, 0x7003, 0x7803, + 0xf013, 0x0f80, 0xd0fb, 0x4770}; + uint8_t status; + + if (FTFL->FCNFG & FTFL_FCNFG_RAMRDY) { + // FlexRAM is configured as traditional RAM + // We need to reconfigure for EEPROM usage + FTFL->FCCOB0 = 0x80; // PGMPART = Program Partition Command + FTFL->FCCOB4 = EEESIZE; // EEPROM Size + FTFL->FCCOB5 = 0x03; // 0K for Dataflash, 32K for EEPROM backup + __disable_irq(); + // do_flash_cmd() must execute from RAM. Luckily the C syntax is simple... + (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFL->FSTAT)); + __enable_irq(); + status = FTFL->FSTAT; + if (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)) { + FTFL->FSTAT = (status & (FTFL_FSTAT_RDCOLERR|FTFL_FSTAT_ACCERR|FTFL_FSTAT_FPVIOL)); + return; // error + } + } + // wait for eeprom to become ready (is this really necessary?) + while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { + if (++count > 20000) break; + } +} + +#define FlexRAM ((uint8_t *)0x14000000) + +uint8_t eeprom_read_byte(const uint8_t *addr) +{ + uint32_t offset = (uint32_t)addr; + if (offset >= EEPROM_SIZE) return 0; + if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); + return FlexRAM[offset]; +} + +uint16_t eeprom_read_word(const uint16_t *addr) +{ + uint32_t offset = (uint32_t)addr; + if (offset >= EEPROM_SIZE-1) return 0; + if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); + return *(uint16_t *)(&FlexRAM[offset]); +} + +uint32_t eeprom_read_dword(const uint32_t *addr) +{ + uint32_t offset = (uint32_t)addr; + if (offset >= EEPROM_SIZE-3) return 0; + if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); + return *(uint32_t *)(&FlexRAM[offset]); +} + +void eeprom_read_block(void *buf, const void *addr, uint32_t len) +{ + uint32_t offset = (uint32_t)addr; + uint8_t *dest = (uint8_t *)buf; + uint32_t end = offset + len; + + if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); + if (end > EEPROM_SIZE) end = EEPROM_SIZE; + while (offset < end) { + *dest++ = FlexRAM[offset++]; + } +} + +int eeprom_is_ready(void) +{ + return (FTFL->FCNFG & FTFL_FCNFG_EEERDY) ? 1 : 0; +} + +static void flexram_wait(void) +{ + while (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) { + // TODO: timeout + } +} + +void eeprom_write_byte(uint8_t *addr, uint8_t value) +{ + uint32_t offset = (uint32_t)addr; + + if (offset >= EEPROM_SIZE) return; + if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); + if (FlexRAM[offset] != value) { + FlexRAM[offset] = value; + flexram_wait(); + } +} + +void eeprom_write_word(uint16_t *addr, uint16_t value) +{ + uint32_t offset = (uint32_t)addr; + + if (offset >= EEPROM_SIZE-1) return; + if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); +#ifdef HANDLE_UNALIGNED_WRITES + if ((offset & 1) == 0) { +#endif + if (*(uint16_t *)(&FlexRAM[offset]) != value) { + *(uint16_t *)(&FlexRAM[offset]) = value; + flexram_wait(); + } +#ifdef HANDLE_UNALIGNED_WRITES + } else { + if (FlexRAM[offset] != value) { + FlexRAM[offset] = value; + flexram_wait(); + } + if (FlexRAM[offset + 1] != (value >> 8)) { + FlexRAM[offset + 1] = value >> 8; + flexram_wait(); + } + } +#endif +} + +void eeprom_write_dword(uint32_t *addr, uint32_t value) +{ + uint32_t offset = (uint32_t)addr; + + if (offset >= EEPROM_SIZE-3) return; + if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); +#ifdef HANDLE_UNALIGNED_WRITES + switch (offset & 3) { + case 0: +#endif + if (*(uint32_t *)(&FlexRAM[offset]) != value) { + *(uint32_t *)(&FlexRAM[offset]) = value; + flexram_wait(); + } + return; +#ifdef HANDLE_UNALIGNED_WRITES + case 2: + if (*(uint16_t *)(&FlexRAM[offset]) != value) { + *(uint16_t *)(&FlexRAM[offset]) = value; + flexram_wait(); + } + if (*(uint16_t *)(&FlexRAM[offset + 2]) != (value >> 16)) { + *(uint16_t *)(&FlexRAM[offset + 2]) = value >> 16; + flexram_wait(); + } + return; + default: + if (FlexRAM[offset] != value) { + FlexRAM[offset] = value; + flexram_wait(); + } + if (*(uint16_t *)(&FlexRAM[offset + 1]) != (value >> 8)) { + *(uint16_t *)(&FlexRAM[offset + 1]) = value >> 8; + flexram_wait(); + } + if (FlexRAM[offset + 3] != (value >> 24)) { + FlexRAM[offset + 3] = value >> 24; + flexram_wait(); + } + } +#endif +} + +void eeprom_write_block(const void *buf, void *addr, uint32_t len) +{ + uint32_t offset = (uint32_t)addr; + const uint8_t *src = (const uint8_t *)buf; + + if (offset >= EEPROM_SIZE) return; + if (!(FTFL->FCNFG & FTFL_FCNFG_EEERDY)) eeprom_initialize(); + if (len >= EEPROM_SIZE) len = EEPROM_SIZE; + if (offset + len >= EEPROM_SIZE) len = EEPROM_SIZE - offset; + while (len > 0) { + uint32_t lsb = offset & 3; + if (lsb == 0 && len >= 4) { + // write aligned 32 bits + uint32_t val32; + val32 = *src++; + val32 |= (*src++ << 8); + val32 |= (*src++ << 16); + val32 |= (*src++ << 24); + if (*(uint32_t *)(&FlexRAM[offset]) != val32) { + *(uint32_t *)(&FlexRAM[offset]) = val32; + flexram_wait(); + } + offset += 4; + len -= 4; + } else if ((lsb == 0 || lsb == 2) && len >= 2) { + // write aligned 16 bits + uint16_t val16; + val16 = *src++; + val16 |= (*src++ << 8); + if (*(uint16_t *)(&FlexRAM[offset]) != val16) { + *(uint16_t *)(&FlexRAM[offset]) = val16; + flexram_wait(); + } + offset += 2; + len -= 2; + } else { + // write 8 bits + uint8_t val8 = *src++; + if (FlexRAM[offset] != val8) { + FlexRAM[offset] = val8; + flexram_wait(); + } + offset++; + len--; + } + } +} + +/* +void do_flash_cmd(volatile uint8_t *fstat) +{ + *fstat = 0x80; + while ((*fstat & 0x80) == 0) ; // wait +} +00000000 : + 0: f06f 037f mvn.w r3, #127 ; 0x7f + 4: 7003 strb r3, [r0, #0] + 6: 7803 ldrb r3, [r0, #0] + 8: f013 0f80 tst.w r3, #128 ; 0x80 + c: d0fb beq.n 6 + e: 4770 bx lr +*/ + +#elif defined(KL2x) /* chip selection */ +/* Teensy LC (emulated) */ + +#define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0)) + +extern uint32_t __eeprom_workarea_start__; +extern uint32_t __eeprom_workarea_end__; + +#define EEPROM_SIZE 128 + +static uint32_t flashend = 0; + +void eeprom_initialize(void) +{ + const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); + + do { + if (*p++ == 0xFFFF) { + flashend = (uint32_t)(p - 2); + return; + } + } while (p < (uint16_t *)SYMVAL(__eeprom_workarea_end__)); + flashend = (uint32_t)((uint16_t *)SYMVAL(__eeprom_workarea_end__) - 1); +} + +uint8_t eeprom_read_byte(const uint8_t *addr) +{ + uint32_t offset = (uint32_t)addr; + const uint16_t *p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); + const uint16_t *end = (const uint16_t *)((uint32_t)flashend); + uint16_t val; + uint8_t data=0xFF; + + if (!end) { + eeprom_initialize(); + end = (const uint16_t *)((uint32_t)flashend); + } + if (offset < EEPROM_SIZE) { + while (p <= end) { + val = *p++; + if ((val & 255) == offset) data = val >> 8; + } + } + return data; +} + +static void flash_write(const uint16_t *code, uint32_t addr, uint32_t data) +{ + // with great power comes great responsibility.... + uint32_t stat; + *(uint32_t *)&(FTFA->FCCOB3) = 0x06000000 | (addr & 0x00FFFFFC); + *(uint32_t *)&(FTFA->FCCOB7) = data; + __disable_irq(); + (*((void (*)(volatile uint8_t *))((uint32_t)code | 1)))(&(FTFA->FSTAT)); + __enable_irq(); + stat = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL); + if (stat) { + FTFA->FSTAT = stat; + } + MCM->PLACR |= MCM_PLACR_CFCC; +} + +void eeprom_write_byte(uint8_t *addr, uint8_t data) +{ + uint32_t offset = (uint32_t)addr; + const uint16_t *p, *end = (const uint16_t *)((uint32_t)flashend); + uint32_t i, val, flashaddr; + uint16_t do_flash_cmd[] = { + 0x2380, 0x7003, 0x7803, 0xb25b, 0x2b00, 0xdafb, 0x4770}; + uint8_t buf[EEPROM_SIZE]; + + if (offset >= EEPROM_SIZE) return; + if (!end) { + eeprom_initialize(); + end = (const uint16_t *)((uint32_t)flashend); + } + if (++end < (uint16_t *)SYMVAL(__eeprom_workarea_end__)) { + val = (data << 8) | offset; + flashaddr = (uint32_t)end; + flashend = flashaddr; + if ((flashaddr & 2) == 0) { + val |= 0xFFFF0000; + } else { + val <<= 16; + val |= 0x0000FFFF; + } + flash_write(do_flash_cmd, flashaddr, val); + } else { + for (i=0; i < EEPROM_SIZE; i++) { + buf[i] = 0xFF; + } + val = 0; + for (p = (uint16_t *)SYMVAL(__eeprom_workarea_start__); p < (uint16_t *)SYMVAL(__eeprom_workarea_end__); p++) { + val = *p; + if ((val & 255) < EEPROM_SIZE) { + buf[val & 255] = val >> 8; + } + } + buf[offset] = data; + for (flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); flashaddr < (uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_end__); flashaddr += 1024) { + *(uint32_t *)&(FTFA->FCCOB3) = 0x09000000 | flashaddr; + __disable_irq(); + (*((void (*)(volatile uint8_t *))((uint32_t)do_flash_cmd | 1)))(&(FTFA->FSTAT)); + __enable_irq(); + val = FTFA->FSTAT & (FTFA_FSTAT_RDCOLERR|FTFA_FSTAT_ACCERR|FTFA_FSTAT_FPVIOL);; + if (val) FTFA->FSTAT = val; + MCM->PLACR |= MCM_PLACR_CFCC; + } + flashaddr=(uint32_t)(uint16_t *)SYMVAL(__eeprom_workarea_start__); + for (i=0; i < EEPROM_SIZE; i++) { + if (buf[i] == 0xFF) continue; + if ((flashaddr & 2) == 0) { + val = (buf[i] << 8) | i; + } else { + val = val | (buf[i] << 24) | (i << 16); + flash_write(do_flash_cmd, flashaddr, val); + } + flashaddr += 2; + } + flashend = flashaddr; + if ((flashaddr & 2)) { + val |= 0xFFFF0000; + flash_write(do_flash_cmd, flashaddr, val); + } + } +} + +/* +void do_flash_cmd(volatile uint8_t *fstat) +{ + *fstat = 0x80; + while ((*fstat & 0x80) == 0) ; // wait +} +00000000 : + 0: 2380 movs r3, #128 ; 0x80 + 2: 7003 strb r3, [r0, #0] + 4: 7803 ldrb r3, [r0, #0] + 6: b25b sxtb r3, r3 + 8: 2b00 cmp r3, #0 + a: dafb bge.n 4 + c: 4770 bx lr +*/ + + +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++); + } +} + +int eeprom_is_ready(void) +{ + return 1; +} + +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++); + } +} + +#else +// No EEPROM supported, so emulate it + +#define EEPROM_SIZE 32 +static uint8_t buffer[EEPROM_SIZE]; + +uint8_t eeprom_read_byte(const uint8_t *addr) { + uint32_t offset = (uint32_t)addr; + return buffer[offset]; +} + +void eeprom_write_byte(uint8_t *addr, uint8_t value) { + uint32_t offset = (uint32_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++); + } +} + +#endif /* chip selection */ +// The update functions just calls write for now, but could probably be optimized + +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/chibios/printf.c b/tmk_core/common/chibios/printf.c new file mode 100644 index 0000000000..72e3d4f8c4 --- /dev/null +++ b/tmk_core/common/chibios/printf.c @@ -0,0 +1,240 @@ +/* + * found at: http://www.sparetimelabs.com/tinyprintf/tinyprintf.php + * and: http://www.sparetimelabs.com/printfrevisited/printfrevisited.php + */ + +/* +File: printf.c + +Copyright (C) 2004 Kustaa Nyholm + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +*/ + +#include "printf.h" + +typedef void (*putcf) (void*,char); +static putcf stdout_putf; +static void* stdout_putp; + +// this adds cca 400 bytes +#define PRINTF_LONG_SUPPORT + +#ifdef PRINTF_LONG_SUPPORT + +static void uli2a(unsigned long int num, unsigned int base, int uc,char * bf) + { + int n=0; + unsigned int d=1; + while (num/d >= base) + d*=base; + while (d!=0) { + int dgt = num / d; + num%=d; + d/=base; + if (n || dgt>0|| d==0) { + *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); + ++n; + } + } + *bf=0; + } + +static void li2a (long num, char * bf) + { + if (num<0) { + num=-num; + *bf++ = '-'; + } + uli2a(num,10,0,bf); + } + +#endif + +static void ui2a(unsigned int num, unsigned int base, int uc,char * bf) + { + int n=0; + unsigned int d=1; + while (num/d >= base) + d*=base; + while (d!=0) { + int dgt = num / d; + num%= d; + d/=base; + if (n || dgt>0 || d==0) { + *bf++ = dgt+(dgt<10 ? '0' : (uc ? 'A' : 'a')-10); + ++n; + } + } + *bf=0; + } + +static void i2a (int num, char * bf) + { + if (num<0) { + num=-num; + *bf++ = '-'; + } + ui2a(num,10,0,bf); + } + +static int a2d(char ch) + { + if (ch>='0' && ch<='9') + return ch-'0'; + else if (ch>='a' && ch<='f') + return ch-'a'+10; + else if (ch>='A' && ch<='F') + return ch-'A'+10; + else return -1; + } + +static char a2i(char ch, char** src,int base,int* nump) + { + char* p= *src; + int num=0; + int digit; + while ((digit=a2d(ch))>=0) { + if (digit>base) break; + num=num*base+digit; + ch=*p++; + } + *src=p; + *nump=num; + return ch; + } + +static void putchw(void* putp,putcf putf,int n, char z, char* bf) + { + char fc=z? '0' : ' '; + char ch; + char* p=bf; + while (*p++ && n > 0) + n--; + while (n-- > 0) + putf(putp,fc); + while ((ch= *bf++)) + putf(putp,ch); + } + +void tfp_format(void* putp,putcf putf,char *fmt, va_list va) + { + char bf[12]; + + char ch; + + + while ((ch=*(fmt++))) { + if (ch!='%') + putf(putp,ch); + else { + char lz=0; +#ifdef PRINTF_LONG_SUPPORT + char lng=0; +#endif + int w=0; + ch=*(fmt++); + if (ch=='0') { + ch=*(fmt++); + lz=1; + } + if (ch>='0' && ch<='9') { + ch=a2i(ch,&fmt,10,&w); + } +#ifdef PRINTF_LONG_SUPPORT + if (ch=='l') { + ch=*(fmt++); + lng=1; + } +#endif + switch (ch) { + case 0: + goto abort; + case 'u' : { +#ifdef PRINTF_LONG_SUPPORT + if (lng) + uli2a(va_arg(va, unsigned long int),10,0,bf); + else +#endif + ui2a(va_arg(va, unsigned int),10,0,bf); + putchw(putp,putf,w,lz,bf); + break; + } + case 'd' : { +#ifdef PRINTF_LONG_SUPPORT + if (lng) + li2a(va_arg(va, unsigned long int),bf); + else +#endif + i2a(va_arg(va, int),bf); + putchw(putp,putf,w,lz,bf); + break; + } + case 'x': case 'X' : +#ifdef PRINTF_LONG_SUPPORT + if (lng) + uli2a(va_arg(va, unsigned long int),16,(ch=='X'),bf); + else +#endif + ui2a(va_arg(va, unsigned int),16,(ch=='X'),bf); + putchw(putp,putf,w,lz,bf); + break; + case 'c' : + putf(putp,(char)(va_arg(va, int))); + break; + case 's' : + putchw(putp,putf,w,0,va_arg(va, char*)); + break; + case '%' : + putf(putp,ch); + default: + break; + } + } + } + abort:; + } + + +void init_printf(void* putp,void (*putf) (void*,char)) + { + stdout_putf=putf; + stdout_putp=putp; + } + +void tfp_printf(char *fmt, ...) + { + va_list va; + va_start(va,fmt); + tfp_format(stdout_putp,stdout_putf,fmt,va); + va_end(va); + } + +static void putcp(void* p,char c) + { + *(*((char**)p))++ = c; + } + + + +void tfp_sprintf(char* s,char *fmt, ...) + { + va_list va; + va_start(va,fmt); + tfp_format(&s,putcp,fmt,va); + putcp(&s,0); + va_end(va); + } diff --git a/tmk_core/common/chibios/printf.h b/tmk_core/common/chibios/printf.h new file mode 100644 index 0000000000..678a100c6e --- /dev/null +++ b/tmk_core/common/chibios/printf.h @@ -0,0 +1,111 @@ +/* + * found at: http://www.sparetimelabs.com/tinyprintf/tinyprintf.php + * and: http://www.sparetimelabs.com/printfrevisited/printfrevisited.php + */ + +/* +File: printf.h + +Copyright (C) 2004 Kustaa Nyholm + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library 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 Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +This library is realy just two files: 'printf.h' and 'printf.c'. + +They provide a simple and small (+200 loc) printf functionality to +be used in embedded systems. + +I've found them so usefull in debugging that I do not bother with a +debugger at all. + +They are distributed in source form, so to use them, just compile them +into your project. + +Two printf variants are provided: printf and sprintf. + +The formats supported by this implementation are: 'd' 'u' 'c' 's' 'x' 'X'. + +Zero padding and field width are also supported. + +If the library is compiled with 'PRINTF_SUPPORT_LONG' defined then the +long specifier is also +supported. Note that this will pull in some long math routines (pun intended!) +and thus make your executable noticably longer. + +The memory foot print of course depends on the target cpu, compiler and +compiler options, but a rough guestimate (based on a H8S target) is about +1.4 kB for code and some twenty 'int's and 'char's, say 60 bytes of stack space. +Not too bad. Your milage may vary. By hacking the source code you can +get rid of some hunred bytes, I'm sure, but personally I feel the balance of +functionality and flexibility versus code size is close to optimal for +many embedded systems. + +To use the printf you need to supply your own character output function, +something like : + + void putc ( void* p, char c) + { + while (!SERIAL_PORT_EMPTY) ; + SERIAL_PORT_TX_REGISTER = c; + } + +Before you can call printf you need to initialize it to use your +character output function with something like: + + init_printf(NULL,putc); + +Notice the 'NULL' in 'init_printf' and the parameter 'void* p' in 'putc', +the NULL (or any pointer) you pass into the 'init_printf' will eventually be +passed to your 'putc' routine. This allows you to pass some storage space (or +anything realy) to the character output function, if necessary. +This is not often needed but it was implemented like that because it made +implementing the sprintf function so neat (look at the source code). + +The code is re-entrant, except for the 'init_printf' function, so it +is safe to call it from interupts too, although this may result in mixed output. +If you rely on re-entrancy, take care that your 'putc' function is re-entrant! + +The printf and sprintf functions are actually macros that translate to +'tfp_printf' and 'tfp_sprintf'. This makes it possible +to use them along with 'stdio.h' printf's in a single source file. +You just need to undef the names before you include the 'stdio.h'. +Note that these are not function like macros, so if you have variables +or struct members with these names, things will explode in your face. +Without variadic macros this is the best we can do to wrap these +fucnction. If it is a problem just give up the macros and use the +functions directly or rename them. + +For further details see source code. + +regs Kusti, 23.10.2004 +*/ + + +#ifndef __TFP_PRINTF__ +#define __TFP_PRINTF__ + +#include + +void init_printf(void* putp,void (*putf) (void*,char)); + +void tfp_printf(char *fmt, ...); +void tfp_sprintf(char* s,char *fmt, ...); + +void tfp_format(void* putp,void (*putf) (void*,char),char *fmt, va_list va); + +#define printf tfp_printf +#define sprintf tfp_sprintf + +#endif diff --git a/tmk_core/common/chibios/sleep_led.c b/tmk_core/common/chibios/sleep_led.c new file mode 100644 index 0000000000..4c35cfcbac --- /dev/null +++ b/tmk_core/common/chibios/sleep_led.c @@ -0,0 +1,226 @@ +#include "ch.h" +#include "hal.h" + +#include "led.h" +#include "sleep_led.h" + +/* 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 + * + * http://www.wolframalpha.com/input/?i=%28sin%28+x%2F64*pi%29**8+*+255%2C+x%3D0+to+63 + * (0..63).each {|x| p ((sin(x/64.0*PI)**8)*255).to_i } + */ +static const uint8_t breathing_table[64] = { +0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 10, +15, 23, 32, 44, 58, 74, 93, 113, 135, 157, 179, 199, 218, 233, 245, 252, +255, 252, 245, 233, 218, 199, 179, 157, 135, 113, 93, 74, 58, 44, 32, 23, +15, 10, 6, 4, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +/* interrupt handler */ +OSAL_IRQ_HANDLER(TIMER_INTERRUPT_VECTOR) { + OSAL_IRQ_PROLOGUE(); + + /* Software PWM + * timer:1111 1111 1111 1111 + * \_____/\/ \_______/____ count(0-255) + * \ \______________ duration of step(4) + * \__________________ index of step table(0-63) + */ + + // this works for cca 65536 irqs/sec + static union { + uint16_t row; + struct { + uint8_t count:8; + uint8_t duration:2; + uint8_t index:6; + } pwm; + } timer = { .row = 0 }; + + timer.row++; + + // LED on + if (timer.pwm.count == 0) { + led_set(1<SCGC5 |= SIM_SCGC5_LPTMR; + /* Reset LPTMR settings */ + LPTMR0->CSR = 0; + /* Set the compare value */ + LPTMR0->CMR = 0; // trigger on counter value (i.e. every time) + + /* Set up clock source and prescaler */ + /* Software PWM + * ______ ______ __ + * | ON |___OFF___| ON |___OFF___| .... + * |<-------------->|<-------------->|<- .... + * PWM period PWM period + * + * R interrupts/period[resolution] + * F periods/second[frequency] + * R * F interrupts/second + */ + + /* === OPTION 1 === */ + #if 0 + // 1kHz LPO + // No prescaler => 1024 irqs/sec + // Note: this is too slow for a smooth breathe + LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_LPO)|LPTMRx_PSR_PBYP; + #endif /* OPTION 1 */ + + /* === OPTION 2 === */ + #if 1 + // nMHz IRC (n=4 on KL25Z, KL26Z and K20x; n=2 or 8 on KL27Z) + MCG->C2 |= MCG_C2_IRCS; // fast (4MHz) internal ref clock + #if defined(KL27) // divide the 8MHz IRC by 2, to have the same MCGIRCLK speed as others + MCG->MC |= MCG_MC_LIRC_DIV2_DIV2; + #endif /* KL27 */ + MCG->C1 |= MCG_C1_IRCLKEN; // enable internal ref clock + // to work in stop mode, also MCG_C1_IREFSTEN + // Divide 4MHz by 2^N (N=6) => 62500 irqs/sec => + // => approx F=61, R=256, duration = 4 + LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_MCGIRCLK)|LPTMRx_PSR_PRESCALE(6); + #endif /* OPTION 2 */ + + /* === OPTION 3 === */ + #if 0 + // OSC output (external crystal), usually 8MHz or 16MHz + OSC0->CR |= OSC_CR_ERCLKEN; // enable ext ref clock + // to work in stop mode, also OSC_CR_EREFSTEN + // Divide by 2^N + LPTMR0->PSR = LPTMRx_PSR_PCS(LPTMR_CLOCK_OSCERCLK)|LPTMRx_PSR_PRESCALE(7); + #endif /* OPTION 3 */ + /* === END OPTIONS === */ + + /* Interrupt on TCF set (compare flag) */ + nvicEnableVector(LPTMR0_IRQn, 2); // vector, priority + LPTMR0->CSR |= LPTMRx_CSR_TIE; +} + +void sleep_led_enable(void) { + /* Enable the timer */ + LPTMR0->CSR |= LPTMRx_CSR_TEN; +} + +void sleep_led_disable(void) { + /* Disable the timer */ + LPTMR0->CSR &= ~LPTMRx_CSR_TEN; +} + +void sleep_led_toggle(void) { + /* Toggle the timer */ + LPTMR0->CSR ^= LPTMRx_CSR_TEN; +} + +#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) { +} + +void sleep_led_enable(void) { + led_set(1<. */ #include #include -#include +#include "wait.h" #include "keycode.h" #include "host.h" #include "keymap.h" @@ -103,12 +103,14 @@ bool command_proc(uint8_t code) bool command_extra(uint8_t code) __attribute__ ((weak)); bool command_extra(uint8_t code) { + (void)code; return false; } bool command_console_extra(uint8_t code) __attribute__ ((weak)); bool command_console_extra(uint8_t code) { + (void)code; return false; } @@ -217,8 +219,11 @@ static void print_version(void) " " STR(BOOTLOADER_SIZE) "\n"); print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__) +#if defined(__AVR__) " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ - " AVR_ARCH: avr" STR(__AVR_ARCH__) "\n"); + " AVR_ARCH: avr" STR(__AVR_ARCH__) +#endif + "\n"); return; } @@ -234,7 +239,7 @@ static void print_status(void) #ifdef NKRO_ENABLE print_val_hex8(keyboard_nkro); #endif - print_val_hex32(timer_count); + print_val_hex32(timer_read32()); #ifdef PROTOCOL_PJRC print_val_hex8(UDCON); @@ -360,7 +365,7 @@ static bool command_common(uint8_t code) stop_all_notes(); shutdown_user(); #else - _delay_ms(1000); + wait_ms(1000); #endif bootloader_jump(); // not return break; @@ -430,10 +435,11 @@ static bool command_common(uint8_t code) case MAGIC_KC(MAGIC_KEY_NKRO): clear_keyboard(); // clear to prevent stuck keys keyboard_nkro = !keyboard_nkro; - if (keyboard_nkro) + if (keyboard_nkro) { print("NKRO: on\n"); - else + } else { print("NKRO: off\n"); + } break; #endif @@ -750,10 +756,11 @@ static bool mousekey_console(uint8_t code) print("?"); return false; } - if (mousekey_param) + if (mousekey_param) { xprintf("M%d> ", mousekey_param); - else + } else { print("M>" ); + } return true; } #endif diff --git a/tmk_core/common/avr/eeconfig.c b/tmk_core/common/eeconfig.c similarity index 98% rename from tmk_core/common/avr/eeconfig.c rename to tmk_core/common/eeconfig.c index 656938fb33..140d2b85bb 100644 --- a/tmk_core/common/avr/eeconfig.c +++ b/tmk_core/common/eeconfig.c @@ -1,6 +1,6 @@ #include #include -#include +#include "eeprom.h" #include "eeconfig.h" void eeconfig_init(void) diff --git a/tmk_core/common/eeprom.h b/tmk_core/common/eeprom.h new file mode 100644 index 0000000000..2cc2ccee3f --- /dev/null +++ b/tmk_core/common/eeprom.h @@ -0,0 +1,22 @@ +#ifndef TMK_CORE_COMMON_EEPROM_H_ +#define TMK_CORE_COMMON_EEPROM_H_ + +#if defined(__AVR__) +#include +#else +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); +void eeprom_read_block (void *__dst, const void *__src, uint32_t __n); +void eeprom_write_byte (uint8_t *__p, uint8_t __value); +void eeprom_write_word (uint16_t *__p, uint16_t __value); +void eeprom_write_dword (uint32_t *__p, uint32_t __value); +void eeprom_write_block (const void *__src, void *__dst, uint32_t __n); +void eeprom_update_byte (uint8_t *__p, uint8_t __value); +void eeprom_update_word (uint16_t *__p, uint16_t __value); +void eeprom_update_dword (uint32_t *__p, uint32_t __value); +void eeprom_update_block (const void *__src, void *__dst, uint32_t __n); +#endif + + +#endif /* TMK_CORE_COMMON_EEPROM_H_ */ diff --git a/tmk_core/common/magic.c b/tmk_core/common/magic.c index f21d1346c7..194e4cc026 100644 --- a/tmk_core/common/magic.c +++ b/tmk_core/common/magic.c @@ -1,6 +1,8 @@ #include #include +#if defined(__AVR__) #include +#endif #include "matrix.h" #include "bootloader.h" #include "debug.h" @@ -33,4 +35,4 @@ void magic(void) default_layer = eeconfig_read_default_layer(); default_layer_set((uint32_t)default_layer); -} \ No newline at end of file +} diff --git a/tmk_core/common/print.c b/tmk_core/common/print.c index ca94e1e5d6..00489557f2 100644 --- a/tmk_core/common/print.c +++ b/tmk_core/common/print.c @@ -38,11 +38,15 @@ void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) xdev_out(sendchar_func); } -#elif defined(__arm__) +#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ + +// don't need anything extra + +#elif defined(__arm__) /* __AVR__ */ // TODO //void print_set_sendchar(int8_t (*sendchar_func)(uint8_t)) { } -#endif +#endif /* __AVR__ */ #endif diff --git a/tmk_core/common/print.h b/tmk_core/common/print.h index 4f3dde65aa..0368bcd4a1 100644 --- a/tmk_core/common/print.h +++ b/tmk_core/common/print.h @@ -47,7 +47,15 @@ extern "C" /* function pointer of sendchar to be used by print utility */ void print_set_sendchar(int8_t (*print_sendchar_func)(uint8_t)); -#elif defined(__arm__) +#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ + +#include "chibios/printf.h" + +#define print(s) printf(s) +#define println(s) printf(s "\r\n") +#define xprintf printf + +#elif defined(__arm__) /* __AVR__ */ #include "mbed/xprintf.h" diff --git a/tmk_core/common/progmem.h b/tmk_core/common/progmem.h index 199b1bedfe..5b27656250 100644 --- a/tmk_core/common/progmem.h +++ b/tmk_core/common/progmem.h @@ -5,8 +5,8 @@ # include #elif defined(__arm__) # define PROGMEM -# define pgm_read_byte(p) *(p) -# define pgm_read_word(p) *(p) +# define pgm_read_byte(p) *((unsigned char*)p) +# define pgm_read_word(p) *((uint16_t*)p) #endif #endif diff --git a/tmk_core/common/report.h b/tmk_core/common/report.h index f6c0a315de..0c799eca39 100644 --- a/tmk_core/common/report.h +++ b/tmk_core/common/report.h @@ -84,6 +84,11 @@ along with this program. If not, see . # define KEYBOARD_REPORT_SIZE NKRO_EPSIZE # define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2) # define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) +#elif defined(PROTOCOL_CHIBIOS) && defined(NKRO_ENABLE) +# include "protocol/chibios/usb_main.h" +# define KEYBOARD_REPORT_SIZE NKRO_EPSIZE +# define KEYBOARD_REPORT_KEYS (NKRO_EPSIZE - 2) +# define KEYBOARD_REPORT_BITS (NKRO_EPSIZE - 1) #else # define KEYBOARD_REPORT_SIZE 8 diff --git a/tmk_core/common/wait.h b/tmk_core/common/wait.h index 40d00b0c75..82727be012 100644 --- a/tmk_core/common/wait.h +++ b/tmk_core/common/wait.h @@ -9,9 +9,13 @@ extern "C" { # include # define wait_ms(ms) _delay_ms(ms) # define wait_us(us) _delay_us(us) -#elif defined(__arm__) +#elif defined(PROTOCOL_CHIBIOS) /* __AVR__ */ +# include "ch.h" +# define wait_ms(ms) chThdSleepMilliseconds(ms) +# define wait_us(us) chThdSleepMicroseconds(us) +#elif defined(__arm__) /* __AVR__ */ # include "wait_api.h" -#endif +#endif /* __AVR__ */ #ifdef __cplusplus } diff --git a/tmk_core/protocol/chibios.mk b/tmk_core/protocol/chibios.mk new file mode 100644 index 0000000000..3f4e0a71fc --- /dev/null +++ b/tmk_core/protocol/chibios.mk @@ -0,0 +1,10 @@ +PROTOCOL_DIR = protocol +CHIBIOS_DIR = $(PROTOCOL_DIR)/chibios + + +SRC += $(CHIBIOS_DIR)/usb_main.c +SRC += $(CHIBIOS_DIR)/main.c + +VPATH += $(TMK_PATH)/$(PROTOCOL_DIR) +VPATH += $(TMK_PATH)/$(CHIBIOS_DIR) + diff --git a/tmk_core/protocol/chibios/README.md b/tmk_core/protocol/chibios/README.md new file mode 100644 index 0000000000..63e6641f82 --- /dev/null +++ b/tmk_core/protocol/chibios/README.md @@ -0,0 +1,55 @@ +## TMK running on top of ChibiOS + +This code can be used to run TMK keyboard logic on top of [ChibiOS], meaning that you can run TMK on whatever [ChibiOS] supports. The notable examples are ARM-based Teensies (3.x and LC) and on the boards with STM32 MCUs. + +### Usage + +- To use, [get a zip of chibios](https://github.com/ChibiOS/ChibiOS/archive/a7df9a891067621e8e1a5c2a2c0ceada82403afe.zip) and unpack/rename it to `tmk_core/tool/chibios/chibios`; or you can just clone [the repo](https://github.com/ChibiOS/ChibiOS) there. For Freescale/NXP Kinetis support (meaning ARM Teensies and the Infinity keyboard), you'll also need [a zip of chibios-contrib](https://github.com/ChibiOS/ChibiOS-Contrib/archive/e1311c4db6cd366cf760673f769e925741ac0ad3.zip), unpacked/renamed to `tmk_core/tool/chibios/chibios-contrib`. Likewise, for git-savvy people, just clone [the repo](https://github.com/ChibiOS/ChibiOS-Contrib) there. +- Note: the abovementioned directories are the defaults. You can have the two chibios repositories wherever you want, just define their location in `CHIBIOS` and `CHIBIOS_CONTRIB` variables in your `Makefile`. +- You will also need to install an ARM toolchain, for instance from [here](https://launchpad.net/gcc-arm-embedded). On linux, this is usually also present as a package for your distribution (as `gcc-arm` or something similar). On OS X, you can use [homebrew](http://brew.sh/) with an appropriate tap. + +### Notes + +- Some comments about ChibiOS syntax and the most commonly used GPIO functions are, as well as an example for ARM Teensies, is [here](https://github.com/tmk/tmk_keyboard/blob/master/keyboard/teensy_lc_onekey/instructions.md). +- For gcc options, inspect `tmk_core/tool/chibios/chibios.mk`. For instance, I enabled `-Wno-missing-field-initializers`, because TMK common bits generated a lot of warnings on that. +- For debugging, it is sometimes useful disable gcc optimisations, you can do that by adding `-O0` to `OPT_DEFS` in your `Makefile`. +- USB string descriptors are messy. I did not find a way to cleanly generate the right structures from actual strings, so the definitions in individual keyboards' `config.h` are ugly as heck. +- It is easy to add some code for testing (e.g. blink LED, do stuff on button press, etc...) - just create another thread in `main.c`, it will run independently of the keyboard business. +- 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.) In any case, there are no problems for Teensies. + + +### Immediate todo + +- power saving for suspend + +### Not tested, but possibly working + +- backlight + +### Missing / not working (TMK vs ChibiOS bits) + +- eeprom / bootmagic for STM32 (will be chip dependent; eeprom needs to be emulated in flash, which means less writes; wear-levelling?) There is a semi-official ST "driver" for eeprom, with wear-levelling, but I think it consumes a lot of RAM (like 2 pages, i.e. 1kB or so). + +### Tried with + +- 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 + +- Pretty much all STM32 chips. +- K20x and KL2x Freescale/NXP chips (i.e. Teensy 3.x/LC, mchck, FRDM-KL2{5,6}Z, FRDM-K20D50M), via the [ChibiOS-Contrib](https://github.com/ChibiOS/ChibiOS-Contrib) repository. +- There is also support for AVR8, but the USB stack is not implemented for them yet (some news on that front recently though), and also the kernel itself takes about 1k of RAM. I think people managed to get ChibiOS running on atmega32[8p/u4] though. +- There is also support for Nordic NRF51822 (the chip in Adafruit's Bluefruit bluetooth-low-energy boards), but be aware that that chip does *not* have USB, and the BLE softdevice (i.e. Bluetooth) is not supported directly at the moment. + +## STM32-based keyboard design considerations + +- 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. +- There is a working example of a STM32F042-based keyboard: [firmware here](https://github.com/flabbergast/flabber_kbs/tree/master/kb45p) and [hardware (kicad) here](https://github.com/flabbergast/kicad/tree/master/kb45p). You can check this example firmware for custom board files, and a more complicated matrix than just one key. + + + +[ChibiOS]: http://chibios.org diff --git a/tmk_core/protocol/chibios/main.c b/tmk_core/protocol/chibios/main.c new file mode 100644 index 0000000000..54bb6a8f55 --- /dev/null +++ b/tmk_core/protocol/chibios/main.c @@ -0,0 +1,147 @@ +/* + * (c) 2015 flabberast + * + * Based on the following work: + * - Guillaume Duc's raw hid example (MIT License) + * https://github.com/guiduc/usb-hid-chibios-example + * - PJRC Teensy examples (MIT License) + * https://www.pjrc.com/teensy/usb_keyboard.html + * - hasu's TMK keyboard code (GPL v2 and some code Modified BSD) + * https://github.com/tmk/tmk_keyboard/ + * - ChibiOS demo code (Apache 2.0 License) + * http://www.chibios.org + * + * Since some GPL'd code is used, this work is licensed under + * GPL v2 or later. + */ + +#include "ch.h" +#include "hal.h" + +#include "usb_main.h" + +/* TMK includes */ +#include "report.h" +#include "host.h" +#include "host_driver.h" +#include "keyboard.h" +#include "action.h" +#include "action_util.h" +#include "mousekey.h" +#include "led.h" +#include "sendchar.h" +#include "debug.h" +#include "printf.h" +#ifdef SLEEP_LED_ENABLE +#include "sleep_led.h" +#endif +#include "suspend.h" + + +/* ------------------------- + * TMK host driver defs + * ------------------------- + */ + +/* declarations */ +uint8_t keyboard_leds(void); +void send_keyboard(report_keyboard_t *report); +void send_mouse(report_mouse_t *report); +void send_system(uint16_t data); +void send_consumer(uint16_t data); + +/* host struct */ +host_driver_t chibios_driver = { + keyboard_leds, + send_keyboard, + send_mouse, + send_system, + send_consumer +}; + + +/* TESTING + * Amber LED blinker thread, times are in milliseconds. + */ +/* set this variable to non-zero anywhere to blink once */ +// uint8_t blinkLed = 0; +// static THD_WORKING_AREA(waBlinkerThread, 128); +// static THD_FUNCTION(blinkerThread, arg) { +// (void)arg; +// chRegSetThreadName("blinkOrange"); +// while(true) { +// if(blinkLed) { +// blinkLed = 0; +// palSetPad(TEENSY_PIN13_IOPORT, TEENSY_PIN13); +// chThdSleepMilliseconds(100); +// palClearPad(TEENSY_PIN13_IOPORT, TEENSY_PIN13); +// } +// chThdSleepMilliseconds(100); +// } +// } + + + +/* Main thread + */ +int main(void) { + /* ChibiOS/RT init */ + halInit(); + chSysInit(); + + // TESTING + // chThdCreateStatic(waBlinkerThread, sizeof(waBlinkerThread), NORMALPRIO, blinkerThread, NULL); + + /* Init USB */ + init_usb_driver(&USB_DRIVER); + + /* init printf */ + init_printf(NULL,sendchar_pf); + + /* Wait until the USB is active */ + while(USB_DRIVER.state != USB_ACTIVE) + chThdSleepMilliseconds(50); + + /* Do need to wait here! + * Otherwise the next print might start a transfer on console EP + * before the USB is completely ready, which sometimes causes + * HardFaults. + */ + chThdSleepMilliseconds(50); + + print("USB configured.\n"); + + /* init TMK modules */ + keyboard_init(); + host_set_driver(&chibios_driver); + +#ifdef SLEEP_LED_ENABLE + sleep_led_init(); +#endif + + print("Keyboard start.\n"); + + /* 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); + } + } + /* Woken up */ + // variables has been already cleared by the wakeup hook + send_keyboard_report(); +#ifdef MOUSEKEY_ENABLE + mousekey_send(); +#endif /* MOUSEKEY_ENABLE */ + } + + keyboard_task(); + } +} diff --git a/tmk_core/protocol/chibios/usb_main.c b/tmk_core/protocol/chibios/usb_main.c new file mode 100644 index 0000000000..e2c9d9bf14 --- /dev/null +++ b/tmk_core/protocol/chibios/usb_main.c @@ -0,0 +1,1372 @@ +/* + * (c) 2015 flabberast + * + * Based on the following work: + * - Guillaume Duc's raw hid example (MIT License) + * https://github.com/guiduc/usb-hid-chibios-example + * - PJRC Teensy examples (MIT License) + * https://www.pjrc.com/teensy/usb_keyboard.html + * - hasu's TMK keyboard code (GPL v2 and some code Modified BSD) + * https://github.com/tmk/tmk_keyboard/ + * - ChibiOS demo code (Apache 2.0 License) + * http://www.chibios.org + * + * Since some GPL'd code is used, this work is licensed under + * GPL v2 or later. + */ + +#include "ch.h" +#include "hal.h" + +#include "usb_main.h" + +#include "host.h" +#include "debug.h" +#include "suspend.h" +#ifdef SLEEP_LED_ENABLE +#include "sleep_led.h" +#include "led.h" +#endif + +/* --------------------------------------------------------- + * Global interface variables and declarations + * --------------------------------------------------------- + */ + +uint8_t keyboard_idle __attribute__((aligned(2))) = 0; +uint8_t keyboard_protocol __attribute__((aligned(2))) = 1; +uint16_t keyboard_led_stats __attribute__((aligned(2))) = 0; +volatile uint16_t keyboard_idle_count = 0; +static virtual_timer_t keyboard_idle_timer; +static void keyboard_idle_timer_cb(void *arg); +#ifdef NKRO_ENABLE +extern bool keyboard_nkro; +#endif /* NKRO_ENABLE */ + +report_keyboard_t keyboard_report_sent = {{0}}; +#ifdef MOUSE_ENABLE +report_mouse_t mouse_report_blank = {0}; +#endif /* MOUSE_ENABLE */ +#ifdef EXTRAKEY_ENABLE +uint8_t extra_report_blank[3] = {0}; +#endif /* EXTRAKEY_ENABLE */ + +#ifdef CONSOLE_ENABLE +/* The emission buffers queue */ +output_buffers_queue_t console_buf_queue; +static uint8_t console_queue_buffer[BQ_BUFFER_SIZE(CONSOLE_QUEUE_CAPACITY, CONSOLE_EPSIZE)]; + +static virtual_timer_t console_flush_timer; +void console_queue_onotify(io_buffers_queue_t *bqp); +static void console_flush_cb(void *arg); +#endif /* CONSOLE_ENABLE */ + +/* --------------------------------------------------------- + * Descriptors and USB driver objects + * --------------------------------------------------------- + */ + +/* HID specific constants */ +#define USB_DESCRIPTOR_HID 0x21 +#define USB_DESCRIPTOR_HID_REPORT 0x22 +#define HID_GET_REPORT 0x01 +#define HID_GET_IDLE 0x02 +#define HID_GET_PROTOCOL 0x03 +#define HID_SET_REPORT 0x09 +#define HID_SET_IDLE 0x0A +#define HID_SET_PROTOCOL 0x0B + +/* USB Device Descriptor */ +static const uint8_t usb_device_descriptor_data[] = { + USB_DESC_DEVICE(0x0200, // bcdUSB (1.1) + 0, // bDeviceClass (defined in later in interface) + 0, // bDeviceSubClass + 0, // bDeviceProtocol + 64, // bMaxPacketSize (64 bytes) (the driver didn't work with 32) + VENDOR_ID, // idVendor + PRODUCT_ID, // idProduct + DEVICE_VER, // bcdDevice + 1, // iManufacturer + 2, // iProduct + 3, // iSerialNumber + 1) // bNumConfigurations +}; + +/* Device Descriptor wrapper */ +static const USBDescriptor usb_device_descriptor = { + sizeof usb_device_descriptor_data, + usb_device_descriptor_data +}; + +/* + * HID Report Descriptor + * + * See "Device Class Definition for Human Interface Devices (HID)" + * (http://www.usb.org/developers/hidpage/HID1_11.pdf) for the + * detailed descrition of all the fields + */ + +/* Keyboard Protocol 1, HID 1.11 spec, Appendix B, page 59-60 */ +static const uint8_t keyboard_hid_report_desc_data[] = { + 0x05, 0x01, // Usage Page (Generic Desktop), + 0x09, 0x06, // Usage (Keyboard), + 0xA1, 0x01, // Collection (Application), + 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0xE0, // Usage Minimum (224), + 0x29, 0xE7, // Usage Maximum (231), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte + 0x95, 0x01, // Report Count (1), + 0x75, 0x08, // Report Size (8), + 0x81, 0x03, // Input (Constant), ;Reserved byte + 0x95, 0x05, // Report Count (5), + 0x75, 0x01, // Report Size (1), + 0x05, 0x08, // Usage Page (LEDs), + 0x19, 0x01, // Usage Minimum (1), + 0x29, 0x05, // Usage Maximum (5), + 0x91, 0x02, // Output (Data, Variable, Absolute), ;LED report + 0x95, 0x01, // Report Count (1), + 0x75, 0x03, // Report Size (3), + 0x91, 0x03, // Output (Constant), ;LED report padding + 0x95, KBD_REPORT_KEYS, // Report Count (), + 0x75, 0x08, // Report Size (8), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0xFF, // Logical Maximum(255), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x00, // Usage Minimum (0), + 0x29, 0xFF, // Usage Maximum (255), + 0x81, 0x00, // Input (Data, Array), + 0xc0 // End Collection +}; +/* wrapper */ +static const USBDescriptor keyboard_hid_report_descriptor = { + sizeof keyboard_hid_report_desc_data, + keyboard_hid_report_desc_data +}; + +#ifdef NKRO_ENABLE +static const uint8_t nkro_hid_report_desc_data[] = { + 0x05, 0x01, // Usage Page (Generic Desktop), + 0x09, 0x06, // Usage (Keyboard), + 0xA1, 0x01, // Collection (Application), + // bitmap of modifiers + 0x75, 0x01, // Report Size (1), + 0x95, 0x08, // Report Count (8), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0xE0, // Usage Minimum (224), + 0x29, 0xE7, // Usage Maximum (231), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum (1), + 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte + // LED output report + 0x95, 0x05, // Report Count (5), + 0x75, 0x01, // Report Size (1), + 0x05, 0x08, // Usage Page (LEDs), + 0x19, 0x01, // Usage Minimum (1), + 0x29, 0x05, // Usage Maximum (5), + 0x91, 0x02, // Output (Data, Variable, Absolute), + 0x95, 0x01, // Report Count (1), + 0x75, 0x03, // Report Size (3), + 0x91, 0x03, // Output (Constant), + // bitmap of keys + 0x95, NKRO_REPORT_KEYS * 8, // Report Count (), + 0x75, 0x01, // Report Size (1), + 0x15, 0x00, // Logical Minimum (0), + 0x25, 0x01, // Logical Maximum(1), + 0x05, 0x07, // Usage Page (Key Codes), + 0x19, 0x00, // Usage Minimum (0), + 0x29, NKRO_REPORT_KEYS * 8 - 1, // Usage Maximum (), + 0x81, 0x02, // Input (Data, Variable, Absolute), + 0xc0 // End Collection +}; +/* wrapper */ +static const USBDescriptor nkro_hid_report_descriptor = { + sizeof nkro_hid_report_desc_data, + nkro_hid_report_desc_data +}; +#endif /* NKRO_ENABLE */ + +#ifdef MOUSE_ENABLE +/* Mouse Protocol 1, HID 1.11 spec, Appendix B, page 59-60, with wheel extension + * http://www.microchip.com/forums/tm.aspx?high=&m=391435&mpage=1#391521 + * http://www.keil.com/forum/15671/ + * http://www.microsoft.com/whdc/device/input/wheel.mspx */ +static const uint8_t mouse_hid_report_desc_data[] = { + /* mouse */ + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x02, // USAGE (Mouse) + 0xa1, 0x01, // COLLECTION (Application) + //0x85, REPORT_ID_MOUSE, // REPORT_ID (1) + 0x09, 0x01, // USAGE (Pointer) + 0xa1, 0x00, // COLLECTION (Physical) + // ---------------------------- Buttons + 0x05, 0x09, // USAGE_PAGE (Button) + 0x19, 0x01, // USAGE_MINIMUM (Button 1) + 0x29, 0x05, // USAGE_MAXIMUM (Button 5) + 0x15, 0x00, // LOGICAL_MINIMUM (0) + 0x25, 0x01, // LOGICAL_MAXIMUM (1) + 0x75, 0x01, // REPORT_SIZE (1) + 0x95, 0x05, // REPORT_COUNT (5) + 0x81, 0x02, // INPUT (Data,Var,Abs) + 0x75, 0x03, // REPORT_SIZE (3) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x03, // INPUT (Cnst,Var,Abs) + // ---------------------------- X,Y position + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x30, // USAGE (X) + 0x09, 0x31, // USAGE (Y) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x02, // REPORT_COUNT (2) + 0x81, 0x06, // INPUT (Data,Var,Rel) + // ---------------------------- Vertical wheel + 0x09, 0x38, // USAGE (Wheel) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + 0x35, 0x00, // PHYSICAL_MINIMUM (0) - reset physical + 0x45, 0x00, // PHYSICAL_MAXIMUM (0) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x06, // INPUT (Data,Var,Rel) + // ---------------------------- Horizontal wheel + 0x05, 0x0c, // USAGE_PAGE (Consumer Devices) + 0x0a, 0x38, 0x02, // USAGE (AC Pan) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + 0x75, 0x08, // REPORT_SIZE (8) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xc0, // END_COLLECTION + 0xc0, // END_COLLECTION +}; +/* wrapper */ +static const USBDescriptor mouse_hid_report_descriptor = { + sizeof mouse_hid_report_desc_data, + mouse_hid_report_desc_data +}; +#endif /* MOUSE_ENABLE */ + +#ifdef CONSOLE_ENABLE +static const uint8_t console_hid_report_desc_data[] = { + 0x06, 0x31, 0xFF, // Usage Page 0xFF31 (vendor defined) + 0x09, 0x74, // Usage 0x74 + 0xA1, 0x53, // Collection 0x53 + 0x75, 0x08, // report size = 8 bits + 0x15, 0x00, // logical minimum = 0 + 0x26, 0xFF, 0x00, // logical maximum = 255 + 0x95, CONSOLE_EPSIZE, // report count + 0x09, 0x75, // usage + 0x81, 0x02, // Input (array) + 0xC0 // end collection +}; +/* wrapper */ +static const USBDescriptor console_hid_report_descriptor = { + sizeof console_hid_report_desc_data, + console_hid_report_desc_data +}; +#endif /* CONSOLE_ENABLE */ + +#ifdef EXTRAKEY_ENABLE +/* audio controls & system controls + * http://www.microsoft.com/whdc/archive/w2kbd.mspx */ +static const uint8_t extra_hid_report_desc_data[] = { + /* system control */ + 0x05, 0x01, // USAGE_PAGE (Generic Desktop) + 0x09, 0x80, // USAGE (System Control) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, REPORT_ID_SYSTEM, // REPORT_ID (2) + 0x15, 0x01, // LOGICAL_MINIMUM (0x1) + 0x25, 0xb7, // LOGICAL_MAXIMUM (0xb7) + 0x19, 0x01, // USAGE_MINIMUM (0x1) + 0x29, 0xb7, // USAGE_MAXIMUM (0xb7) + 0x75, 0x10, // REPORT_SIZE (16) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x00, // INPUT (Data,Array,Abs) + 0xc0, // END_COLLECTION + /* consumer */ + 0x05, 0x0c, // USAGE_PAGE (Consumer Devices) + 0x09, 0x01, // USAGE (Consumer Control) + 0xa1, 0x01, // COLLECTION (Application) + 0x85, REPORT_ID_CONSUMER, // REPORT_ID (3) + 0x15, 0x01, // LOGICAL_MINIMUM (0x1) + 0x26, 0x9c, 0x02, // LOGICAL_MAXIMUM (0x29c) + 0x19, 0x01, // USAGE_MINIMUM (0x1) + 0x2a, 0x9c, 0x02, // USAGE_MAXIMUM (0x29c) + 0x75, 0x10, // REPORT_SIZE (16) + 0x95, 0x01, // REPORT_COUNT (1) + 0x81, 0x00, // INPUT (Data,Array,Abs) + 0xc0, // END_COLLECTION +}; +/* wrapper */ +static const USBDescriptor extra_hid_report_descriptor = { + sizeof extra_hid_report_desc_data, + extra_hid_report_desc_data +}; +#endif /* EXTRAKEY_ENABLE */ + + +/* + * Configuration Descriptor tree for a HID device + * + * The HID Specifications version 1.11 require the following order: + * - Configuration Descriptor + * - Interface Descriptor + * - HID Descriptor + * - Endpoints Descriptors + */ +#define KBD_HID_DESC_NUM 0 +#define KBD_HID_DESC_OFFSET (9 + (9 + 9 + 7) * KBD_HID_DESC_NUM + 9) + +#ifdef MOUSE_ENABLE +# define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 1) +# define MOUSE_HID_DESC_OFFSET (9 + (9 + 9 + 7) * MOUSE_HID_DESC_NUM + 9) +#else /* MOUSE_ENABLE */ +# define MOUSE_HID_DESC_NUM (KBD_HID_DESC_NUM + 0) +#endif /* MOUSE_ENABLE */ + +#ifdef CONSOLE_ENABLE +#define CONSOLE_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 1) +#define CONSOLE_HID_DESC_OFFSET (9 + (9 + 9 + 7) * CONSOLE_HID_DESC_NUM + 9) +#else /* CONSOLE_ENABLE */ +# define CONSOLE_HID_DESC_NUM (MOUSE_HID_DESC_NUM + 0) +#endif /* CONSOLE_ENABLE */ + +#ifdef EXTRAKEY_ENABLE +# define EXTRA_HID_DESC_NUM (CONSOLE_HID_DESC_NUM + 1) +# define EXTRA_HID_DESC_OFFSET (9 + (9 + 9 + 7) * EXTRA_HID_DESC_NUM + 9) +#else /* EXTRAKEY_ENABLE */ +# define EXTRA_HID_DESC_NUM (CONSOLE_HID_DESC_NUM + 0) +#endif /* EXTRAKEY_ENABLE */ + +#ifdef NKRO_ENABLE +# define NKRO_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 1) +# define NKRO_HID_DESC_OFFSET (9 + (9 + 9 + 7) * EXTRA_HID_DESC_NUM + 9) +#else /* NKRO_ENABLE */ +# define NKRO_HID_DESC_NUM (EXTRA_HID_DESC_NUM + 0) +#endif /* NKRO_ENABLE */ + +#define NUM_INTERFACES (NKRO_HID_DESC_NUM + 1) +#define CONFIG1_DESC_SIZE (9 + (9 + 9 + 7) * NUM_INTERFACES) + +static const uint8_t hid_configuration_descriptor_data[] = { + /* Configuration Descriptor (9 bytes) USB spec 9.6.3, page 264-266, Table 9-10 */ + USB_DESC_CONFIGURATION(CONFIG1_DESC_SIZE, // wTotalLength + NUM_INTERFACES, // bNumInterfaces + 1, // bConfigurationValue + 0, // iConfiguration + 0xA0, // bmAttributes (RESERVED|REMOTEWAKEUP) + 50), // bMaxPower (50mA) + + /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */ + USB_DESC_INTERFACE(KBD_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass: HID + 0x01, // bInterfaceSubClass: Boot + 0x01, // bInterfaceProtocol: Keyboard + 0), // iInterface + + /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */ + USB_DESC_BYTE(9), // bLength + USB_DESC_BYTE(0x21), // bDescriptorType (HID class) + USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11 + USB_DESC_BYTE(0), // bCountryCode + USB_DESC_BYTE(1), // bNumDescriptors + USB_DESC_BYTE(0x22), // bDescriptorType (report desc) + USB_DESC_WORD(sizeof(keyboard_hid_report_desc_data)), // wDescriptorLength + + /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */ + USB_DESC_ENDPOINT(KBD_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (Interrupt) + KBD_EPSIZE,// wMaxPacketSize + 10), // bInterval + + #ifdef MOUSE_ENABLE + /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */ + USB_DESC_INTERFACE(MOUSE_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass (0x03 = HID) + // ThinkPad T23 BIOS doesn't work with boot mouse. + 0x00, // bInterfaceSubClass (0x01 = Boot) + 0x00, // bInterfaceProtocol (0x02 = Mouse) + /* + 0x01, // bInterfaceSubClass (0x01 = Boot) + 0x02, // bInterfaceProtocol (0x02 = Mouse) + */ + 0), // iInterface + + /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */ + USB_DESC_BYTE(9), // bLength + USB_DESC_BYTE(0x21), // bDescriptorType (HID class) + USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11 + USB_DESC_BYTE(0), // bCountryCode + USB_DESC_BYTE(1), // bNumDescriptors + USB_DESC_BYTE(0x22), // bDescriptorType (report desc) + USB_DESC_WORD(sizeof(mouse_hid_report_desc_data)), // wDescriptorLength + + /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */ + USB_DESC_ENDPOINT(MOUSE_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (Interrupt) + MOUSE_EPSIZE, // wMaxPacketSize + 1), // bInterval + #endif /* MOUSE_ENABLE */ + + #ifdef CONSOLE_ENABLE + /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */ + USB_DESC_INTERFACE(CONSOLE_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass: HID + 0x00, // bInterfaceSubClass: None + 0x00, // bInterfaceProtocol: None + 0), // iInterface + + /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */ + USB_DESC_BYTE(9), // bLength + USB_DESC_BYTE(0x21), // bDescriptorType (HID class) + USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11 + USB_DESC_BYTE(0), // bCountryCode + USB_DESC_BYTE(1), // bNumDescriptors + USB_DESC_BYTE(0x22), // bDescriptorType (report desc) + USB_DESC_WORD(sizeof(console_hid_report_desc_data)), // wDescriptorLength + + /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */ + USB_DESC_ENDPOINT(CONSOLE_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (Interrupt) + CONSOLE_EPSIZE, // wMaxPacketSize + 1), // bInterval + #endif /* CONSOLE_ENABLE */ + + #ifdef EXTRAKEY_ENABLE + /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */ + USB_DESC_INTERFACE(EXTRA_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass: HID + 0x00, // bInterfaceSubClass: None + 0x00, // bInterfaceProtocol: None + 0), // iInterface + + /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */ + USB_DESC_BYTE(9), // bLength + USB_DESC_BYTE(0x21), // bDescriptorType (HID class) + USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11 + USB_DESC_BYTE(0), // bCountryCode + USB_DESC_BYTE(1), // bNumDescriptors + USB_DESC_BYTE(0x22), // bDescriptorType (report desc) + USB_DESC_WORD(sizeof(extra_hid_report_desc_data)), // wDescriptorLength + + /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */ + USB_DESC_ENDPOINT(EXTRA_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (Interrupt) + EXTRA_EPSIZE, // wMaxPacketSize + 10), // bInterval + #endif /* EXTRAKEY_ENABLE */ + + #ifdef NKRO_ENABLE + /* Interface Descriptor (9 bytes) USB spec 9.6.5, page 267-269, Table 9-12 */ + USB_DESC_INTERFACE(NKRO_INTERFACE, // bInterfaceNumber + 0, // bAlternateSetting + 1, // bNumEndpoints + 0x03, // bInterfaceClass: HID + 0x00, // bInterfaceSubClass: None + 0x00, // bInterfaceProtocol: None + 0), // iInterface + + /* HID descriptor (9 bytes) HID 1.11 spec, section 6.2.1 */ + USB_DESC_BYTE(9), // bLength + USB_DESC_BYTE(0x21), // bDescriptorType (HID class) + USB_DESC_BCD(0x0111), // bcdHID: HID version 1.11 + USB_DESC_BYTE(0), // bCountryCode + USB_DESC_BYTE(1), // bNumDescriptors + USB_DESC_BYTE(0x22), // bDescriptorType (report desc) + USB_DESC_WORD(sizeof(nkro_hid_report_desc_data)), // wDescriptorLength + + /* Endpoint Descriptor (7 bytes) USB spec 9.6.6, page 269-271, Table 9-13 */ + USB_DESC_ENDPOINT(NKRO_ENDPOINT | 0x80, // bEndpointAddress + 0x03, // bmAttributes (Interrupt) + NKRO_EPSIZE, // wMaxPacketSize + 1), // bInterval + #endif /* NKRO_ENABLE */ +}; + +/* Configuration Descriptor wrapper */ +static const USBDescriptor hid_configuration_descriptor = { + sizeof hid_configuration_descriptor_data, + hid_configuration_descriptor_data +}; + +/* wrappers */ +#define HID_DESCRIPTOR_SIZE 9 +static const USBDescriptor keyboard_hid_descriptor = { + HID_DESCRIPTOR_SIZE, + &hid_configuration_descriptor_data[KBD_HID_DESC_OFFSET] +}; +#ifdef MOUSE_ENABLE +static const USBDescriptor mouse_hid_descriptor = { + HID_DESCRIPTOR_SIZE, + &hid_configuration_descriptor_data[MOUSE_HID_DESC_OFFSET] +}; +#endif /* MOUSE_ENABLE */ +#ifdef CONSOLE_ENABLE +static const USBDescriptor console_hid_descriptor = { + HID_DESCRIPTOR_SIZE, + &hid_configuration_descriptor_data[CONSOLE_HID_DESC_OFFSET] +}; +#endif /* CONSOLE_ENABLE */ +#ifdef EXTRAKEY_ENABLE +static const USBDescriptor extra_hid_descriptor = { + HID_DESCRIPTOR_SIZE, + &hid_configuration_descriptor_data[EXTRA_HID_DESC_OFFSET] +}; +#endif /* EXTRAKEY_ENABLE */ +#ifdef NKRO_ENABLE +static const USBDescriptor nkro_hid_descriptor = { + HID_DESCRIPTOR_SIZE, + &hid_configuration_descriptor_data[NKRO_HID_DESC_OFFSET] +}; +#endif /* NKRO_ENABLE */ + + +/* U.S. English language identifier */ +static const uint8_t usb_string_langid[] = { + USB_DESC_BYTE(4), // bLength + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType + USB_DESC_WORD(0x0409) // wLANGID (U.S. English) +}; + +/* ugly ugly hack */ +#define PP_NARG(...) \ + PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) +#define PP_NARG_(...) \ + PP_ARG_N(__VA_ARGS__) +#define PP_ARG_N( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63,N,...) N +#define PP_RSEQ_N() \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9,8,7,6,5,4,3,2,1,0 + +/* Vendor string = manufacturer */ +static const uint8_t usb_string_vendor[] = { + USB_DESC_BYTE(PP_NARG(USBSTR_MANUFACTURER)+2), // bLength + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType + USBSTR_MANUFACTURER +}; + +/* Device Description string = product */ +static const uint8_t usb_string_description[] = { + USB_DESC_BYTE(PP_NARG(USBSTR_PRODUCT)+2), // bLength + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType + USBSTR_PRODUCT +}; + +/* Serial Number string (will be filled by the function init_usb_serial_string) */ +static uint8_t usb_string_serial[] = { + USB_DESC_BYTE(22), // bLength + USB_DESC_BYTE(USB_DESCRIPTOR_STRING), // bDescriptorType + '0', 0, 'x', 0, 'D', 0, 'E', 0, 'A', 0, 'D', 0, 'B', 0, 'E', 0, 'E', 0, 'F', 0 +}; + +/* Strings wrappers array */ +static const USBDescriptor usb_strings[] = { + { sizeof usb_string_langid, usb_string_langid } + , + { sizeof usb_string_vendor, usb_string_vendor } + , + { sizeof usb_string_description, usb_string_description } + , + { sizeof usb_string_serial, usb_string_serial } +}; + +/* + * Handles the GET_DESCRIPTOR callback + * + * Returns the proper descriptor + */ +static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t lang) { + (void)usbp; + (void)lang; + switch(dtype) { + /* Generic descriptors */ + case USB_DESCRIPTOR_DEVICE: /* Device Descriptor */ + return &usb_device_descriptor; + + case USB_DESCRIPTOR_CONFIGURATION: /* Configuration Descriptor */ + return &hid_configuration_descriptor; + + case USB_DESCRIPTOR_STRING: /* Strings */ + if(dindex < 4) + return &usb_strings[dindex]; + break; + + /* HID specific descriptors */ + case USB_DESCRIPTOR_HID: /* HID Descriptors */ + switch(lang) { /* yea, poor label, it's actually wIndex from the setup packet */ + case KBD_INTERFACE: + return &keyboard_hid_descriptor; + +#ifdef MOUSE_ENABLE + case MOUSE_INTERFACE: + return &mouse_hid_descriptor; +#endif /* MOUSE_ENABLE */ +#ifdef CONSOLE_ENABLE + case CONSOLE_INTERFACE: + return &console_hid_descriptor; +#endif /* CONSOLE_ENABLE */ +#ifdef EXTRAKEY_ENABLE + case EXTRA_INTERFACE: + return &extra_hid_descriptor; +#endif /* EXTRAKEY_ENABLE */ +#ifdef NKRO_ENABLE + case NKRO_INTERFACE: + return &nkro_hid_descriptor; +#endif /* NKRO_ENABLE */ + } + + case USB_DESCRIPTOR_HID_REPORT: /* HID Report Descriptor */ + switch(lang) { + case KBD_INTERFACE: + return &keyboard_hid_report_descriptor; + +#ifdef MOUSE_ENABLE + case MOUSE_INTERFACE: + return &mouse_hid_report_descriptor; +#endif /* MOUSE_ENABLE */ +#ifdef CONSOLE_ENABLE + case CONSOLE_INTERFACE: + return &console_hid_report_descriptor; +#endif /* CONSOLE_ENABLE */ +#ifdef EXTRAKEY_ENABLE + case EXTRA_INTERFACE: + return &extra_hid_report_descriptor; +#endif /* EXTRAKEY_ENABLE */ +#ifdef NKRO_ENABLE + case NKRO_INTERFACE: + return &nkro_hid_report_descriptor; +#endif /* NKRO_ENABLE */ + } + } + return NULL; +} + +/* keyboard endpoint state structure */ +static USBInEndpointState kbd_ep_state; +/* keyboard endpoint initialization structure (IN) */ +static const USBEndpointConfig kbd_ep_config = { + USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ + NULL, /* SETUP packet notification callback */ + kbd_in_cb, /* IN notification callback */ + NULL, /* OUT notification callback */ + KBD_EPSIZE, /* IN maximum packet size */ + 0, /* OUT maximum packet size */ + &kbd_ep_state, /* IN Endpoint state */ + NULL, /* OUT endpoint state */ + 2, /* IN multiplier */ + NULL /* SETUP buffer (not a SETUP endpoint) */ +}; + +#ifdef MOUSE_ENABLE +/* mouse endpoint state structure */ +static USBInEndpointState mouse_ep_state; + +/* mouse endpoint initialization structure (IN) */ +static const USBEndpointConfig mouse_ep_config = { + USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ + NULL, /* SETUP packet notification callback */ + mouse_in_cb, /* IN notification callback */ + NULL, /* OUT notification callback */ + MOUSE_EPSIZE, /* IN maximum packet size */ + 0, /* OUT maximum packet size */ + &mouse_ep_state, /* IN Endpoint state */ + NULL, /* OUT endpoint state */ + 2, /* IN multiplier */ + NULL /* SETUP buffer (not a SETUP endpoint) */ +}; +#endif /* MOUSE_ENABLE */ + +#ifdef CONSOLE_ENABLE +/* console endpoint state structure */ +static USBInEndpointState console_ep_state; + +/* console endpoint initialization structure (IN) */ +static const USBEndpointConfig console_ep_config = { + USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ + NULL, /* SETUP packet notification callback */ + console_in_cb, /* IN notification callback */ + NULL, /* OUT notification callback */ + CONSOLE_EPSIZE, /* IN maximum packet size */ + 0, /* OUT maximum packet size */ + &console_ep_state, /* IN Endpoint state */ + NULL, /* OUT endpoint state */ + 2, /* IN multiplier */ + NULL /* SETUP buffer (not a SETUP endpoint) */ +}; +#endif /* CONSOLE_ENABLE */ + +#ifdef EXTRAKEY_ENABLE +/* extrakey endpoint state structure */ +static USBInEndpointState extra_ep_state; + +/* extrakey endpoint initialization structure (IN) */ +static const USBEndpointConfig extra_ep_config = { + USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ + NULL, /* SETUP packet notification callback */ + extra_in_cb, /* IN notification callback */ + NULL, /* OUT notification callback */ + EXTRA_EPSIZE, /* IN maximum packet size */ + 0, /* OUT maximum packet size */ + &extra_ep_state, /* IN Endpoint state */ + NULL, /* OUT endpoint state */ + 2, /* IN multiplier */ + NULL /* SETUP buffer (not a SETUP endpoint) */ +}; +#endif /* EXTRAKEY_ENABLE */ + +#ifdef NKRO_ENABLE +/* nkro endpoint state structure */ +static USBInEndpointState nkro_ep_state; + +/* nkro endpoint initialization structure (IN) */ +static const USBEndpointConfig nkro_ep_config = { + USB_EP_MODE_TYPE_INTR, /* Interrupt EP */ + NULL, /* SETUP packet notification callback */ + nkro_in_cb, /* IN notification callback */ + NULL, /* OUT notification callback */ + NKRO_EPSIZE, /* IN maximum packet size */ + 0, /* OUT maximum packet size */ + &nkro_ep_state, /* IN Endpoint state */ + NULL, /* OUT endpoint state */ + 2, /* IN multiplier */ + NULL /* SETUP buffer (not a SETUP endpoint) */ +}; +#endif /* NKRO_ENABLE */ + +/* --------------------------------------------------------- + * USB driver functions + * --------------------------------------------------------- + */ + +/* Handles the USB driver global events + * TODO: maybe disable some things when connection is lost? */ +static void usb_event_cb(USBDriver *usbp, usbevent_t event) { + switch(event) { + case USB_EVENT_RESET: + //TODO: from ISR! print("[R]"); + return; + + case USB_EVENT_ADDRESS: + return; + + case USB_EVENT_CONFIGURED: + osalSysLockFromISR(); + /* Enable the endpoints specified into the configuration. */ + usbInitEndpointI(usbp, KBD_ENDPOINT, &kbd_ep_config); +#ifdef MOUSE_ENABLE + usbInitEndpointI(usbp, MOUSE_ENDPOINT, &mouse_ep_config); +#endif /* MOUSE_ENABLE */ +#ifdef CONSOLE_ENABLE + usbInitEndpointI(usbp, CONSOLE_ENDPOINT, &console_ep_config); + /* don't need to start the flush timer, it starts from console_in_cb automatically */ +#endif /* CONSOLE_ENABLE */ +#ifdef EXTRAKEY_ENABLE + usbInitEndpointI(usbp, EXTRA_ENDPOINT, &extra_ep_config); +#endif /* EXTRAKEY_ENABLE */ +#ifdef NKRO_ENABLE + usbInitEndpointI(usbp, NKRO_ENDPOINT, &nkro_ep_config); +#endif /* NKRO_ENABLE */ + osalSysUnlockFromISR(); + return; + + case USB_EVENT_SUSPEND: + //TODO: from ISR! print("[S]"); +#ifdef SLEEP_LED_ENABLE + sleep_led_enable(); +#endif /* SLEEP_LED_ENABLE */ + 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 */ + return; + + case USB_EVENT_STALLED: + return; + } +} + +/* Function used locally in os/hal/src/usb.c for getting descriptors + * need it here for HID descriptor */ +static uint16_t get_hword(uint8_t *p) { + uint16_t hw; + + hw = (uint16_t)*p++; + hw |= (uint16_t)*p << 8U; + return hw; +} + +/* + * Appendix G: HID Request Support Requirements + * + * The following table enumerates the requests that need to be supported by various types of HID class devices. + * Device type GetReport SetReport GetIdle SetIdle GetProtocol SetProtocol + * ------------------------------------------------------------------------------------------ + * Boot Mouse Required Optional Optional Optional Required Required + * Non-Boot Mouse Required Optional Optional Optional Optional Optional + * Boot Keyboard Required Optional Required Required Required Required + * Non-Boot Keybrd Required Optional Required Required Optional Optional + * Other Device Required Optional Optional Optional Optional Optional + */ + +/* Callback for SETUP request on the endpoint 0 (control) */ +static bool usb_request_hook_cb(USBDriver *usbp) { + const USBDescriptor *dp; + + /* usbp->setup fields: + * 0: bmRequestType (bitmask) + * 1: bRequest + * 2,3: (LSB,MSB) wValue + * 4,5: (LSB,MSB) wIndex + * 6,7: (LSB,MSB) wLength (number of bytes to transfer if there is a data phase) */ + + /* Handle HID class specific requests */ + if(((usbp->setup[0] & USB_RTYPE_TYPE_MASK) == USB_RTYPE_TYPE_CLASS) && + ((usbp->setup[0] & USB_RTYPE_RECIPIENT_MASK) == USB_RTYPE_RECIPIENT_INTERFACE)) { + switch(usbp->setup[0] & USB_RTYPE_DIR_MASK) { + case USB_RTYPE_DIR_DEV2HOST: + switch(usbp->setup[1]) { /* bRequest */ + case HID_GET_REPORT: + switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0?) */ + case KBD_INTERFACE: +#ifdef NKRO_ENABLE + case NKRO_INTERFACE: +#endif /* NKRO_ENABLE */ + usbSetupTransfer(usbp, (uint8_t *)&keyboard_report_sent, sizeof(keyboard_report_sent), NULL); + return TRUE; + break; + +#ifdef MOUSE_ENABLE + case MOUSE_INTERFACE: + usbSetupTransfer(usbp, (uint8_t *)&mouse_report_blank, sizeof(mouse_report_blank), NULL); + return TRUE; + break; +#endif /* MOUSE_ENABLE */ + +#ifdef CONSOLE_ENABLE + case CONSOLE_INTERFACE: + usbSetupTransfer(usbp, console_queue_buffer, CONSOLE_EPSIZE, NULL); + return TRUE; + break; +#endif /* CONSOLE_ENABLE */ + +#ifdef EXTRAKEY_ENABLE + case EXTRA_INTERFACE: + if(usbp->setup[3] == 1) { /* MSB(wValue) [Report Type] == 1 [Input Report] */ + switch(usbp->setup[2]) { /* LSB(wValue) [Report ID] */ + case REPORT_ID_SYSTEM: + extra_report_blank[0] = REPORT_ID_SYSTEM; + usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL); + return TRUE; + break; + case REPORT_ID_CONSUMER: + extra_report_blank[0] = REPORT_ID_CONSUMER; + usbSetupTransfer(usbp, (uint8_t *)extra_report_blank, sizeof(extra_report_blank), NULL); + return TRUE; + break; + default: + return FALSE; + } + } else { + return FALSE; + } + break; +#endif /* EXTRAKEY_ENABLE */ + + default: + usbSetupTransfer(usbp, NULL, 0, NULL); + return TRUE; + break; + } + break; + + case HID_GET_PROTOCOL: + if((usbp->setup[4] == KBD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */ + usbSetupTransfer(usbp, &keyboard_protocol, 1, NULL); + return TRUE; + } + break; + + case HID_GET_IDLE: + usbSetupTransfer(usbp, &keyboard_idle, 1, NULL); + return TRUE; + break; + } + break; + + case USB_RTYPE_DIR_HOST2DEV: + switch(usbp->setup[1]) { /* bRequest */ + case HID_SET_REPORT: + switch(usbp->setup[4]) { /* LSB(wIndex) (check MSB==0 and wLength==1?) */ + case KBD_INTERFACE: +#ifdef NKRO_ENABLE + case NKRO_INTERFACE: +#endif /* NKRO_ENABLE */ + /* keyboard_led_stats = + * keyboard_led_stats needs be word (or dword), otherwise we get an exception on F0 */ + usbSetupTransfer(usbp, (uint8_t *)&keyboard_led_stats, 1, NULL); + return TRUE; + break; + } + break; + + case HID_SET_PROTOCOL: + if((usbp->setup[4] == KBD_INTERFACE) && (usbp->setup[5] == 0)) { /* wIndex */ + keyboard_protocol = ((usbp->setup[2]) != 0x00); /* LSB(wValue) */ +#ifdef NKRO_ENABLE + keyboard_nkro = !!keyboard_protocol; + if(!keyboard_nkro && keyboard_idle) { +#else /* NKRO_ENABLE */ + if(keyboard_idle) { +#endif /* NKRO_ENABLE */ + /* arm the idle timer if boot protocol & idle */ + osalSysLockFromISR(); + chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp); + osalSysUnlockFromISR(); + } + } + usbSetupTransfer(usbp, NULL, 0, NULL); + return TRUE; + break; + + case HID_SET_IDLE: + keyboard_idle = usbp->setup[3]; /* MSB(wValue) */ + /* arm the timer */ +#ifdef NKRO_ENABLE + if(!keyboard_nkro && keyboard_idle) { +#else /* NKRO_ENABLE */ + if(keyboard_idle) { +#endif /* NKRO_ENABLE */ + osalSysLockFromISR(); + chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp); + osalSysUnlockFromISR(); + } + usbSetupTransfer(usbp, NULL, 0, NULL); + return TRUE; + break; + } + break; + } + } + + /* Handle the Get_Descriptor Request for HID class (not handled by the default hook) */ + if((usbp->setup[0] == 0x81) && (usbp->setup[1] == USB_REQ_GET_DESCRIPTOR)) { + dp = usbp->config->get_descriptor_cb(usbp, usbp->setup[3], usbp->setup[2], get_hword(&usbp->setup[4])); + if(dp == NULL) + return FALSE; + usbSetupTransfer(usbp, (uint8_t *)dp->ud_string, dp->ud_size, NULL); + return TRUE; + } + + return FALSE; +} + +/* Start-of-frame callback */ +static void usb_sof_cb(USBDriver *usbp) { + kbd_sof_cb(usbp); +} + + +/* USB driver configuration */ +static const USBConfig usbcfg = { + usb_event_cb, /* USB events callback */ + usb_get_descriptor_cb, /* Device GET_DESCRIPTOR request callback */ + usb_request_hook_cb, /* Requests hook callback */ + usb_sof_cb /* Start Of Frame callback */ +}; + +/* + * Initialize the USB driver + */ +void init_usb_driver(USBDriver *usbp) { + /* + * Activates the USB driver and then the USB bus pull-up on D+. + * Note, a delay is inserted in order to not have to disconnect the cable + * after a reset. + */ + usbDisconnectBus(usbp); + chThdSleepMilliseconds(1500); + usbStart(usbp, &usbcfg); + usbConnectBus(usbp); + + chVTObjectInit(&keyboard_idle_timer); +#ifdef CONSOLE_ENABLE + obqObjectInit(&console_buf_queue, console_queue_buffer, CONSOLE_EPSIZE, CONSOLE_QUEUE_CAPACITY, console_queue_onotify, (void*)usbp); + chVTObjectInit(&console_flush_timer); +#endif +} + +/* + * Send remote wakeup packet + * Note: should not be called from ISR + */ +void send_remote_wakeup(USBDriver *usbp) { + (void)usbp; +#if defined(K20x) || defined(KL2x) +#if KINETIS_USB_USE_USB0 + USB0->CTL |= USBx_CTL_RESUME; + chThdSleepMilliseconds(15); + USB0->CTL &= ~USBx_CTL_RESUME; +#endif /* KINETIS_USB_USE_USB0 */ +#elif defined(STM32F0XX) || defined(STM32F1XX) /* K20x || KL2x */ + STM32_USB->CNTR |= CNTR_RESUME; + chThdSleepMilliseconds(15); + STM32_USB->CNTR &= ~CNTR_RESUME; +#else /* STM32F0XX || STM32F1XX */ +#warning Sending remote wakeup packet not implemented for your platform. +#endif /* K20x || KL2x */ +} + +/* --------------------------------------------------------- + * Keyboard functions + * --------------------------------------------------------- + */ + +/* keyboard IN callback hander (a kbd report has made it IN) */ +void kbd_in_cb(USBDriver *usbp, usbep_t ep) { + /* STUB */ + (void)usbp; + (void)ep; +} + +#ifdef NKRO_ENABLE +/* nkro IN callback hander (a nkro report has made it IN) */ +void nkro_in_cb(USBDriver *usbp, usbep_t ep) { + /* STUB */ + (void)usbp; + (void)ep; +} +#endif /* NKRO_ENABLE */ + +/* start-of-frame handler + * TODO: i guess it would be better to re-implement using timers, + * so that this is not going to have to be checked every 1ms */ +void kbd_sof_cb(USBDriver *usbp) { + (void)usbp; +} + +/* Idle requests timer code + * callback (called from ISR, unlocked state) */ +static void keyboard_idle_timer_cb(void *arg) { + USBDriver *usbp = (USBDriver *)arg; + + osalSysLockFromISR(); + + /* check that the states of things are as they're supposed to */ + if(usbGetDriverStateI(usbp) != USB_ACTIVE) { + /* do not rearm the timer, should be enabled on IDLE request */ + osalSysUnlockFromISR(); + return; + } + +#ifdef NKRO_ENABLE + if(!keyboard_nkro && keyboard_idle) { +#else /* NKRO_ENABLE */ + if(keyboard_idle) { +#endif /* NKRO_ENABLE */ + /* TODO: are we sure we want the KBD_ENDPOINT? */ + if(!usbGetTransmitStatusI(usbp, KBD_ENDPOINT)) { + usbStartTransmitI(usbp, KBD_ENDPOINT, (uint8_t *)&keyboard_report_sent, KBD_EPSIZE); + } + /* rearm the timer */ + chVTSetI(&keyboard_idle_timer, 4*MS2ST(keyboard_idle), keyboard_idle_timer_cb, (void *)usbp); + } + + /* do not rearm the timer if the condition above fails + * it should be enabled again on either IDLE or SET_PROTOCOL requests */ + osalSysUnlockFromISR(); +} + +/* LED status */ +uint8_t keyboard_leds(void) { + return (uint8_t)(keyboard_led_stats & 0xFF); +} + +/* prepare and start sending a report IN + * not callable from ISR or locked state */ +void send_keyboard(report_keyboard_t *report) { + osalSysLock(); + if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { + osalSysUnlock(); + return; + } + osalSysUnlock(); + +#ifdef NKRO_ENABLE + if(keyboard_nkro) { /* NKRO protocol */ + /* need to wait until the previous packet has made it through */ + /* can rewrite this using the synchronous API, then would wait + * until *after* the packet has been transmitted. I think + * this is more efficient */ + /* busy wait, should be short and not very common */ + osalSysLock(); + if(usbGetTransmitStatusI(&USB_DRIVER, NKRO_ENDPOINT)) { + /* Need to either suspend, or loop and call unlock/lock during + * every iteration - otherwise the system will remain locked, + * no interrupts served, so USB not going through as well. + * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ + osalThreadSuspendS(&(&USB_DRIVER)->epc[NKRO_ENDPOINT]->in_state->thread); + } + usbStartTransmitI(&USB_DRIVER, NKRO_ENDPOINT, (uint8_t *)report, sizeof(report_keyboard_t)); + osalSysUnlock(); + } else +#endif /* NKRO_ENABLE */ + { /* boot protocol */ + /* need to wait until the previous packet has made it through */ + /* busy wait, should be short and not very common */ + osalSysLock(); + if(usbGetTransmitStatusI(&USB_DRIVER, KBD_ENDPOINT)) { + /* Need to either suspend, or loop and call unlock/lock during + * every iteration - otherwise the system will remain locked, + * no interrupts served, so USB not going through as well. + * Note: for suspend, need USB_USE_WAIT == TRUE in halconf.h */ + osalThreadSuspendS(&(&USB_DRIVER)->epc[KBD_ENDPOINT]->in_state->thread); + } + usbStartTransmitI(&USB_DRIVER, KBD_ENDPOINT, (uint8_t *)report, KBD_EPSIZE); + osalSysUnlock(); + } + keyboard_report_sent = *report; +} + +/* --------------------------------------------------------- + * Mouse functions + * --------------------------------------------------------- + */ + +#ifdef MOUSE_ENABLE + +/* mouse IN callback hander (a mouse report has made it IN) */ +void mouse_in_cb(USBDriver *usbp, usbep_t ep) { + (void)usbp; + (void)ep; +} + +void send_mouse(report_mouse_t *report) { + osalSysLock(); + if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { + osalSysUnlock(); + return; + } + osalSysUnlock(); + + /* TODO: LUFA manually waits for the endpoint to become ready + * for about 10ms for mouse, kbd, system; 1ms for nkro + * is this really needed? + */ + + osalSysLock(); + usbStartTransmitI(&USB_DRIVER, MOUSE_ENDPOINT, (uint8_t *)report, sizeof(report_mouse_t)); + osalSysUnlock(); +} + +#else /* MOUSE_ENABLE */ +void send_mouse(report_mouse_t *report) { + (void)report; +} +#endif /* MOUSE_ENABLE */ + +/* --------------------------------------------------------- + * Extrakey functions + * --------------------------------------------------------- + */ + +#ifdef EXTRAKEY_ENABLE + +/* extrakey IN callback hander */ +void extra_in_cb(USBDriver *usbp, usbep_t ep) { + /* STUB */ + (void)usbp; + (void)ep; +} + +static void send_extra_report(uint8_t report_id, uint16_t data) { + osalSysLock(); + if(usbGetDriverStateI(&USB_DRIVER) != USB_ACTIVE) { + osalSysUnlock(); + return; + } + + report_extra_t report = { + .report_id = report_id, + .usage = data + }; + + usbStartTransmitI(&USB_DRIVER, EXTRA_ENDPOINT, (uint8_t *)&report, sizeof(report_extra_t)); + osalSysUnlock(); +} + +void send_system(uint16_t data) { + send_extra_report(REPORT_ID_SYSTEM, data); +} + +void send_consumer(uint16_t data) { + send_extra_report(REPORT_ID_CONSUMER, data); +} + +#else /* EXTRAKEY_ENABLE */ +void send_system(uint16_t data) { + (void)data; +} +void send_consumer(uint16_t data) { + (void)data; +} +#endif /* EXTRAKEY_ENABLE */ + +/* --------------------------------------------------------- + * Console functions + * --------------------------------------------------------- + */ + +#ifdef CONSOLE_ENABLE + +/* console IN callback hander */ +void console_in_cb(USBDriver *usbp, usbep_t ep) { + (void)ep; /* should have ep == CONSOLE_ENDPOINT, so use that to save time/space */ + uint8_t *buf; + size_t n; + + osalSysLockFromISR(); + + /* rearm the timer */ + chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp); + + /* Freeing the buffer just transmitted, if it was not a zero size packet.*/ + if (usbp->epc[CONSOLE_ENDPOINT]->in_state->txsize > 0U) { + obqReleaseEmptyBufferI(&console_buf_queue); + } + + /* Checking if there is a buffer ready for transmission.*/ + buf = obqGetFullBufferI(&console_buf_queue, &n); + + if (buf != NULL) { + /* The endpoint cannot be busy, we are in the context of the callback, + so it is safe to transmit without a check.*/ + /* Should have n == CONSOLE_EPSIZE; check it? */ + usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE); + } else { + /* Nothing to transmit.*/ + } + + osalSysUnlockFromISR(); +} + +/* Callback when data is inserted into the output queue + * Called from a locked state */ +void console_queue_onotify(io_buffers_queue_t *bqp) { + size_t n; + USBDriver *usbp = bqGetLinkX(bqp); + + if(usbGetDriverStateI(usbp) != USB_ACTIVE) + return; + + /* Checking if there is already a transaction ongoing on the endpoint.*/ + if (!usbGetTransmitStatusI(usbp, CONSOLE_ENDPOINT)) { + /* Trying to get a full buffer.*/ + uint8_t *buf = obqGetFullBufferI(&console_buf_queue, &n); + if (buf != NULL) { + /* Buffer found, starting a new transaction.*/ + /* Should have n == CONSOLE_EPSIZE; check this? */ + usbStartTransmitI(usbp, CONSOLE_ENDPOINT, buf, CONSOLE_EPSIZE); + } + } +} + +/* Flush timer code + * callback (called from ISR, unlocked state) */ +static void console_flush_cb(void *arg) { + USBDriver *usbp = (USBDriver *)arg; + osalSysLockFromISR(); + + /* check that the states of things are as they're supposed to */ + if(usbGetDriverStateI(usbp) != USB_ACTIVE) { + /* rearm the timer */ + chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp); + osalSysUnlockFromISR(); + return; + } + + /* If there is already a transaction ongoing then another one cannot be + started.*/ + if (usbGetTransmitStatusI(usbp, CONSOLE_ENDPOINT)) { + /* rearm the timer */ + chVTSetI(&console_flush_timer, MS2ST(CONSOLE_FLUSH_MS), console_flush_cb, (void *)usbp); + osalSysUnlockFromISR(); + return; + } + + /* Checking if there only a buffer partially filled, if so then it is + enforced in the queue and transmitted.*/ + if(obqTryFlushI(&console_buf_queue)) { + size_t n,i; + uint8_t *buf = obqGetFullBufferI(&console_buf_queue, &n); + + osalDbgAssert(buf != NULL, "queue is empty"); + + /* zero the rest of the buffer (buf should point to allocated space) */ + for(i=n; i + * + * Based on the following work: + * - Guillaume Duc's raw hid example (MIT License) + * https://github.com/guiduc/usb-hid-chibios-example + * - PJRC Teensy examples (MIT License) + * https://www.pjrc.com/teensy/usb_keyboard.html + * - hasu's TMK keyboard code (GPL v2 and some code Modified BSD) + * https://github.com/tmk/tmk_keyboard/ + * - ChibiOS demo code (Apache 2.0 License) + * http://www.chibios.org + * + * Since some GPL'd code is used, this work is licensed under + * GPL v2 or later. + */ + + +#ifndef _USB_MAIN_H_ +#define _USB_MAIN_H_ + +// TESTING +// extern uint8_t blinkLed; + +#include "ch.h" +#include "hal.h" + +/* ------------------------- + * General USB driver header + * ------------------------- + */ + +/* The USB driver to use */ +#define USB_DRIVER USBD1 + +/* Initialize the USB driver and bus */ +void init_usb_driver(USBDriver *usbp); + +/* Send remote wakeup packet */ +void send_remote_wakeup(USBDriver *usbp); + +/* --------------- + * Keyboard header + * --------------- + */ + +/* main keyboard (6kro) */ +#define KBD_INTERFACE 0 +#define KBD_ENDPOINT 1 +#define KBD_EPSIZE 8 +#define KBD_REPORT_KEYS (KBD_EPSIZE - 2) + +/* secondary keyboard */ +#ifdef NKRO_ENABLE +#define NKRO_INTERFACE 4 +#define NKRO_ENDPOINT 5 +#define NKRO_EPSIZE 16 +#define NKRO_REPORT_KEYS (NKRO_EPSIZE - 1) +#endif + +/* extern report_keyboard_t keyboard_report_sent; */ + +/* keyboard IN request callback handler */ +void kbd_in_cb(USBDriver *usbp, usbep_t ep); + +/* start-of-frame handler */ +void kbd_sof_cb(USBDriver *usbp); + +#ifdef NKRO_ENABLE +/* nkro IN callback hander */ +void nkro_in_cb(USBDriver *usbp, usbep_t ep); +#endif /* NKRO_ENABLE */ + +/* ------------ + * Mouse header + * ------------ + */ + +#ifdef MOUSE_ENABLE + +#define MOUSE_INTERFACE 1 +#define MOUSE_ENDPOINT 2 +#define MOUSE_EPSIZE 8 + +/* mouse IN request callback handler */ +void mouse_in_cb(USBDriver *usbp, usbep_t ep); +#endif /* MOUSE_ENABLE */ + +/* --------------- + * Extrakey header + * --------------- + */ + +#ifdef EXTRAKEY_ENABLE + +#define EXTRA_INTERFACE 3 +#define EXTRA_ENDPOINT 4 +#define EXTRA_EPSIZE 8 + +/* extrakey IN request callback handler */ +void extra_in_cb(USBDriver *usbp, usbep_t ep); + +/* extra report structure */ +typedef struct { + uint8_t report_id; + uint16_t usage; +} __attribute__ ((packed)) report_extra_t; +#endif /* EXTRAKEY_ENABLE */ + +/* -------------- + * Console header + * -------------- + */ + +#ifdef CONSOLE_ENABLE + +#define CONSOLE_INTERFACE 2 +#define CONSOLE_ENDPOINT 3 +#define CONSOLE_EPSIZE 16 + +/* Number of IN reports that can be stored inside the output queue */ +#define CONSOLE_QUEUE_CAPACITY 4 + +/* Console flush time */ +#define CONSOLE_FLUSH_MS 50 + +/* Putchar over the USB console */ +int8_t sendchar(uint8_t c); + +/* Flush output (send everything immediately) */ +void console_flush_output(void); + +/* console IN request callback handler */ +void console_in_cb(USBDriver *usbp, usbep_t ep); +#endif /* CONSOLE_ENABLE */ + +void sendchar_pf(void *p, char c); + +#endif /* _USB_MAIN_H_ */ diff --git a/tmk_core/readme.md b/tmk_core/readme.md index 6b6714a6a2..f460d0ed44 100644 --- a/tmk_core/readme.md +++ b/tmk_core/readme.md @@ -5,6 +5,16 @@ This is a keyboard firmware library with some useful features for Atmel AVR and Source code is available here: +Updates +------- +#### 2016/02/10 +flabbergast's Chibios protocol was merged from . See [protocol/chibios/README.md](protocol/chibios/README.md). Chibios protocol supports Cortex-M such as STM32 and Kinetis. + +#### 2015/04/22 +separated with TMK Keyboard Firmware Collection + + + Features -------- These features can be used in your keyboard. @@ -27,12 +37,6 @@ These features can be used in your keyboard. -Updates -------- -2015/04/22 separated with TMK Keyboard Firmware Collection - - - TMK Keyboard Firmware Collection -------------------------------- Complete firmwares for various keyboards and protocol converters. diff --git a/tmk_core/rules.mk b/tmk_core/rules.mk index f8f77e892e..96eba24d67 100644 --- a/tmk_core/rules.mk +++ b/tmk_core/rules.mk @@ -20,26 +20,11 @@ # Output format. (can be srec, ihex, binary) FORMAT = ihex -BUILD_DIR = .build - -# Object files directory -# To put object files in current directory, use a dot (.), do NOT make -# this an empty or blank macro! -OBJDIR = $(BUILD_DIR)/obj_$(TARGET) - - # Optimization level, can be [0, 1, 2, 3, s]. # 0 = turn off optimization. s = optimize for size. # (Note: 3 is not always the best optimization level. See avr-libc FAQ.) OPT = s - -# Debugging format. -# Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs. -# AVR Studio 4.10 requires dwarf-2. -# AVR [Extended] COFF format requires stabs, plus an avr-objcopy run. -DEBUG = dwarf-2 - COLOR ?= true ifeq ($(COLOR),true) @@ -87,7 +72,7 @@ BUILD_CMD = LOG=$$($(CMD) 2>&1) ; if [ $$? -gt 0 ]; then $(PRINT_ERROR); elif [ # Each directory must be seperated by a space. # Use forward slashes for directory separators. # For a directory that has spaces, enclose it in quotes. -EXTRAINCDIRS = $(subst :, ,$(VPATH)) +EXTRAINCDIRS += $(subst :, ,$(VPATH)) # Compiler flag to set the C Standard level. @@ -99,17 +84,14 @@ CSTANDARD = -std=gnu99 # Place -D or -U options here for C sources -CDEFS = -DF_CPU=$(F_CPU)UL CDEFS += $(OPT_DEFS) # Place -D or -U options here for ASM sources -ADEFS = -DF_CPU=$(F_CPU) ADEFS += $(OPT_DEFS) # Place -D or -U options here for C++ sources -CPPDEFS = -DF_CPU=$(F_CPU)UL #CPPDEFS += -D__STDC_LIMIT_MACROS #CPPDEFS += -D__STDC_CONSTANT_MACROS CPPDEFS += $(OPT_DEFS) @@ -123,17 +105,9 @@ CPPDEFS += $(OPT_DEFS) # -Wall...: warning level # -Wa,...: tell GCC to pass this to the assembler. # -adhlns...: create assembler listing -CFLAGS = -g$(DEBUG) +CFLAGS += -g$(DEBUG) CFLAGS += $(CDEFS) CFLAGS += -O$(OPT) -CFLAGS += -funsigned-char -CFLAGS += -funsigned-bitfields -CFLAGS += -ffunction-sections -CFLAGS += -fdata-sections -CFLAGS += -fno-inline-small-functions -CFLAGS += -fpack-struct -CFLAGS += -fshort-enums -CFLAGS += -fno-strict-aliasing # add color ifeq ($(COLOR),true) ifeq ("$(shell echo "int main(){}" | $(CC) -fdiagnostics-color -x c - -o /dev/null 2>&1)", "") @@ -162,16 +136,9 @@ endif # -Wall...: warning level # -Wa,...: tell GCC to pass this to the assembler. # -adhlns...: create assembler listing -CPPFLAGS = -g$(DEBUG) +CPPFLAGS += -g$(DEBUG) CPPFLAGS += $(CPPDEFS) CPPFLAGS += -O$(OPT) -CPPFLAGS += -funsigned-char -CPPFLAGS += -funsigned-bitfields -CPPFLAGS += -fpack-struct -CPPFLAGS += -fshort-enums -CPPFLAGS += -fno-exceptions -CPPFLAGS += -ffunction-sections -CPPFLAGS += -fdata-sections # to supress "warning: only initialized variables can be placed into program memory area" CPPFLAGS += -w CPPFLAGS += -Wall @@ -198,7 +165,7 @@ endif # files -- see avr-libc docs [FIXME: not yet described there] # -listing-cont-lines: Sets the maximum number of continuation lines of hex # dump that will be displayed for a given single line of source input. -ASFLAGS = $(ADEFS) -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100 +ASFLAGS += $(ADEFS) -Wa,-adhlns=$(@:%.o=%.lst),-gstabs,--listing-cont-lines=100 ASFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) ifdef CONFIG_H ASFLAGS += -include $(CONFIG_H) @@ -232,28 +199,6 @@ SCANF_LIB = MATH_LIB = -lm -# List any extra directories to look for libraries here. -# Each directory must be seperated by a space. -# Use forward slashes for directory separators. -# For a directory that has spaces, enclose it in quotes. -EXTRALIBDIRS = - - - -#---------------- External Memory Options ---------------- - -# 64 KB of external RAM, starting after internal RAM (ATmega128!), -# used for variables (.data/.bss) and heap (malloc()). -#EXTMEMOPTS = -Wl,-Tdata=0x801100,--defsym=__heap_end=0x80ffff - -# 64 KB of external RAM, starting after internal RAM (ATmega128!), -# only used for heap (malloc()). -#EXTMEMOPTS = -Wl,--section-start,.data=0x801100,--defsym=__heap_end=0x80ffff - -EXTMEMOPTS = - - - #---------------- Linker Options ---------------- # -Wl,...: tell GCC to pass this to linker. # -Map: create map file @@ -262,9 +207,8 @@ EXTMEMOPTS = # Comennt out "--relax" option to avoid a error such: # (.vectors+0x30): relocation truncated to fit: R_AVR_13_PCREL against symbol `__vector_12' # -LDFLAGS = -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref +LDFLAGS += -Wl,-Map=$(BUILD_DIR)/$(TARGET).map,--cref #LDFLAGS += -Wl,--relax -LDFLAGS += -Wl,--gc-sections LDFLAGS += $(EXTMEMOPTS) LDFLAGS += $(patsubst %,-L%,$(EXTRALIBDIRS)) LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) @@ -272,59 +216,13 @@ LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) # You can give EXTRALDFLAGS at 'make' command line. LDFLAGS += $(EXTRALDFLAGS) - - -#---------------- Debugging Options ---------------- - -# For simulavr only - target MCU frequency. -DEBUG_MFREQ = $(F_CPU) - -# Set the DEBUG_UI to either gdb or insight. -# DEBUG_UI = gdb -DEBUG_UI = insight - -# Set the debugging back-end to either avarice, simulavr. -DEBUG_BACKEND = avarice -#DEBUG_BACKEND = simulavr - -# GDB Init Filename. -GDBINIT_FILE = __avr_gdbinit - -# When using avarice settings for the JTAG -JTAG_DEV = /dev/com1 - -# Debugging port used to communicate between GDB / avarice / simulavr. -DEBUG_PORT = 4242 - -# Debugging host used to communicate between GDB / avarice / simulavr, normally -# just set to localhost unless doing some sort of crazy debugging when -# avarice is running on a different computer. -DEBUG_HOST = localhost - - - -#============================================================================ - - # Define programs and commands. SHELL = sh -CC = avr-gcc -OBJCOPY = avr-objcopy -OBJDUMP = avr-objdump -SIZE = avr-size -AR = avr-ar rcs -NM = avr-nm REMOVE = rm -f REMOVEDIR = rmdir COPY = cp WINSHELL = cmd SECHO = $(SILENT) || echo -# Autodecct teensy loader -ifneq (, $(shell which teensy-loader-cli 2>/dev/null)) - TEENSY_LOADER_CLI = teensy-loader-cli -else - TEENSY_LOADER_CLI = teensy_loader_cli -endif # Define Messages # English @@ -347,8 +245,6 @@ MSG_CLEANING = Cleaning project: MSG_CREATING_LIBRARY = Creating library: - - # Define all object files. OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(patsubst %.cpp,$(OBJDIR)/%.o,$(patsubst %.S,$(OBJDIR)/%.o,$(SRC)))) @@ -364,9 +260,9 @@ GENDEPFLAGS = -MMD -MP -MF $(BUILD_DIR)/.dep/$(subst /,_,$@).d # Combine all necessary flags and optional flags. # Add target processor to flags. # You can give extra flags at 'make' command line like: make EXTRAFLAGS=-DFOO=bar -ALL_CFLAGS = -mmcu=$(MCU) $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) -ALL_CPPFLAGS = -mmcu=$(MCU) -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) -ALL_ASFLAGS = -mmcu=$(MCU) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS) +ALL_CFLAGS = $(MCUFLAGS) $(CFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) +ALL_CPPFLAGS = $(MCUFLAGS) -x c++ $(CPPFLAGS) $(GENDEPFLAGS) $(EXTRAFLAGS) +ALL_ASFLAGS = $(MCUFLAGS) -x assembler-with-cpp $(ASFLAGS) $(EXTRAFLAGS) # Default target. all: @@ -432,104 +328,10 @@ sizeafter: gccversion : @$(SILENT) || $(CC) --version - - -# Program the device. -program: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep - $(PROGRAM_CMD) - -teensy: $(BUILD_DIR)/$(TARGET).hex - $(TEENSY_LOADER_CLI) -mmcu=$(MCU) -w -v $(BUILD_DIR)/$(TARGET).hex - -flip: $(BUILD_DIR)/$(TARGET).hex - batchisp -hardware usb -device $(MCU) -operation erase f - batchisp -hardware usb -device $(MCU) -operation loadbuffer $(BUILD_DIR)/$(TARGET).hex program - batchisp -hardware usb -device $(MCU) -operation start reset 0 - -dfu: $(BUILD_DIR)/$(TARGET).hex sizeafter -ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1))) - dfu-programmer $(MCU) erase --force -else - dfu-programmer $(MCU) erase -endif - dfu-programmer $(MCU) flash $(BUILD_DIR)/$(TARGET).hex - dfu-programmer $(MCU) reset - -dfu-start: - dfu-programmer $(MCU) reset - dfu-programmer $(MCU) start - -flip-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep - $(COPY) $(BUILD_DIR)/$(TARGET).eep $(BUILD_DIR)/$(TARGET)eep.hex - batchisp -hardware usb -device $(MCU) -operation memory EEPROM erase - batchisp -hardware usb -device $(MCU) -operation memory EEPROM loadbuffer $(BUILD_DIR)/$(TARGET)eep.hex program - batchisp -hardware usb -device $(MCU) -operation start reset 0 - $(REMOVE) $(BUILD_DIR)/$(TARGET)eep.hex - -dfu-ee: $(BUILD_DIR)/$(TARGET).hex $(BUILD_DIR)/$(TARGET).eep -ifneq (, $(findstring 0.7, $(shell dfu-programmer --version 2>&1))) - dfu-programmer $(MCU) flash --eeprom $(BUILD_DIR)/$(TARGET).eep -else - dfu-programmer $(MCU) flash-eeprom $(BUILD_DIR)/$(TARGET).eep -endif - dfu-programmer $(MCU) reset - - -# Generate avr-gdb config/init file which does the following: -# define the reset signal, load the target file, connect to target, and set -# a breakpoint at main(). -gdb-config: - @$(REMOVE) $(GDBINIT_FILE) - @echo define reset >> $(GDBINIT_FILE) - @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) - @echo end >> $(GDBINIT_FILE) - @echo file $(BUILD_DIR)/$(TARGET).elf >> $(GDBINIT_FILE) - @echo target remote $(DEBUG_HOST):$(DEBUG_PORT) >> $(GDBINIT_FILE) -ifeq ($(DEBUG_BACKEND),simulavr) - @echo load >> $(GDBINIT_FILE) -endif - @echo break main >> $(GDBINIT_FILE) - -debug: gdb-config $(BUILD_DIR)/$(TARGET).elf -ifeq ($(DEBUG_BACKEND), avarice) - @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. - @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ - $(BUILD_DIR)/$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) - @$(WINSHELL) /c pause - -else - @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ - $(DEBUG_MFREQ) --port $(DEBUG_PORT) -endif - @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) - - - - -# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB. -COFFCONVERT = $(OBJCOPY) --debugging -COFFCONVERT += --change-section-address .data-0x800000 -COFFCONVERT += --change-section-address .bss-0x800000 -COFFCONVERT += --change-section-address .noinit-0x800000 -COFFCONVERT += --change-section-address .eeprom-0x810000 - - - -coff: $(BUILD_DIR)/$(TARGET).elf - @$(SECHO) $(MSG_COFF) $(BUILD_DIR)/$(TARGET).cof - $(COFFCONVERT) -O coff-avr $< $(BUILD_DIR)/$(TARGET).cof - - -extcoff: $(BUILD_DIR)/$(TARGET).elf - @$(SECHO) $(MSG_EXTENDED_COFF) $(BUILD_DIR)/$(TARGET).cof - $(COFFCONVERT) -O coff-ext-avr $< $(BUILD_DIR)/$(TARGET).cof - - - # Create final output files (.hex, .eep) from ELF output file. %.hex: %.elf @$(SILENT) || printf "$(MSG_FLASH) $@" | $(AWK_CMD) - $(eval CMD=$(OBJCOPY) -O $(FORMAT) -R .eeprom -R .fuse -R .lock -R .signature $< $@) + $(eval CMD=$(HEX) $< $@) @$(BUILD_CMD) @if $(AUTOGEN); then \ $(SILENT) || printf "Copying $(TARGET).hex to keymaps/$(KEYMAP)/$(KEYBOARD)_$(KEYMAP).hex\n"; \ @@ -540,7 +342,7 @@ extcoff: $(BUILD_DIR)/$(TARGET).elf %.eep: %.elf @$(SILENT) || printf "$(MSG_EEPROM) $@" | $(AWK_CMD) - $(eval CMD=$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0) + $(eval CMD=$(EEP) $< $@ || exit 0) @$(BUILD_CMD) # Create extended listing file from ELF output file. @@ -622,7 +424,7 @@ show_path: @echo VPATH=$(VPATH) @echo SRC=$(SRC) -SUBDIRS := $(filter-out %/util/ %/doc/ %/keymaps/ %/old_keymap_files/,$(dir $(wildcard $(TOP_DIR)/keyboards/**/*/.))) +SUBDIRS := $(filter-out %/util/ %/doc/ %/keymaps/ %/old_keymap_files/,$(dir $(wildcard $(TOP_DIR)/keyboards/**/*/Makefile))) SUBDIRS := $(SUBDIRS) $(dir $(wildcard $(TOP_DIR)/keyboards/*/.)) SUBDIRS := $(sort $(SUBDIRS)) # $(error $(SUBDIRS)) diff --git a/tmk_core/tool/chibios/.gitignore b/tmk_core/tool/chibios/.gitignore new file mode 100644 index 0000000000..88bbafe34f --- /dev/null +++ b/tmk_core/tool/chibios/.gitignore @@ -0,0 +1,2 @@ +chibios +chibios-contrib diff --git a/tmk_core/tool/chibios/ch-bootloader-jump.patch b/tmk_core/tool/chibios/ch-bootloader-jump.patch new file mode 100644 index 0000000000..d886576214 --- /dev/null +++ b/tmk_core/tool/chibios/ch-bootloader-jump.patch @@ -0,0 +1,116 @@ +diff --git a/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s b/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s +index 51a79bb..42d07bd 100644 +--- a/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s ++++ b/os/common/ports/ARMCMx/compilers/GCC/crt0_v6m.s +@@ -105,6 +105,13 @@ + #define CRT0_CALL_DESTRUCTORS TRUE + #endif + ++/** ++ * @brief Magic number for jumping to bootloader. ++ */ ++#if !defined(MAGIC_BOOTLOADER_NUMBER) || defined(__DOXYGEN__) ++#define MAGIC_BOOTLOADER_NUMBER 0xDEADBEEF ++#endif ++ + /*===========================================================================*/ + /* Code section. */ + /*===========================================================================*/ +@@ -124,6 +131,17 @@ + .thumb_func + .global Reset_Handler + Reset_Handler: ++ ++#ifdef STM32_BOOTLOADER_ADDRESS ++ /* jump to bootloader code */ ++ ldr r0, =__ram0_end__-4 ++ ldr r1, =MAGIC_BOOTLOADER_NUMBER ++ ldr r2, [r0, #0] ++ str r0, [r0, #0] /* erase stored magic */ ++ cmp r2, r1 ++ beq Bootloader_Jump ++#endif /* STM32_BOOTLOADER_ADDRESS */ ++ + /* Interrupts are globally masked initially.*/ + cpsid i + +@@ -242,6 +260,21 @@ endfiniloop: + ldr r1, =__default_exit + bx r1 + ++#ifdef STM32_BOOTLOADER_ADDRESS ++/* ++ * Jump-to-bootloader function. ++ */ ++ ++ .align 2 ++ .thumb_func ++Bootloader_Jump: ++ ldr r0, =STM32_BOOTLOADER_ADDRESS ++ ldr r1, [r0, #0] ++ mov sp, r1 ++ ldr r0, [r0, #4] ++ bx r0 ++#endif /* STM32_BOOTLOADER_ADDRESS */ ++ + #endif + + /** @} */ +diff --git a/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s b/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +index 4812a29..dca9f88 100644 +--- a/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s ++++ b/os/common/ports/ARMCMx/compilers/GCC/crt0_v7m.s +@@ -140,6 +140,13 @@ + #define CRT0_CPACR_INIT 0x00F00000 + #endif + ++/** ++ * @brief Magic number for jumping to bootloader. ++ */ ++#if !defined(MAGIC_BOOTLOADER_NUMBER) || defined(__DOXYGEN__) ++#define MAGIC_BOOTLOADER_NUMBER 0xDEADBEEF ++#endif ++ + /*===========================================================================*/ + /* Code section. */ + /*===========================================================================*/ +@@ -164,6 +171,17 @@ + .thumb_func + .global Reset_Handler + Reset_Handler: ++ ++#ifdef STM32_BOOTLOADER_ADDRESS ++ /* jump to bootloader code */ ++ ldr r0, =__ram0_end__-4 ++ ldr r1, =MAGIC_BOOTLOADER_NUMBER ++ ldr r2, [r0, #0] ++ str r0, [r0, #0] /* erase stored magic */ ++ cmp r2, r1 ++ beq Bootloader_Jump ++#endif /* STM32_BOOTLOADER_ADDRESS */ ++ + /* Interrupts are globally masked initially.*/ + cpsid i + +@@ -305,6 +323,21 @@ endfiniloop: + /* Branching to the defined exit handler.*/ + b __default_exit + ++#ifdef STM32_BOOTLOADER_ADDRESS ++/* ++ * Jump-to-bootloader function. ++ */ ++ ++ .align 2 ++ .thumb_func ++Bootloader_Jump: ++ ldr r0, =STM32_BOOTLOADER_ADDRESS ++ ldr r1, [r0, #0] ++ mov sp, r1 ++ ldr r0, [r0, #4] ++ bx r0 ++#endif /* STM32_BOOTLOADER_ADDRESS */ ++ + #endif /* !defined(__DOXYGEN__) */ + + /** @} */