example_keyboards
Christopher Browne 8 years ago
commit 2e1cfaf73f

6
.gitmodules vendored

@ -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

@ -18,4 +18,7 @@ addons:
- gcc-avr - gcc-avr
- dfu-programmer - dfu-programmer
- pandoc - pandoc
after_success: bash util/travis_compiled_push.sh - gcc-arm-none-eabi
- binutils-arm-none-eabi
- libnewlib-arm-none-eabi
after_success: bash util/travis_compiled_push.sh

@ -2,6 +2,8 @@ ifndef VERBOSE
.SILENT: .SILENT:
endif endif
.DEFAULT_GOAL := all
space := $(subst ,, ) space := $(subst ,, )
starting_makefile := $(subst $(space),_SPACE_,$(abspath $(firstword $(MAKEFILE_LIST)))) starting_makefile := $(subst $(space),_SPACE_,$(abspath $(firstword $(MAKEFILE_LIST))))
mkfile_path := $(subst $(space),_SPACE_,$(abspath $(lastword $(MAKEFILE_LIST)))) mkfile_path := $(subst $(space),_SPACE_,$(abspath $(lastword $(MAKEFILE_LIST))))
@ -41,6 +43,7 @@ endif
TOP_DIR = $(tmk_root) TOP_DIR = $(tmk_root)
TMK_DIR = tmk_core TMK_DIR = tmk_core
TMK_PATH = $(TOP_DIR)/$(TMK_DIR) TMK_PATH = $(TOP_DIR)/$(TMK_DIR)
LIB_PATH = $(TOP_DIR)/lib
QUANTUM_DIR = quantum QUANTUM_DIR = quantum
QUANTUM_PATH = $(TOP_DIR)/$(QUANTUM_DIR) QUANTUM_PATH = $(TOP_DIR)/$(QUANTUM_DIR)
@ -126,6 +129,13 @@ ifdef SUBPROJECT
else else
TARGET ?= $(KEYBOARD)_$(KEYMAP) TARGET ?= $(KEYBOARD)_$(KEYMAP)
endif 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)","") ifneq ("$(wildcard $(KEYMAP_PATH)/config.h)","")
@ -143,7 +153,7 @@ endif
SRC += $(KEYBOARD_FILE) \ SRC += $(KEYBOARD_FILE) \
$(KEYMAP_FILE) \ $(KEYMAP_FILE) \
$(QUANTUM_DIR)/quantum.c \ $(QUANTUM_DIR)/quantum.c \
$(QUANTUM_DIR)/keymap.c \ $(QUANTUM_DIR)/keymap_common.c \
$(QUANTUM_DIR)/keycode_config.c \ $(QUANTUM_DIR)/keycode_config.c \
$(QUANTUM_DIR)/process_keycode/process_leader.c $(QUANTUM_DIR)/process_keycode/process_leader.c
@ -208,8 +218,25 @@ VPATH += $(QUANTUM_PATH)/keymap_extras
VPATH += $(QUANTUM_PATH)/audio VPATH += $(QUANTUM_PATH)/audio
VPATH += $(QUANTUM_PATH)/process_keycode 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 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 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") GIT_VERSION := $(shell git describe --abbrev=6 --dirty --always --tags 2>/dev/null || date +"%Y-%m-%d-%H:%M:%S")

4
Vagrantfile vendored

@ -78,7 +78,7 @@ Vagrant.configure(2) do |config|
# add a # before ,args: and run 'vagrant up' to get a working # add a # before ,args: and run 'vagrant up' to get a working
# non-updated box and then attempt to troubleshoot or open a Github issue # non-updated box and then attempt to troubleshoot or open a Github issue
config.vm.provision "shell", run: "always", path: "./util/avr_setup.sh", args: "-update" config.vm.provision "shell", run: "always", path: "./util/install_dependencies.sh", args: "-update"
config.vm.post_up_message = <<-EOT config.vm.post_up_message = <<-EOT
Log into the VM using 'vagrant ssh' on OSX or from Git Bash (Win) Log into the VM using 'vagrant ssh' on OSX or from Git Bash (Win)
@ -91,7 +91,7 @@ Vagrant.configure(2) do |config|
Or you can copy and paste the example line below. Or you can copy and paste the example line below.
cd /vagrant; cd keyboard; cd ergodox_ez; make clean; make cd /vagrant; cd keyboards; cd ergodox_ez; make clean; make
EOT EOT

@ -62,7 +62,7 @@ KC_NONUS_HASH KC_NUHS 32 Keyboard Non-US # and ~
KC_SCOLON KC_SCLN 33 Keyboard ; and : KC_SCOLON KC_SCLN 33 Keyboard ; and :
KC_QUOTE KC_QUOT 34 Keyboard and “ KC_QUOTE KC_QUOT 34 Keyboard and “
KC_GRAVE KC_GRV 35 Keyboard Grave Accent and Tilde KC_GRAVE KC_GRV 35 Keyboard Grave Accent and Tilde
KC_COMMA KC_COMM 36 Keyboard, and < KC_COMMA KC_COMM 36 Keyboard , and <
KC_DOT 37 Keyboard . and > KC_DOT 37 Keyboard . and >
KC_SLASH KC_SLSH 38 Keyboard / and ? KC_SLASH KC_SLSH 38 Keyboard / and ?
KC_CAPSLOCK KC_CAPS 39 Keyboard Caps Lock KC_CAPSLOCK KC_CAPS 39 Keyboard Caps Lock
@ -92,7 +92,7 @@ KC_LEFT 50 Keyboard LeftArrow1
KC_DOWN 51 Keyboard DownArrow1 KC_DOWN 51 Keyboard DownArrow1
KC_UP 52 Keyboard UpArrow1 KC_UP 52 Keyboard UpArrow1
KC_NUMLOCK KC_NLCK 53 Keypad Num Lock and Clear11 KC_NUMLOCK KC_NLCK 53 Keypad Num Lock and Clear11
KC_KP_SLASH KC_PSLS 54 Keypad /1 KC_KP_SLASH KC_PSLS 54 Keypad /
KC_KP_ASTERISK KC_PAST 55 Keypad * KC_KP_ASTERISK KC_PAST 55 Keypad *
KC_KP_MINUS KC_PMNS 56 Keypad - KC_KP_MINUS KC_PMNS 56 Keypad -
KC_KP_PLUS KC_PPLS 57 Keypad + KC_KP_PLUS KC_PPLS 57 Keypad +

@ -27,7 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define DEVICE_VER 0x0001 #define DEVICE_VER 0x0001
#define MANUFACTURER ErgoDox EZ #define MANUFACTURER ErgoDox EZ
#define PRODUCT ErgoDox EZ #define PRODUCT ErgoDox EZ
#define DESCRIPTION t.m.k. keyboard firmware for Ergodox #define DESCRIPTION QMK keyboard firmware for Ergodox EZ
/* key matrix size */ /* key matrix size */
#define MATRIX_ROWS 14 #define MATRIX_ROWS 14
@ -40,12 +40,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define TAPPING_TOGGLE 1 #define TAPPING_TOGGLE 1
#define COLS (int []){ F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }
#define ROWS (int []){ D0, D5, B5, B6 }
/* COL2ROW or ROW2COL */
#define DIODE_DIRECTION COL2ROW
/* define if matrix has ghost */ /* define if matrix has ghost */
//#define MATRIX_HAS_GHOST //#define MATRIX_HAS_GHOST
@ -53,7 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#define BACKLIGHT_LEVELS 3 #define BACKLIGHT_LEVELS 3
/* Set 0 if debouncing isn't needed */ /* Set 0 if debouncing isn't needed */
#define DEBOUNCE 2 #define DEBOUNCE 5
#define TAPPING_TERM 200 #define TAPPING_TERM 200
#define IGNORE_MOD_TAP_INTERRUPT // this makes it possible to do rolling combos (zx) with keys that convert to other keys on hold (z becomes ctrl when you hold it, and when this option isn't enabled, z rapidly followed by x actually sends Ctrl-x. That's bad.) #define IGNORE_MOD_TAP_INTERRUPT // this makes it possible to do rolling combos (zx) with keys that convert to other keys on hold (z becomes ctrl when you hold it, and when this option isn't enabled, z rapidly followed by x actually sends Ctrl-x. That's bad.)

@ -27,7 +27,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <avr/io.h> #include <avr/io.h>
#include <util/delay.h> #include "wait.h"
#include "action_layer.h" #include "action_layer.h"
#include "print.h" #include "print.h"
#include "debug.h" #include "debug.h"
@ -166,6 +166,7 @@ uint8_t matrix_scan(void)
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
select_row(i); select_row(i);
wait_us(30); // without this wait read unstable value.
matrix_row_t cols = read_cols(i); matrix_row_t cols = read_cols(i);
if (matrix_debouncing[i] != cols) { if (matrix_debouncing[i] != cols) {
matrix_debouncing[i] = cols; matrix_debouncing[i] = cols;
@ -179,7 +180,7 @@ uint8_t matrix_scan(void)
if (debouncing) { if (debouncing) {
if (--debouncing) { if (--debouncing) {
_delay_ms(1); wait_us(1);
} else { } else {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i]; matrix[i] = matrix_debouncing[i];
@ -267,7 +268,6 @@ static matrix_row_t read_cols(uint8_t row)
return data; return data;
} }
} else { } else {
_delay_us(30); // without this wait read unstable value.
// read from teensy // read from teensy
return return
(PINF&(1<<0) ? 0 : (1<<0)) | (PINF&(1<<0) ? 0 : (1<<0)) |

@ -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
--------
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
MCU_FAMILY = KINETIS
MCU_SERIES = KL2x
# - it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <this_dir>/ld/
MCU_LDSCRIPT = MKL26Z64
# - it should exist in <chibios>/os/common/ports/ARMCMx/compilers/GCC/mk/
MCU_STARTUP = kl2x
# Board: it should exist either in <chibios>/os/hal/boards/
# or <this_dir>/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

@ -0,0 +1,70 @@
# project specific files
SRC = matrix.c \
led.c
## chip/board settings
# - the next two should match the directories in
# <chibios>/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 <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <this_dir>/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 <chibios>/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 <chibios>/os/hal/boards/
# or <this_dir>/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

@ -0,0 +1 @@
#define KIIBOHD_BOOTLOADER

@ -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 */
/** @} */

@ -0,0 +1,75 @@
/*
Copyright 2015 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

@ -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_ */
/** @} */

@ -0,0 +1,17 @@
/*
Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "infinity_chibios.h"

@ -0,0 +1,66 @@
/*
Copyright 2014 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

@ -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),
};

@ -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;
}
}

@ -0,0 +1,24 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "hal.h"
#include "led.h"
void led_set(uint8_t usb_led) {
}

@ -0,0 +1,128 @@
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#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<<col));
}
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_print(void)
{
xprintf("\nr/c 01234567\n");
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
xprintf("%02X: ");
matrix_row_t data = matrix_get_row(row);
for (int col = 0; col < MATRIX_COLS; col++) {
if (data & (1<<col))
xprintf("1");
else
xprintf("0");
}
xprintf("\n");
}
}

@ -0,0 +1,55 @@
/*
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 _MCUCONF_H_
#define _MCUCONF_H_
#define K20x_MCUCONF
/*
* HAL driver system settings.
*/
/* Select the MCU clocking mode below by enabling the appropriate block. */
#define KINETIS_NO_INIT FALSE
/* FEI mode - 48 MHz with internal 32.768 kHz crystal */
#define KINETIS_MCG_MODE KINETIS_MCG_MODE_FEI
#define KINETIS_MCG_FLL_DMX32 1 /* Fine-tune for 32.768 kHz */
#define KINETIS_MCG_FLL_DRS 1 /* 1464x FLL factor */
#define KINETIS_SYSCLK_FREQUENCY 47972352UL /* 32.768 kHz * 1464 (~48 MHz) */
#define KINETIS_CLKDIV1_OUTDIV1 1
#define KINETIS_CLKDIV1_OUTDIV2 1
#define KINETIS_CLKDIV1_OUTDIV4 2
#define KINETIS_BUSCLK_FREQUENCY KINETIS_SYSCLK_FREQUENCY
#define KINETIS_FLASHCLK_FREQUENCY KINETIS_SYSCLK_FREQUENCY/2
/*
* SERIAL driver system settings.
*/
#define KINETIS_SERIAL_USE_UART0 TRUE
/*
* USB driver settings
*/
#define KINETIS_USB_USE_USB0 TRUE
/* Need to redefine this, since the default is for K20x */
/* This is for Teensy LC; you should comment it out (or change to 5)
* for Teensy 3.x */
#define KINETIS_USB_USB0_IRQ_PRIORITY 2
#endif /* _MCUCONF_H_ */

@ -21,5 +21,5 @@ SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
NKRO_ENABLE ?= yes # USB Nkey Rollover NKRO_ENABLE ?= yes # USB Nkey Rollover
ifndef QUANTUM_DIR ifndef QUANTUM_DIR
include ../../Makefile include ../../../../Makefile
endif endif

@ -0,0 +1,24 @@
# Build Options
# change yes to no to disable
#
BOOTMAGIC_ENABLE ?= yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE ?= no # Mouse keys(+4700)
EXTRAKEY_ENABLE ?= yes # Audio control and System control(+450)
CONSOLE_ENABLE ?= no # Console for debug(+400)
COMMAND_ENABLE ?= no # Commands for debug and configuration
KEYBOARD_LOCK_ENABLE ?= yes # Allow locking of keyboard via magic key
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
NKRO_ENABLE ?= yes # USB Nkey Rollover
BACKLIGHT_ENABLE ?= yes # Enable keyboard backlight functionality
MIDI_ENABLE ?= no # MIDI controls
UNICODE_ENABLE ?= no # Unicode
BLUETOOTH_ENABLE ?= no # Enable Bluetooth with the Adafruit EZ-Key HID
AUDIO_ENABLE ?= no # Audio output on port C6
ifndef QUANTUM_DIR
include ../../../../Makefile
endif

@ -0,0 +1,62 @@
// This keymap was designed to close to the default kc60 layout, with some useful changes, such as adding media keys.
// It also moves the reset key off the base layer, as in the default kc60 layout for this firmware.
// I have swapped FN and RGUI as my rainbow keyset has them in the opposite order.
#include "kc60.h"
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Basic QWERTY
* ,-----------------------------------------------------------.
* |Esc | 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp |
* |-----------------------------------------------------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \ |
* |-----------------------------------------------------------|
* |CAPS | A| S| D| F| G| H| J| K| L| ;| '|Return |
* |-----------------------------------------------------------|
* |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift |
* |-----------------------------------------------------------|
* |Ctrl|Gui |Alt | Space |Alt |FN |Gui |Ctrl |
* `-----------------------------------------------------------'
*/
[0] = KEYMAP(
KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, \
KC_CAPS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NO, KC_ENT, \
KC_LSFT, KC_NO, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_NO, KC_RSFT, \
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RGUI, KC_RCTL \
),
/*
* ,-----------------------------------------------------------.
* | ` |F1| F2| F3| F4| F5| F6| F7| F8| F9|F10|F11|F12| Del |
* |-----------------------------------------------------------|
* | | | Up| | | | | | | | PS| | | |
* |-----------------------------------------------------------|
* | |Lft|Dwn|Rgt| |BL-|BL+| | | | | | |
* |-----------------------------------------------------------|
* | |Prv| PP|Nxt| | | | |Hom|End| | |
* |-----------------------------------------------------------|
* | Rst| | | BL | | | | |
* `-----------------------------------------------------------'
* PS = Print Screen
* PP = Play/Pause
*/
[1] = KEYMAP( /* Function Layer */
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DELETE, \
KC_TRNS, KC_TRNS, KC_UP, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, BL_DEC, BL_INC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_MPRV, KC_MPLY, KC_MNXT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_END, KC_TRNS, KC_TRNS, KC_TRNS, \
RESET, KC_TRNS, KC_TRNS, BL_TOGG, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS \
),
};
const uint16_t PROGMEM fn_actions[] = {
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
return MACRO_NONE;
};

@ -0,0 +1,14 @@
Wigguno's KC60 Layout
======================
## Quantum MK Firmware
For the full Quantum feature list, see [the parent readme.md](/readme.md).
## Changes from default QMK layout
The default QMK layout for KC60 does not have a function layer. It also has the bootloader-mode reset key bound. This keymap fixes both of these by adding a sensible function layer (including moving the reset key onto it, far away from the FN key).
### Changes from the default KC60 layout
The default KC60 layout is good, but it was missing media keys. I've added previous, play/pause and next. I've also removed some of the keys from the function layer I didn't use.
### Build
To enable NKRO you must be in the keymaps/wigguno directory when running make.

@ -21,5 +21,5 @@ SLEEP_LED_ENABLE ?= no # Breathing sleep LED during USB suspend
NKRO_ENABLE ?= no # USB Nkey Rollover NKRO_ENABLE ?= no # USB Nkey Rollover
ifndef QUANTUM_DIR ifndef QUANTUM_DIR
include ../../Makefile include ../../../../Makefile
endif endif

@ -0,0 +1,66 @@
-------- begin --------
avr-gcc.exe (AVR_8_bit_GNU_Toolchain_3.5.0_1662) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Compiling: ../../keyboards/planck/planck.c [OK]
Compiling: ../../keyboards/planck/keymaps/experimental/keymap.c [WARNINGS]
|
| ../../keyboards/planck/keymaps/experimental/keymap.c: In function 'action_get_macro':
| ../../keyboards/planck/keymaps/experimental/keymap.c:227:17: warning: implicit declaration of function 'breathing_speed_set' [-Wimplicit-function-declaration]
| breathing_speed_set(2);
| ^
| ../../keyboards/planck/keymaps/experimental/keymap.c:228:17: warning: implicit declaration of function 'breathing_pulse' [-Wimplicit-function-declaration]
| breathing_pulse();
| ^
|
Compiling: ../../quantum/quantum.c [OK]
Compiling: ../../quantum/keymap.c [OK]
Compiling: ../../quantum/keycode_config.c [OK]
Compiling: ../../quantum/matrix.c [OK]
Compiling: ../../quantum/audio/audio.c [OK]
Compiling: ../../quantum/audio/voices.c [OK]
Compiling: ../../quantum/audio/luts.c [OK]
Compiling: ../../tmk_core/protocol/lufa/lufa.c [OK]
Compiling: ../../tmk_core/protocol/lufa/descriptor.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Class/Common/HIDParser.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Device_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/EndpointStream_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Endpoint_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Host_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/PipeStream_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/Pipe_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/USBController_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/AVR8/USBInterrupt_AVR8.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/ConfigDescriptors.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/DeviceStandardReq.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/Events.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/HostStandardReq.c [OK]
Compiling: ../../tmk_core/protocol/lufa/LUFA-git/LUFA/Drivers/USB/Core/USBTask.c [OK]
Compiling: ../../tmk_core/common/host.c [OK]
Compiling: ../../tmk_core/common/keyboard.c [OK]
Compiling: ../../tmk_core/common/action.c [OK]
Compiling: ../../tmk_core/common/action_tapping.c [OK]
Compiling: ../../tmk_core/common/action_macro.c [OK]
Compiling: ../../tmk_core/common/action_layer.c [OK]
Compiling: ../../tmk_core/common/action_util.c [OK]
Compiling: ../../tmk_core/common/print.c [OK]
Compiling: ../../tmk_core/common/debug.c [OK]
Compiling: ../../tmk_core/common/util.c [OK]
Compiling: ../../tmk_core/common/avr/suspend.c [OK]
Assembling: ../../tmk_core/common/avr/xprintf.S [OK]
Compiling: ../../tmk_core/common/avr/timer.c [OK]
Compiling: ../../tmk_core/common/avr/bootloader.c [OK]
Compiling: ../../tmk_core/common/magic.c [OK]
Compiling: ../../tmk_core/common/avr/eeconfig.c [OK]
Compiling: ../../tmk_core/common/mousekey.c [OK]
Compiling: ../../tmk_core/common/command.c [OK]
Compiling: ../../tmk_core/common/backlight.c [OK]
Linking: .build/planck_experimental.elf [ERRORS]
|
| .build/obj_planck_experimental/keyboards/planck/keymaps/experimental/keymap.o: In function `action_get_macro':
| C:\Users\Fred Wales\Documents\Programming\qmk_firmware\keyboards\planck/../../keyboards/planck/keymaps/experimental/keymap.c:240: undefined reference to `breathing_speed_set'
| C:\Users\Fred Wales\Documents\Programming\qmk_firmware\keyboards\planck/../../keyboards/planck/keymaps/experimental/keymap.c:241: undefined reference to `breathing_pulse'
| collect2.exe: error: ld returned 1 exit status
|

@ -0,0 +1,149 @@
#include "satan.h"
#ifdef RGBLIGHT_ENABLE
#include "rgblight.h"
#endif
// Used for SHIFT_ESC
#define MODS_CTRL_MASK (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT))
// Each layer gets a name for readability, which is then used in the keymap matrix below.
// The underscores don't mean anything - you can have a layer called STUFF or any other name.
// Layer names don't all need to be of the same length, obviously, and you can also skip them
// entirely and just use numbers.
#define _BL 0
#define _FL 1
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
/* Keymap _BL: (Base Layer) Default Layer
* ,-----------------------------------------------------------.
* |Esc~| 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =| \ | ~ |
* |-----------------------------------------------------------|
* |Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]|bksp |
* |-----------------------------------------------------------|
* |CAPS | A| S| D| F| G| H| J| K| L| ;| '|Return |
* |-----------------------------------------------------------|
* |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift| fn |
* |-----------------------------------------------------------|
* |Ctrl|Gui |Alt | Space |Alt |Gui |FN |Ctrl |
* `-----------------------------------------------------------'
*/
[_BL] = KEYMAP_HHKB(
F(0), KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSLS, KC_GRV, \
KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSPC, \
KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, \
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, MO(_FL), \
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_MENU, KC_RCTL),
[_FL] = KEYMAP_HHKB(
#ifdef RGBLIGHT_ENABLE
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, RESET, \
KC_CAPS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_BSPC, \
KC_TRNS, KC_VOLD, KC_VOLU, KC_MUTE, KC_TRNS, KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
#else
KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_TRNS, RESET, \
KC_CAPS, KC_TRNS, F(1), F(2), F(3), KC_TRNS, KC_TRNS, KC_TRNS, KC_PSCR, KC_SLCK, KC_PAUS, KC_UP, KC_TRNS, KC_BSPC, \
KC_TRNS, KC_VOLD, F(4), F(5), F(6), KC_TRNS, KC_PAST, KC_PSLS, KC_HOME, KC_PGUP, KC_LEFT, KC_RGHT, KC_PENT, \
KC_TRNS, F(7), F(8), KC_TRNS, KC_TRNS, KC_TRNS, KC_PPLS, KC_PMNS, KC_END, KC_PGDN, KC_DOWN, KC_TRNS, KC_TRNS, \
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS),
#endif
};
enum function_id {
SHIFT_ESC,
#ifdef RGBLIGHT_ENABLE
RGBLED_TOGGLE,
RGBLED_STEP_MODE,
RGBLED_INCREASE_HUE,
RGBLED_DECREASE_HUE,
RGBLED_INCREASE_SAT,
RGBLED_DECREASE_SAT,
RGBLED_INCREASE_VAL,
RGBLED_DECREASE_VAL
#endif
};
const uint16_t PROGMEM fn_actions[] = {
[0] = ACTION_FUNCTION(SHIFT_ESC),
#ifdef RGBLIGHT_ENABLE
[1] = ACTION_FUNCTION(RGBLED_TOGGLE),
[2] = ACTION_FUNCTION(RGBLED_STEP_MODE),
[3] = ACTION_FUNCTION(RGBLED_INCREASE_HUE),
[4] = ACTION_FUNCTION(RGBLED_DECREASE_HUE),
[5] = ACTION_FUNCTION(RGBLED_INCREASE_SAT),
[6] = ACTION_FUNCTION(RGBLED_DECREASE_SAT),
[7] = ACTION_FUNCTION(RGBLED_INCREASE_VAL),
[8] = ACTION_FUNCTION(RGBLED_DECREASE_VAL),
#endif
};
void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
static uint8_t shift_esc_shift_mask;
switch (id) {
case SHIFT_ESC:
shift_esc_shift_mask = get_mods()&MODS_CTRL_MASK;
if (record->event.pressed) {
if (shift_esc_shift_mask) {
add_key(KC_GRV);
send_keyboard_report();
} else {
add_key(KC_ESC);
send_keyboard_report();
}
} else {
if (shift_esc_shift_mask) {
del_key(KC_GRV);
send_keyboard_report();
} else {
del_key(KC_ESC);
send_keyboard_report();
}
}
break;
//led operations
#ifdef RGBLIGHT_ENABLE
case RGBLED_TOGGLE:
if (record->event.pressed) {
rgblight_toggle();
}
break;
case RGBLED_INCREASE_HUE:
if (record->event.pressed) {
rgblight_increase_hue();
}
break;
case RGBLED_DECREASE_HUE:
if (record->event.pressed) {
rgblight_decrease_hue();
}
break;
case RGBLED_INCREASE_SAT:
if (record->event.pressed) {
rgblight_increase_sat();
}
break;
case RGBLED_DECREASE_SAT:
if (record->event.pressed) {
rgblight_decrease_sat();
}
break;
case RGBLED_INCREASE_VAL:
if (record->event.pressed) {
rgblight_increase_val();
}
break;
case RGBLED_DECREASE_VAL:
if (record->event.pressed) {
rgblight_decrease_val();
}
break;
case RGBLED_STEP_MODE:
if (record->event.pressed) {
rgblight_step();
}
break;
#endif
}
}

@ -26,13 +26,43 @@
k40, k41, k42, k45, k4a, k4b, k4c, k4d \ k40, k41, k42, k45, k4a, k4b, k4c, k4d \
) \ ) \
{ \ { \
{k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d}, \ {k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d}, \
{k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d}, \ {k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d}, \
{k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, KC_NO, k2d}, \ {k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, KC_NO, k2d}, \
{k30, KC_NO, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, KC_NO, k3d}, \ {k30, KC_NO, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, KC_NO, k3d}, \
{k40, k41, k42, KC_NO, KC_NO, k45, KC_NO, KC_NO, KC_NO, KC_NO, k4a, k4b, k4c, k4d} \ {k40, k41, k42, KC_NO, KC_NO, k45, KC_NO, KC_NO, KC_NO, KC_NO, k4a, k4b, k4c, k4d} \
} }
/* Satan HHKB matrix layout
* ,------------------------------------------------------------.
* | 00 |01| 02| 03| 04| 05| 06| 07| 08| 09| 0a| 0b| 0c| 0d| 49 |
* |------------------------------------------------------------|
* | 10 | 11| 12| 13| 14| 15| 16| 17| 18| 19| 1a| 1b| 1c| 1d |
* |------------------------------------------------------------|
* | 20 | 21| 22| 23| 24| 25| 26| 27| 28| 29| 2a| 2b| 2d |
* |------------------------------------------------------------|
* | 30 | 32| 33| 34| 35| 36| 37| 38| 39| 3a| 3b| 3d | 3c |
* |------------------------------------------------------------|
* | 40 | 41 | 42 | 45 | 4a | 4b | 4c | 4d |
* `------------------------------------------------------------'
*/
#define KEYMAP_HHKB( \
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d, k49, \
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d, \
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, k2d, \
k30, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3d, k3c, \
k40, k41, k42, k45, k4a, k4b, k4c, k4d \
) \
{ \
{k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0a, k0b, k0c, k0d}, \
{k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1a, k1b, k1c, k1d}, \
{k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2a, k2b, KC_NO, k2d}, \
{k30, KC_NO, k32, k33, k34, k35, k36, k37, k38, k39, k3a, k3b, k3c, k3d}, \
{k40, k41, k42, KC_NO, KC_NO, k45, KC_NO, KC_NO, KC_NO, k49, k4a, k4b, k4c, k4d} \
}
void matrix_init_user(void); void matrix_init_user(void);
void matrix_scan_user(void); void matrix_scan_user(void);

@ -0,0 +1,50 @@
# project specific files
SRC = matrix.c \
led.c
## chip/board settings
# the next two should match the directories in
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
MCU_FAMILY = STM32
MCU_SERIES = STM32F0xx
# linker script to use
# it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <this_dir>/ld/
MCU_LDSCRIPT = STM32F072xB
# startup code to use
# is should exist in <chibios>/os/common/ports/ARMCMx/compilers/GCC/mk/
MCU_STARTUP = stm32f0xx
# it should exist either in <chibios>/os/hal/boards/
# or <this_dir>/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/<FOO>/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_dir>/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

@ -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_dir>/tmk_core/tool/chibios/ch-bootloader-jump.patch
*/
#define STM32_BOOTLOADER_ADDRESS 0x1FFFC800

@ -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 */
/** @} */

@ -0,0 +1,76 @@
/*
Copyright 2015 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

@ -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_ */
/** @} */

@ -0,0 +1,25 @@
/*
Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "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[] = {
};

@ -0,0 +1,34 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "hal.h"
#include "led.h"
void led_set(uint8_t usb_led)
{
(void)usb_led;
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
// output high
palSetPadMode(GPIOC, GPIOC_LED_GREEN, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(GPIOC, GPIOC_LED_GREEN);
} else {
// Hi-Z
palSetPadMode(GPIOC, GPIOC_LED_GREEN, PAL_MODE_INPUT);
}
}

@ -0,0 +1,163 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "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<<col));
}
inline
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_print(void)
{
print("\nr/c 0123456789ABCDEF\n");
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
phex(row); print(": ");
pbin_reverse16(matrix_get_row(row));
print("\n");
}
}
/* Column pin configuration
*/
static void init_cols(void)
{
// don't need pullup/down, since it's pulled down in hardware
palSetPadMode(GPIOA, GPIOA_BUTTON, PAL_MODE_INPUT);
}
/* Returns status of switches(1:on, 0:off) */
static matrix_row_t read_cols(void)
{
return ((palReadPad(GPIOA, GPIOA_BUTTON)==PAL_LOW) ? 0 : (1<<0));
// | ((palReadPad(...)==PAL_HIGH) ? 0 : (1<<1))
}
/* Row pin configuration
*/
static void unselect_rows(void)
{
// palSetPadMode(GPIOA, GPIOA_PIN10, PAL_MODE_INPUT); // hi-Z
}
static void select_row(uint8_t row)
{
(void)row;
// Output low to select
// switch (row) {
// case 0:
// palSetPadMode(GPIOA, GPIOA_PIN10, PAL_MODE_OUTPUT_PUSHPULL);
// palSetPad(GPIOA, GPIOA_PIN10, PAL_LOW);
// break;
// }
}

@ -0,0 +1,171 @@
/*
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 _MCUCONF_H_
#define _MCUCONF_H_
/*
* STM32F0xx drivers configuration.
* The following settings override the default settings present in
* the various device driver implementation headers.
* Note that the settings for each driver only have effect if the whole
* driver is enabled in halconf.h.
*
* IRQ priorities:
* 3...0 Lowest...Highest.
*
* DMA priorities:
* 0...3 Lowest...Highest.
*/
#define STM32F0xx_MCUCONF
/*
* HAL driver system settings.
*/
#define STM32_NO_INIT FALSE
#define STM32_PVD_ENABLE FALSE
#define STM32_PLS STM32_PLS_LEV0
#define STM32_HSI_ENABLED TRUE
#define STM32_HSI14_ENABLED TRUE
#define STM32_HSI48_ENABLED FALSE
#define STM32_LSI_ENABLED TRUE
#define STM32_HSE_ENABLED FALSE
#define STM32_LSE_ENABLED FALSE
#define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_HSI_DIV2
#define STM32_PREDIV_VALUE 1
#define STM32_PLLMUL_VALUE 12
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE STM32_PPRE_DIV1
#define STM32_ADCSW STM32_ADCSW_HSI14
#define STM32_ADCPRE STM32_ADCPRE_DIV4
#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
#define STM32_ADCPRE STM32_ADCPRE_DIV4
#define STM32_ADCSW STM32_ADCSW_HSI14
#define STM32_USBSW STM32_USBSW_HSI48
#define STM32_CECSW STM32_CECSW_HSI
#define STM32_I2C1SW STM32_I2C1SW_HSI
#define STM32_USART1SW STM32_USART1SW_PCLK
#define STM32_RTCSEL STM32_RTCSEL_LSI
/*
* ADC driver system settings.
*/
#define STM32_ADC_USE_ADC1 FALSE
#define STM32_ADC_ADC1_DMA_PRIORITY 2
#define STM32_ADC_IRQ_PRIORITY 2
#define STM32_ADC_ADC1_DMA_IRQ_PRIORITY 2
/*
* EXT driver system settings.
*/
#define STM32_EXT_EXTI0_1_IRQ_PRIORITY 3
#define STM32_EXT_EXTI2_3_IRQ_PRIORITY 3
#define STM32_EXT_EXTI4_15_IRQ_PRIORITY 3
#define STM32_EXT_EXTI16_IRQ_PRIORITY 3
#define STM32_EXT_EXTI17_IRQ_PRIORITY 3
/*
* GPT driver system settings.
*/
#define STM32_GPT_USE_TIM1 FALSE
#define STM32_GPT_USE_TIM2 FALSE
#define STM32_GPT_USE_TIM3 FALSE
#define STM32_GPT_USE_TIM14 FALSE
#define STM32_GPT_TIM1_IRQ_PRIORITY 2
#define STM32_GPT_TIM2_IRQ_PRIORITY 2
#define STM32_GPT_TIM3_IRQ_PRIORITY 2
#define STM32_GPT_TIM14_IRQ_PRIORITY 2
/*
* I2C driver system settings.
*/
#define STM32_I2C_USE_I2C1 FALSE
#define STM32_I2C_USE_I2C2 FALSE
#define STM32_I2C_BUSY_TIMEOUT 50
#define STM32_I2C_I2C1_IRQ_PRIORITY 3
#define STM32_I2C_I2C2_IRQ_PRIORITY 3
#define STM32_I2C_USE_DMA TRUE
#define STM32_I2C_I2C1_DMA_PRIORITY 1
#define STM32_I2C_I2C2_DMA_PRIORITY 1
#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
/*
* ICU driver system settings.
*/
#define STM32_ICU_USE_TIM1 FALSE
#define STM32_ICU_USE_TIM2 FALSE
#define STM32_ICU_USE_TIM3 FALSE
#define STM32_ICU_TIM1_IRQ_PRIORITY 3
#define STM32_ICU_TIM2_IRQ_PRIORITY 3
#define STM32_ICU_TIM3_IRQ_PRIORITY 3
/*
* PWM driver system settings.
*/
#define STM32_PWM_USE_ADVANCED FALSE
#define STM32_PWM_USE_TIM1 FALSE
#define STM32_PWM_USE_TIM2 FALSE
#define STM32_PWM_USE_TIM3 FALSE
#define STM32_PWM_TIM1_IRQ_PRIORITY 3
#define STM32_PWM_TIM2_IRQ_PRIORITY 3
#define STM32_PWM_TIM3_IRQ_PRIORITY 3
/*
* SERIAL driver system settings.
*/
#define STM32_SERIAL_USE_USART1 FALSE
#define STM32_SERIAL_USE_USART2 FALSE
#define STM32_SERIAL_USART1_PRIORITY 3
#define STM32_SERIAL_USART2_PRIORITY 3
/*
* SPI driver system settings.
*/
#define STM32_SPI_USE_SPI1 FALSE
#define STM32_SPI_USE_SPI2 FALSE
#define STM32_SPI_SPI1_DMA_PRIORITY 1
#define STM32_SPI_SPI2_DMA_PRIORITY 1
#define STM32_SPI_SPI1_IRQ_PRIORITY 2
#define STM32_SPI_SPI2_IRQ_PRIORITY 2
#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
/*
* ST driver system settings.
*/
#define STM32_ST_IRQ_PRIORITY 2
#define STM32_ST_USE_TIMER 2
/*
* UART driver system settings.
*/
#define STM32_UART_USE_USART1 FALSE
#define STM32_UART_USE_USART2 FALSE
#define STM32_UART_USART1_IRQ_PRIORITY 3
#define STM32_UART_USART2_IRQ_PRIORITY 3
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
/*
* USB driver system settings.
*/
#define STM32_USB_USE_USB1 TRUE
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
#define STM32_USB_USB1_LP_IRQ_PRIORITY 3
#endif /* _MCUCONF_H_ */

@ -0,0 +1 @@
#include "stm32_f072_onekey.h"

@ -0,0 +1,5 @@
#ifndef STM32_F072_ONEKEY_H
#define STM32_F072_ONEKEY_H
#include "quantum.h"
#endif

@ -0,0 +1,64 @@
# project specific files
SRC = matrix.c \
led.c
# GENERIC STM32F103C8T6 board - stm32duino bootloader
OPT_DEFS = -DCORTEX_VTOR_INIT=0x2000
MCU_LDSCRIPT = STM32F103x8_stm32duino_bootloader
BOARD = GENERIC_STM32_F103
# GENERIC STM32F103C8T6 board - no bootloader (programmer over serial or SWD)
# OPT_DEFS =
# MCU_LDSCRIPT = STM32F103x8
# BOARD = GENERIC_STM32_F103
# MAPLE MINI
# OPT_DEFS = -DCORTEX_VTOR_INIT=0x5000
# MCU_LDSCRIPT = STM32F103xB_maplemini_bootloader
# BOARD = MAPLEMINI_STM32_F103
## chip/board settings
# the next two should match the directories in
# <chibios>/os/hal/ports/$(MCU_FAMILY)/$(MCU_SERIES)
MCU_FAMILY = STM32
MCU_SERIES = STM32F1xx
# linker script to use
# it should exist either in <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <this_dir>/ld/
# startup code to use
# is should exist in <chibios>/os/common/ports/ARMCMx/compilers/GCC/mk/
MCU_STARTUP = stm32f1xx
# it should exist either in <chibios>/os/hal/boards/
# or <this_dir>/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/<FOO>/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_dir>/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

@ -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) {
}

@ -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_ */

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 159 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 232 KiB

@ -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_dir>/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

@ -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 */
/** @} */

@ -0,0 +1,75 @@
/*
Copyright 2015 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

@ -0,0 +1,2 @@
#!/bin/bash
Arduino_STM32_usb_hid/tools/linux/maple_upload ttyACM0 2 1EAF:0003 build/ch.bin

@ -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_ */
/** @} */

@ -0,0 +1,25 @@
/*
Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "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[] = {
};

@ -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

@ -0,0 +1,43 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "hal.h"
#include "led.h"
void led_set(uint8_t usb_led)
{
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
/* generic STM32F103C8T6 board */
#ifdef BOARD_GENERIC_STM32_F103
palClearPad(GPIOC, 13);
#endif
/* Maple Mini */
#ifdef BOARD_MAPLEMINI_STM32_F103
palSetPad(GPIOB, 1);
#endif
} else {
/* generic STM32F103C8T6 board */
#ifdef BOARD_GENERIC_STM32_F103
palSetPad(GPIOC, 13);
#endif
/* Maple Mini */
#ifdef BOARD_MAPLEMINI_STM32_F103
palClearPad(GPIOB,1);
#endif
}
}

@ -0,0 +1,177 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "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<<col));
}
inline
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_print(void)
{
print("\nr/c 0123456789ABCDEF\n");
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
phex(row); print(": ");
pbin_reverse16(matrix_get_row(row));
print("\n");
}
}
/* Column pin configuration
*/
static void init_cols(void)
{
#ifdef BOARD_MAPLEMINI_STM32_F103
// don't need pullup/down, since it's pulled down in hardware
palSetPadMode(GPIOB, 8, PAL_MODE_INPUT);
#else
palSetPadMode(GPIOB, 8, PAL_MODE_INPUT_PULLDOWN);
#endif
}
/* Returns status of switches(1:on, 0:off) */
static matrix_row_t read_cols(void)
{
return ((palReadPad(GPIOB, 8)==PAL_LOW) ? 0 : (1<<0));
// | ((palReadPad(...)==PAL_HIGH) ? 0 : (1<<1))
}
/* Row pin configuration
*/
static void unselect_rows(void)
{
// palSetPadMode(GPIOA, GPIOA_PIN10, PAL_MODE_INPUT); // hi-Z
}
static void select_row(uint8_t row)
{
(void)row;
// Output low to select
// switch (row) {
// case 0:
// palSetPadMode(GPIOA, GPIOA_PIN10, PAL_MODE_OUTPUT_PUSHPULL);
// palSetPad(GPIOA, GPIOA_PIN10, PAL_LOW);
// break;
// }
}

@ -0,0 +1,209 @@
/*
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 _MCUCONF_H_
#define _MCUCONF_H_
#define STM32F103_MCUCONF
/*
* STM32F103 drivers configuration.
* The following settings override the default settings present in
* the various device driver implementation headers.
* Note that the settings for each driver only have effect if the whole
* driver is enabled in halconf.h.
*
* IRQ priorities:
* 15...0 Lowest...Highest.
*
* DMA priorities:
* 0...3 Lowest...Highest.
*/
/*
* HAL driver system settings.
*/
#define STM32_NO_INIT FALSE
#define STM32_HSI_ENABLED TRUE
#define STM32_LSI_ENABLED FALSE
#define STM32_HSE_ENABLED TRUE
#define STM32_LSE_ENABLED FALSE
#define STM32_SW STM32_SW_PLL
#define STM32_PLLSRC STM32_PLLSRC_HSE
#define STM32_PLLXTPRE STM32_PLLXTPRE_DIV1
#define STM32_PLLMUL_VALUE 9
#define STM32_HPRE STM32_HPRE_DIV1
#define STM32_PPRE1 STM32_PPRE1_DIV2
#define STM32_PPRE2 STM32_PPRE2_DIV2
#define STM32_ADCPRE STM32_ADCPRE_DIV4
#define STM32_USB_CLOCK_REQUIRED TRUE
#define STM32_USBPRE STM32_USBPRE_DIV1P5
#define STM32_MCOSEL STM32_MCOSEL_NOCLOCK
#define STM32_RTCSEL STM32_RTCSEL_HSEDIV
#define STM32_PVD_ENABLE FALSE
#define STM32_PLS STM32_PLS_LEV0
/*
* ADC driver system settings.
*/
#define STM32_ADC_USE_ADC1 FALSE
#define STM32_ADC_ADC1_DMA_PRIORITY 2
#define STM32_ADC_ADC1_IRQ_PRIORITY 6
/*
* CAN driver system settings.
*/
#define STM32_CAN_USE_CAN1 FALSE
#define STM32_CAN_CAN1_IRQ_PRIORITY 11
/*
* EXT driver system settings.
*/
#define STM32_EXT_EXTI0_IRQ_PRIORITY 6
#define STM32_EXT_EXTI1_IRQ_PRIORITY 6
#define STM32_EXT_EXTI2_IRQ_PRIORITY 6
#define STM32_EXT_EXTI3_IRQ_PRIORITY 6
#define STM32_EXT_EXTI4_IRQ_PRIORITY 6
#define STM32_EXT_EXTI5_9_IRQ_PRIORITY 6
#define STM32_EXT_EXTI10_15_IRQ_PRIORITY 6
#define STM32_EXT_EXTI16_IRQ_PRIORITY 6
#define STM32_EXT_EXTI17_IRQ_PRIORITY 6
#define STM32_EXT_EXTI18_IRQ_PRIORITY 6
#define STM32_EXT_EXTI19_IRQ_PRIORITY 6
/*
* GPT driver system settings.
*/
#define STM32_GPT_USE_TIM1 FALSE
#define STM32_GPT_USE_TIM2 FALSE
#define STM32_GPT_USE_TIM3 FALSE
#define STM32_GPT_USE_TIM4 FALSE
#define STM32_GPT_USE_TIM5 FALSE
#define STM32_GPT_USE_TIM8 FALSE
#define STM32_GPT_TIM1_IRQ_PRIORITY 7
#define STM32_GPT_TIM2_IRQ_PRIORITY 7
#define STM32_GPT_TIM3_IRQ_PRIORITY 7
#define STM32_GPT_TIM4_IRQ_PRIORITY 7
#define STM32_GPT_TIM5_IRQ_PRIORITY 7
#define STM32_GPT_TIM8_IRQ_PRIORITY 7
/*
* I2C driver system settings.
*/
#define STM32_I2C_USE_I2C1 FALSE
#define STM32_I2C_USE_I2C2 FALSE
#define STM32_I2C_BUSY_TIMEOUT 50
#define STM32_I2C_I2C1_IRQ_PRIORITY 5
#define STM32_I2C_I2C2_IRQ_PRIORITY 5
#define STM32_I2C_I2C1_DMA_PRIORITY 3
#define STM32_I2C_I2C2_DMA_PRIORITY 3
#define STM32_I2C_DMA_ERROR_HOOK(i2cp) osalSysHalt("DMA failure")
/*
* ICU driver system settings.
*/
#define STM32_ICU_USE_TIM1 FALSE
#define STM32_ICU_USE_TIM2 FALSE
#define STM32_ICU_USE_TIM3 FALSE
#define STM32_ICU_USE_TIM4 FALSE
#define STM32_ICU_USE_TIM5 FALSE
#define STM32_ICU_USE_TIM8 FALSE
#define STM32_ICU_TIM1_IRQ_PRIORITY 7
#define STM32_ICU_TIM2_IRQ_PRIORITY 7
#define STM32_ICU_TIM3_IRQ_PRIORITY 7
#define STM32_ICU_TIM4_IRQ_PRIORITY 7
#define STM32_ICU_TIM5_IRQ_PRIORITY 7
#define STM32_ICU_TIM8_IRQ_PRIORITY 7
/*
* PWM driver system settings.
*/
#define STM32_PWM_USE_ADVANCED FALSE
#define STM32_PWM_USE_TIM1 FALSE
#define STM32_PWM_USE_TIM2 FALSE
#define STM32_PWM_USE_TIM3 FALSE
#define STM32_PWM_USE_TIM4 FALSE
#define STM32_PWM_USE_TIM5 FALSE
#define STM32_PWM_USE_TIM8 FALSE
#define STM32_PWM_TIM1_IRQ_PRIORITY 7
#define STM32_PWM_TIM2_IRQ_PRIORITY 7
#define STM32_PWM_TIM3_IRQ_PRIORITY 7
#define STM32_PWM_TIM4_IRQ_PRIORITY 7
#define STM32_PWM_TIM5_IRQ_PRIORITY 7
#define STM32_PWM_TIM8_IRQ_PRIORITY 7
/*
* RTC driver system settings.
*/
#define STM32_RTC_IRQ_PRIORITY 15
/*
* SERIAL driver system settings.
*/
#define STM32_SERIAL_USE_USART1 FALSE
#define STM32_SERIAL_USE_USART2 FALSE
#define STM32_SERIAL_USE_USART3 FALSE
#define STM32_SERIAL_USE_UART4 FALSE
#define STM32_SERIAL_USE_UART5 FALSE
#define STM32_SERIAL_USART1_PRIORITY 12
#define STM32_SERIAL_USART2_PRIORITY 12
#define STM32_SERIAL_USART3_PRIORITY 12
#define STM32_SERIAL_UART4_PRIORITY 12
#define STM32_SERIAL_UART5_PRIORITY 12
/*
* SPI driver system settings.
*/
#define STM32_SPI_USE_SPI1 FALSE
#define STM32_SPI_USE_SPI2 FALSE
#define STM32_SPI_USE_SPI3 FALSE
#define STM32_SPI_SPI1_DMA_PRIORITY 1
#define STM32_SPI_SPI2_DMA_PRIORITY 1
#define STM32_SPI_SPI3_DMA_PRIORITY 1
#define STM32_SPI_SPI1_IRQ_PRIORITY 10
#define STM32_SPI_SPI2_IRQ_PRIORITY 10
#define STM32_SPI_SPI3_IRQ_PRIORITY 10
#define STM32_SPI_DMA_ERROR_HOOK(spip) osalSysHalt("DMA failure")
/*
* ST driver system settings.
*/
#define STM32_ST_IRQ_PRIORITY 8
#define STM32_ST_USE_TIMER 2
/*
* UART driver system settings.
*/
#define STM32_UART_USE_USART1 FALSE
#define STM32_UART_USE_USART2 FALSE
#define STM32_UART_USE_USART3 FALSE
#define STM32_UART_USART1_IRQ_PRIORITY 12
#define STM32_UART_USART2_IRQ_PRIORITY 12
#define STM32_UART_USART3_IRQ_PRIORITY 12
#define STM32_UART_USART1_DMA_PRIORITY 0
#define STM32_UART_USART2_DMA_PRIORITY 0
#define STM32_UART_USART3_DMA_PRIORITY 0
#define STM32_UART_DMA_ERROR_HOOK(uartp) osalSysHalt("DMA failure")
/*
* USB driver system settings.
*/
#define STM32_USB_USE_USB1 TRUE
#define STM32_USB_LOW_POWER_ON_SUSPEND FALSE
#define STM32_USB_USB1_HP_IRQ_PRIORITY 13
#define STM32_USB_USB1_LP_IRQ_PRIORITY 14
#endif /* _MCUCONF_H_ */

@ -0,0 +1 @@
#include "stm32_f103_onekey.h"

@ -0,0 +1,4 @@
#ifndef STM32_F103_ONEKEY_H
#define STM32_F103_ONEKEY_H
#include "quantum.h"
#endif

@ -0,0 +1,62 @@
# project specific files
SRC = matrix.c \
led.c
## chip/board settings
# - the next two should match the directories in
# <chibios>/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 <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <this_dir>/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 <chibios>/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 <chibios>/os/hal/boards/
# or <this_dir>/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

@ -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
# <chibios>/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 <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <this_dir>/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 <chibios>/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 <chibios>/os/hal/boards/
# or <this_dir>/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

@ -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
# <chibios>/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 <chibios>/os/common/ports/ARMCMx/compilers/GCC/ld/
# or <this_dir>/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 <chibios>/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 <chibios>/os/hal/boards/
# or <this_dir>/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

@ -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 */
/** @} */

@ -0,0 +1,75 @@
/*
Copyright 2015 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#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

@ -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_ */
/** @} */

@ -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-<long_hash_here>`) 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-<long_hash_here>` 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).

@ -0,0 +1,32 @@
/*
Copyright 2012,2013 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "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[] = {
};

@ -0,0 +1,105 @@
/*
* Copyright (C) 2013-2016 Fabio Utzig, http://fabioutzig.com
* (C) 2016 flabbergast <s3+flabbergast@sdfeu.org>
*
* 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

@ -0,0 +1,32 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "hal.h"
#include "led.h"
void led_set(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
// output high
palSetPadMode(TEENSY_PIN13_IOPORT, TEENSY_PIN13, PAL_MODE_OUTPUT_PUSHPULL);
palSetPad(TEENSY_PIN13_IOPORT, TEENSY_PIN13);
} else {
// Hi-Z
palSetPadMode(TEENSY_PIN13_IOPORT, TEENSY_PIN13, PAL_MODE_INPUT);
}
}

@ -0,0 +1,163 @@
/*
Copyright 2012 Jun Wako <wakojun@gmail.com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "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<<col));
}
inline
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_print(void)
{
print("\nr/c 0123456789ABCDEF\n");
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
phex(row); print(": ");
pbin_reverse16(matrix_get_row(row));
print("\n");
}
}
/* Column pin configuration
*/
static void init_cols(void)
{
// internal pull-up
palSetPadMode(TEENSY_PIN2_IOPORT, TEENSY_PIN2, PAL_MODE_INPUT_PULLUP);
}
/* Returns status of switches(1:on, 0:off) */
static matrix_row_t read_cols(void)
{
return ((palReadPad(TEENSY_PIN2_IOPORT, TEENSY_PIN2)==PAL_HIGH) ? 0 : (1<<0));
// | ((palReadPad(...)==PAL_HIGH) ? 0 : (1<<1))
}
/* Row pin configuration
*/
static void unselect_rows(void)
{
palSetPadMode(TEENSY_PIN5_IOPORT, TEENSY_PIN5, PAL_MODE_INPUT); // hi-Z
}
static void select_row(uint8_t row)
{
(void)row;
// Output low to select
switch (row) {
case 0:
palSetPadMode(TEENSY_PIN5_IOPORT, TEENSY_PIN5, PAL_MODE_OUTPUT_PUSHPULL);
palClearPad(TEENSY_PIN5_IOPORT, TEENSY_PIN5);
break;
}
}

@ -0,0 +1,55 @@
/*
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 _MCUCONF_H_
#define _MCUCONF_H_
#define KL2x_MCUCONF
/*
* HAL driver system settings.
*/
#if 1
/* PEE mode - 48MHz system clock driven by (16 MHz) external crystal. */
#define KINETIS_MCG_MODE KINETIS_MCG_MODE_PEE
#define KINETIS_PLLCLK_FREQUENCY 96000000UL
#define KINETIS_SYSCLK_FREQUENCY 48000000UL
#endif
#if 0
/* crystal-less FEI mode - 48 MHz with internal 32.768 kHz crystal */
#define KINETIS_MCG_MODE KINETIS_MCG_MODE_FEI
#define KINETIS_MCG_FLL_DMX32 1 /* Fine-tune for 32.768 kHz */
#define KINETIS_MCG_FLL_DRS 1 /* 1464x FLL factor */
#define KINETIS_SYSCLK_FREQUENCY 47972352UL /* 32.768 kHz * 1464 (~48 MHz) */
#define KINETIS_CLKDIV1_OUTDIV1 1 /* do not divide system clock */
#endif
/*
* SERIAL driver system settings.
*/
#define KINETIS_SERIAL_USE_UART0 TRUE
/*
* USB driver settings
*/
#define KINETIS_USB_USE_USB0 TRUE
/* Need to redefine this, since the default is for K20x */
/* This is for Teensy LC; you should comment it out (or change to 5)
* for Teensy 3.x */
#define KINETIS_USB_USB0_IRQ_PRIORITY 2
#endif /* _MCUCONF_H_ */

@ -0,0 +1 @@
#include "teensy_lc_onekey.h"

@ -0,0 +1,4 @@
#ifndef TEENSY_LC_ONEKEY_H
#define TEENSY_LC_ONEKEY_H
#include "quantum.h"
#endif

@ -0,0 +1 @@
Subproject commit a7df9a891067621e8e1a5c2a2c0ceada82403afe

@ -0,0 +1 @@
Subproject commit e1311c4db6cd366cf760673f769e925741ac0ad3

@ -18,4 +18,4 @@ typedef union {
}; };
} keymap_config_t; } keymap_config_t;
keymap_config_t keymap_config; extern keymap_config_t keymap_config;

@ -21,7 +21,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include "action.h" #include "action.h"
#if defined(__AVR__)
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#endif
#include "keycode.h" #include "keycode.h"
#include "action_macro.h" #include "action_macro.h"
#include "report.h" #include "report.h"
@ -30,12 +32,15 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "debug.h" #include "debug.h"
#include "keycode_config.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 */ /* translates key to keycode */
uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); 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 keymaps[][MATRIX_ROWS][MATRIX_COLS];
extern const uint16_t fn_actions[]; extern const uint16_t fn_actions[];

@ -19,7 +19,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "report.h" #include "report.h"
#include "keycode.h" #include "keycode.h"
#include "action_layer.h" #include "action_layer.h"
#if defined(__AVR__)
#include <util/delay.h> #include <util/delay.h>
#include <stdio.h>
#endif
#include "action.h" #include "action.h"
#include "action_macro.h" #include "action_macro.h"
#include "debug.h" #include "debug.h"
@ -32,7 +35,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
extern keymap_config_t keymap_config; extern keymap_config_t keymap_config;
#include <stdio.h>
#include <inttypes.h> #include <inttypes.h>
/* converts key to action */ /* converts key to action */
@ -46,10 +48,12 @@ action_t action_for_key(uint8_t layer, keypos_t key)
action_t action; action_t action;
uint8_t action_layer, when, mod; 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) { switch (keycode) {
case KC_FN0 ... KC_FN31: 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; break;
case KC_A ... KC_EXSEL: case KC_A ... KC_EXSEL:
case KC_LCTRL ... KC_RGUI: 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: ; case QK_FUNCTION ... QK_FUNCTION_MAX: ;
// Is a shortcut for function action_layer, pull last 12bits // Is a shortcut for function action_layer, pull last 12bits
// This means we have 4,096 FN macros at our disposal // 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; break;
case QK_MACRO ... QK_MACRO_MAX: case QK_MACRO ... QK_MACRO_MAX:
action.code = ACTION_MACRO(keycode & 0xFF); action.code = ACTION_MACRO(keycode & 0xFF);

@ -17,39 +17,55 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#if defined(__AVR__)
#include <avr/io.h> #include <avr/io.h>
#endif
#include "wait.h" #include "wait.h"
#include "print.h" #include "print.h"
#include "debug.h" #include "debug.h"
#include "util.h" #include "util.h"
#include "matrix.h" #include "matrix.h"
#ifdef MATRIX_HAS_GHOST /* Set 0 if debouncing isn't needed */
# error "The universal matrix.c file cannot be used for this keyboard." /*
#endif * This constant define not debouncing time in msecs, but amount of matrix
* scan loops which should be made to get stable debounced results.
*
* On Ergodox matrix scan rate is relatively low, because of slow I2C.
* Now it's only 317 scans/second, or about 3.15 msec/scan.
* According to Cherry specs, debouncing time is 5 msec.
*
* And so, there is no sense to have DEBOUNCE higher than 2.
*/
#ifndef DEBOUNCING_DELAY #ifndef DEBOUNCING_DELAY
# define DEBOUNCING_DELAY 5 # define DEBOUNCING_DELAY 5
#endif #endif
static uint8_t debouncing = DEBOUNCING_DELAY;
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; static const uint8_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
/* matrix state */
#if DIODE_DIRECTION == COL2ROW /* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS]; static matrix_row_t matrix[MATRIX_ROWS];
#else static matrix_row_t matrix_debouncing[MATRIX_ROWS];
static matrix_col_t matrix[MATRIX_COLS];
#if DIODE_DIRECTION == ROW2COL
static matrix_row_t matrix_reversed[MATRIX_COLS];
static matrix_row_t matrix_reversed_debouncing[MATRIX_COLS];
#endif #endif
static int8_t debouncing_delay = -1;
#if DIODE_DIRECTION == COL2ROW #if MATRIX_COLS > 16
static void toggle_row(uint8_t row); #define SHIFTER 1UL
static matrix_row_t read_cols(void);
#else #else
static void toggle_col(uint8_t col); #define SHIFTER 1
static matrix_col_t read_rows(void);
#endif #endif
static matrix_row_t read_cols(void);
static void init_cols(void);
static void unselect_rows(void);
static void select_row(uint8_t row);
__attribute__ ((weak)) __attribute__ ((weak))
void matrix_init_quantum(void) { void matrix_init_quantum(void) {
matrix_init_kb(); matrix_init_kb();
@ -78,10 +94,12 @@ __attribute__ ((weak))
void matrix_scan_user(void) { void matrix_scan_user(void) {
} }
inline
uint8_t matrix_rows(void) { uint8_t matrix_rows(void) {
return MATRIX_ROWS; return MATRIX_ROWS;
} }
inline
uint8_t matrix_cols(void) { uint8_t matrix_cols(void) {
return MATRIX_COLS; return MATRIX_COLS;
} }
@ -111,161 +129,179 @@ uint8_t matrix_cols(void) {
// } // }
void matrix_init(void) { void matrix_init(void) {
/* frees PORTF by setting the JTD bit twice within four cycles */ // To use PORTF disable JTAG with writing JTD bit twice within four cycles.
#ifdef __AVR_ATmega32U4__ #ifdef __AVR_ATmega32U4__
MCUCR |= _BV(JTD); MCUCR |= _BV(JTD);
MCUCR |= _BV(JTD); MCUCR |= _BV(JTD);
#endif #endif
/* initializes the I/O pins */
#if DIODE_DIRECTION == COL2ROW // initialize row and col
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { unselect_rows();
/* DDRxn */ init_cols();
_SFR_IO8((row_pins[r] >> 4) + 1) |= _BV(row_pins[r] & 0xF);
toggle_row(r); // initialize matrix state: all keys off
} for (uint8_t i=0; i < MATRIX_ROWS; i++) {
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { matrix[i] = 0;
/* PORTxn */ matrix_debouncing[i] = 0;
_SFR_IO8((col_pins[c] >> 4) + 2) |= _BV(col_pins[c] & 0xF);
}
#else
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
/* DDRxn */
_SFR_IO8((col_pins[c] >> 4) + 1) |= _BV(col_pins[c] & 0xF);
toggle_col(c);
}
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
/* PORTxn */
_SFR_IO8((row_pins[r] >> 4) + 2) |= _BV(row_pins[r] & 0xF);
} }
#endif
matrix_init_quantum(); matrix_init_quantum();
} }
uint8_t matrix_scan(void)
{
#if DIODE_DIRECTION == COL2ROW #if DIODE_DIRECTION == COL2ROW
uint8_t matrix_scan(void) { for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
static matrix_row_t debouncing_matrix[MATRIX_ROWS]; select_row(i);
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { wait_us(30); // without this wait read unstable value.
toggle_row(r); matrix_row_t cols = read_cols();
matrix_row_t state = read_cols(); if (matrix_debouncing[i] != cols) {
if (debouncing_matrix[r] != state) { matrix_debouncing[i] = cols;
debouncing_matrix[r] = state; if (debouncing) {
debouncing_delay = DEBOUNCING_DELAY; debug("bounce!: "); debug_hex(debouncing); debug("\n");
}
toggle_row(r);
}
if (debouncing_delay >= 0) {
dprintf("Debouncing delay remaining: %X\n", debouncing_delay);
--debouncing_delay;
if (debouncing_delay >= 0) {
wait_ms(1);
}
else {
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) {
matrix[r] = debouncing_matrix[r];
} }
debouncing = DEBOUNCING_DELAY;
} }
unselect_rows();
} }
matrix_scan_quantum();
return 1;
}
static void toggle_row(uint8_t row) {
/* PINxn */
_SFR_IO8((row_pins[row] >> 4)) = _BV(row_pins[row] & 0xF);
}
static matrix_row_t read_cols(void) { if (debouncing) {
matrix_row_t state = 0; if (--debouncing) {
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { wait_us(1);
/* PINxn */ } else {
if (!(_SFR_IO8((col_pins[c] >> 4)) & _BV(col_pins[c] & 0xF))) { for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
state |= (matrix_row_t)1 << c; matrix[i] = matrix_debouncing[i];
}
} }
} }
return state;
}
matrix_row_t matrix_get_row(uint8_t row) {
return matrix[row];
}
#else #else
uint8_t matrix_scan(void) { for (uint8_t i = 0; i < MATRIX_COLS; i++) {
static matrix_col_t debouncing_matrix[MATRIX_COLS]; select_row(i);
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { wait_us(30); // without this wait read unstable value.
toggle_col(c); matrix_row_t rows = read_cols();
matrix_col_t state = read_rows(); if (matrix_reversed_debouncing[i] != rows) {
if (debouncing_matrix[c] != state) { matrix_reversed_debouncing[i] = rows;
debouncing_matrix[c] = state; if (debouncing) {
debouncing_delay = DEBOUNCING_DELAY; debug("bounce!: "); debug_hex(debouncing); debug("\n");
}
debouncing = DEBOUNCING_DELAY;
} }
toggle_col(c); unselect_rows();
} }
if (debouncing_delay >= 0) {
dprintf("Debouncing delay remaining: %X\n", debouncing_delay); if (debouncing) {
--debouncing_delay; if (--debouncing) {
if (debouncing_delay >= 0) { wait_us(1);
wait_ms(1); } else {
} for (uint8_t i = 0; i < MATRIX_COLS; i++) {
else { matrix_reversed[i] = matrix_reversed_debouncing[i];
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) {
matrix[c] = debouncing_matrix[c];
} }
} }
} }
for (uint8_t y = 0; y < MATRIX_ROWS; y++) {
matrix_row_t row = 0;
for (uint8_t x = 0; x < MATRIX_COLS; x++) {
row |= ((matrix_reversed[x] & (1<<y)) >> y) << x;
}
matrix[y] = row;
}
#endif
matrix_scan_quantum(); matrix_scan_quantum();
return 1; return 1;
} }
static void toggle_col(uint8_t col) { bool matrix_is_modified(void)
/* PINxn */ {
_SFR_IO8((col_pins[col] >> 4)) = _BV(col_pins[col] & 0xF); if (debouncing) return false;
return true;
} }
static matrix_col_t read_rows(void) { inline
matrix_col_t state = 0; bool matrix_is_on(uint8_t row, uint8_t col)
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { {
/* PINxn */ return (matrix[row] & ((matrix_row_t)1<col));
if (!(_SFR_IO8((row_pins[r] >> 4)) & _BV(row_pins[r] & 0xF))) { }
state |= (matrix_col_t)1 << r;
} inline
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_print(void)
{
print("\nr/c 0123456789ABCDEF\n");
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
phex(row); print(": ");
pbin_reverse16(matrix_get_row(row));
print("\n");
} }
return state;
} }
matrix_row_t matrix_get_row(uint8_t row) { uint8_t matrix_key_count(void)
matrix_row_t state = 0; {
matrix_col_t mask = (matrix_col_t)1 << row; uint8_t count = 0;
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
if (matrix[c] & mask) { count += bitpop16(matrix[i]);
state |= (matrix_row_t)1 << c;
}
} }
return state; return count;
} }
static void init_cols(void)
{
#if DIODE_DIRECTION == COL2ROW
for(int x = 0; x < MATRIX_COLS; x++) {
int pin = col_pins[x];
#else
for(int x = 0; x < MATRIX_ROWS; x++) {
int pin = row_pins[x];
#endif #endif
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF);
bool matrix_is_modified(void) { _SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF);
if (debouncing_delay >= 0) return false; }
return true;
} }
bool matrix_is_on(uint8_t row, uint8_t col) { static matrix_row_t read_cols(void)
return matrix_get_row(row) & (matrix_row_t)1 << col; {
} matrix_row_t result = 0;
void matrix_print(void) { #if DIODE_DIRECTION == COL2ROW
dprintln("Human-readable matrix state:"); for(int x = 0; x < MATRIX_COLS; x++) {
for (uint8_t r = 0; r < MATRIX_ROWS; r++) { int pin = col_pins[x];
dprintf("State of row %X: %016b\n", r, bitrev16(matrix_get_row(r))); #else
for(int x = 0; x < MATRIX_ROWS; x++) {
int pin = row_pins[x];
#endif
result |= (_SFR_IO8(pin >> 4) & _BV(pin & 0xF)) ? 0 : (SHIFTER << x);
} }
return result;
} }
uint8_t matrix_key_count(void) { static void unselect_rows(void)
uint8_t count = 0; {
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { #if DIODE_DIRECTION == COL2ROW
count += bitpop16(matrix_get_row(r)); for(int x = 0; x < MATRIX_ROWS; x++) {
int pin = row_pins[x];
#else
for(int x = 0; x < MATRIX_COLS; x++) {
int pin = col_pins[x];
#endif
_SFR_IO8((pin >> 4) + 1) &= ~_BV(pin & 0xF);
_SFR_IO8((pin >> 4) + 2) |= _BV(pin & 0xF);
} }
return count; }
static void select_row(uint8_t row)
{
#if DIODE_DIRECTION == COL2ROW
int pin = row_pins[row];
#else
int pin = col_pins[row];
#endif
_SFR_IO8((pin >> 4) + 1) |= _BV(pin & 0xF);
_SFR_IO8((pin >> 4) + 2) &= ~_BV(pin & 0xF);
} }

@ -88,7 +88,7 @@ bool process_record_quantum(keyrecord_t *record) {
stop_all_notes(); stop_all_notes();
shutdown_user(); shutdown_user();
#endif #endif
_delay_ms(250); wait_ms(250);
#ifdef ATREUS_ASTAR #ifdef ATREUS_ASTAR
*(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific *(uint16_t *)0x0800 = 0x7777; // these two are a-star-specific
#endif #endif

@ -1,7 +1,12 @@
#ifndef QUANTUM_H #ifndef QUANTUM_H
#define QUANTUM_H #define QUANTUM_H
#if defined(__AVR__)
#include <avr/pgmspace.h> #include <avr/pgmspace.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#endif
#include "wait.h"
#include "matrix.h" #include "matrix.h"
#include "keymap.h" #include "keymap.h"
#ifdef BACKLIGHT_ENABLE #ifdef BACKLIGHT_ENABLE
@ -14,12 +19,9 @@
#include "action_layer.h" #include "action_layer.h"
#include "eeconfig.h" #include "eeconfig.h"
#include <stddef.h> #include <stddef.h>
#include <avr/io.h>
#include <util/delay.h>
#include "bootloader.h" #include "bootloader.h"
#include "timer.h" #include "timer.h"
#include "config_common.h" #include "config_common.h"
#include <avr/interrupt.h>
#include "led.h" #include "led.h"
#include "action_util.h" #include "action_util.h"
#include <stdlib.h> #include <stdlib.h>

@ -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 :) 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). 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 <https://github.com/flabbergast/tmk_keyboard/tree/chibios> (@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). 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).

@ -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

@ -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

@ -1,4 +1,10 @@
COMMON_DIR = common 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 \ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/keyboard.c \ $(COMMON_DIR)/keyboard.c \
$(COMMON_DIR)/action.c \ $(COMMON_DIR)/action.c \
@ -9,21 +15,29 @@ SRC += $(COMMON_DIR)/host.c \
$(COMMON_DIR)/print.c \ $(COMMON_DIR)/print.c \
$(COMMON_DIR)/debug.c \ $(COMMON_DIR)/debug.c \
$(COMMON_DIR)/util.c \ $(COMMON_DIR)/util.c \
$(COMMON_DIR)/avr/suspend.c \ $(COMMON_DIR)/eeconfig.c \
$(COMMON_DIR)/avr/xprintf.S \ $(PLATFORM_COMMON_DIR)/suspend.c \
$(COMMON_DIR)/avr/timer.c \ $(PLATFORM_COMMON_DIR)/timer.c \
$(COMMON_DIR)/avr/bootloader.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 # Option modules
ifeq ($(strip $(BOOTMAGIC_ENABLE)), yes) ifeq ($(strip $(BOOTMAGIC_ENABLE)), yes)
OPT_DEFS += -DBOOTMAGIC_ENABLE OPT_DEFS += -DBOOTMAGIC_ENABLE
SRC += $(COMMON_DIR)/bootmagic.c SRC += $(COMMON_DIR)/bootmagic.c
SRC += $(COMMON_DIR)/avr/eeconfig.c
else else
OPT_DEFS += -DMAGIC_ENABLE OPT_DEFS += -DMAGIC_ENABLE
SRC += $(COMMON_DIR)/magic.c SRC += $(COMMON_DIR)/magic.c
SRC += $(COMMON_DIR)/avr/eeconfig.c
endif endif
ifeq ($(strip $(MOUSEKEY_ENABLE)), yes) ifeq ($(strip $(MOUSEKEY_ENABLE)), yes)
@ -57,14 +71,13 @@ ifeq ($(strip $(USB_6KRO_ENABLE)), yes)
endif endif
ifeq ($(strip $(SLEEP_LED_ENABLE)), yes) 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 += -DSLEEP_LED_ENABLE
OPT_DEFS += -DNO_SUSPEND_POWER_DOWN OPT_DEFS += -DNO_SUSPEND_POWER_DOWN
endif endif
ifeq ($(strip $(BACKLIGHT_ENABLE)), yes) ifeq ($(strip $(BACKLIGHT_ENABLE)), yes)
SRC += $(COMMON_DIR)/backlight.c SRC += $(COMMON_DIR)/backlight.c
SRC += $(COMMON_DIR)/avr/eeconfig.c
OPT_DEFS += -DBACKLIGHT_ENABLE OPT_DEFS += -DBACKLIGHT_ENABLE
endif endif
@ -87,6 +100,13 @@ endif
# Version string # Version string
OPT_DEFS += -DVERSION=$(shell (git describe --always --dirty || echo 'unknown') 2> /dev/null) 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 # Search Path
VPATH += $(TMK_PATH)/$(COMMON_DIR) VPATH += $(TMK_PATH)/$(COMMON_DIR)
ifeq ($(PLATFORM),CHIBIOS)
VPATH += $(TMK_PATH)/$(COMMON_DIR)/chibios
endif

@ -257,7 +257,7 @@ bool process_tapping(keyrecord_t *keyp)
return true; return true;
} }
} else { } 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); process_record(keyp);
return true; return true;
} }

@ -114,8 +114,10 @@ bool suspend_wakeup_condition(void)
matrix_power_up(); matrix_power_up();
matrix_scan(); matrix_scan();
matrix_power_down(); matrix_power_down();
if (matrix_key_count()) return true; for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
return false; if (matrix_get_row(r)) return true;
}
return false;
} }
// run immediately after wakeup // run immediately after wakeup

@ -1,6 +1,6 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <util/delay.h> #include "wait.h"
#include "matrix.h" #include "matrix.h"
#include "bootloader.h" #include "bootloader.h"
#include "debug.h" #include "debug.h"
@ -10,6 +10,7 @@
#include "eeconfig.h" #include "eeconfig.h"
#include "bootmagic.h" #include "bootmagic.h"
keymap_config_t keymap_config;
void bootmagic(void) void bootmagic(void)
{ {
@ -19,9 +20,9 @@ void bootmagic(void)
} }
/* do scans in case of bounce */ /* do scans in case of bounce */
print("boogmagic scan: ... "); print("bootmagic scan: ... ");
uint8_t scan = 100; uint8_t scan = 100;
while (scan--) { matrix_scan(); _delay_ms(10); } while (scan--) { matrix_scan(); wait_ms(10); }
print("done.\n"); print("done.\n");
/* bootmagic skip */ /* bootmagic skip */
@ -105,13 +106,15 @@ void bootmagic(void)
} }
} }
static bool scan_keycode(uint8_t keycode) { static bool scan_keycode(uint8_t keycode)
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { {
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
matrix_row_t matrix_row = matrix_get_row(r); matrix_row_t matrix_row = matrix_get_row(r);
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { for (uint8_t c = 0; c < MATRIX_COLS; c++) {
if (matrix_row & (matrix_row_t)1 << c) { if (matrix_row & ((matrix_row_t)1<<c)) {
keypos_t key = (keypos_t){ .row = r, .col = c }; if (keycode == keymap_key_to_keycode(0, (keypos_t){ .row = r, .col = c })) {
if (keycode == keymap_key_to_keycode(0, key)) return true; return true;
}
} }
} }
} }
@ -123,4 +126,4 @@ bool bootmagic_scan_keycode(uint8_t keycode)
if (!scan_keycode(BOOTMAGIC_KEY_SALT)) return false; if (!scan_keycode(BOOTMAGIC_KEY_SALT)) return false;
return scan_keycode(keycode); return scan_keycode(keycode);
} }

@ -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

@ -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 <do_flash_cmd>:
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 <do_flash_cmd+0x6>
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 <do_flash_cmd>:
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 <do_flash_cmd+0x4>
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++);
}
}

@ -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);
}

@ -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 <stdarg.h>
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

@ -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<<USB_LED_CAPS_LOCK);
}
// LED off
if (timer.pwm.count == breathing_table[timer.pwm.index]) {
led_set(0);
}
/* Reset the counter */
RESET_COUNTER;
OSAL_IRQ_EPILOGUE();
}
#endif /* common parts for known platforms */
#if defined(KL2x) || defined(K20x) /* platform selection: familiar Kinetis chips */
/* LPTMR clock options */
#define LPTMR_CLOCK_MCGIRCLK 0 /* 4MHz clock */
#define LPTMR_CLOCK_LPO 1 /* 1kHz clock */
#define LPTMR_CLOCK_ERCLK32K 2 /* external 32kHz crystal */
#define LPTMR_CLOCK_OSCERCLK 3 /* output from OSC */
/* Work around inconsistencies in Freescale naming */
#if !defined(SIM_SCGC5_LPTMR)
#define SIM_SCGC5_LPTMR SIM_SCGC5_LPTIMER
#endif
/* Initialise the timer */
void sleep_led_init(void) {
/* Make sure the clock to the LPTMR is enabled */
SIM->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<<USB_LED_CAPS_LOCK);
}
void sleep_led_disable(void) {
led_set(0);
}
void sleep_led_toggle(void) {
// not implemented
}
#endif /* platform selection */

@ -0,0 +1,65 @@
/* TODO */
#include "ch.h"
#include "hal.h"
#include "matrix.h"
#include "action.h"
#include "action_util.h"
#include "mousekey.h"
#include "host.h"
#include "backlight.h"
#include "suspend.h"
void suspend_idle(uint8_t time) {
// TODO: this is not used anywhere - what units is 'time' in?
chThdSleepMilliseconds(time);
}
void suspend_power_down(void) {
// TODO: figure out what to power down and how
// shouldn't power down TPM/FTM if we want a breathing LED
// also shouldn't power down USB
// on AVR, this enables the watchdog for 15ms (max), and goes to
// SLEEP_MODE_PWR_DOWN
chThdSleepMilliseconds(17);
}
__attribute__ ((weak)) void matrix_power_up(void) {}
__attribute__ ((weak)) void matrix_power_down(void) {}
bool suspend_wakeup_condition(void)
{
matrix_power_up();
matrix_scan();
matrix_power_down();
for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
if (matrix_get_row(r)) return true;
}
return false;
}
// run immediately after wakeup
void suspend_wakeup_init(void)
{
// clear keyboard state
// need to do it manually, because we're running from ISR
// and clear_keyboard() calls print
// so only clear the variables in memory
// the reports will be sent from main.c afterwards
// or if the PC asks for GET_REPORT
clear_mods();
clear_weak_mods();
clear_keys();
#ifdef MOUSEKEY_ENABLE
mousekey_clear();
#endif /* MOUSEKEY_ENABLE */
#ifdef EXTRAKEY_ENABLE
host_system_send(0);
host_consumer_send(0);
#endif /* EXTRAKEY_ENABLE */
#ifdef BACKLIGHT_ENABLE
backlight_init();
#endif /* BACKLIGHT_ENABLE */
}

@ -0,0 +1,27 @@
#include "ch.h"
#include "timer.h"
void timer_init(void) {}
void timer_clear(void) {}
uint16_t timer_read(void)
{
return (uint16_t)ST2MS(chVTGetSystemTime());
}
uint32_t timer_read32(void)
{
return ST2MS(chVTGetSystemTime());
}
uint16_t timer_elapsed(uint16_t last)
{
return (uint16_t)(ST2MS(chVTTimeElapsedSinceX(MS2ST(last))));
}
uint32_t timer_elapsed32(uint32_t last)
{
return ST2MS(chVTTimeElapsedSinceX(MS2ST(last)));
}

@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <util/delay.h> #include "wait.h"
#include "keycode.h" #include "keycode.h"
#include "host.h" #include "host.h"
#include "keymap.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) __attribute__ ((weak));
bool command_extra(uint8_t code) bool command_extra(uint8_t code)
{ {
(void)code;
return false; return false;
} }
bool command_console_extra(uint8_t code) __attribute__ ((weak)); bool command_console_extra(uint8_t code) __attribute__ ((weak));
bool command_console_extra(uint8_t code) bool command_console_extra(uint8_t code)
{ {
(void)code;
return false; return false;
} }
@ -217,8 +219,11 @@ static void print_version(void)
" " STR(BOOTLOADER_SIZE) "\n"); " " STR(BOOTLOADER_SIZE) "\n");
print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__) print("GCC: " STR(__GNUC__) "." STR(__GNUC_MINOR__) "." STR(__GNUC_PATCHLEVEL__)
#if defined(__AVR__)
" AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__
" AVR_ARCH: avr" STR(__AVR_ARCH__) "\n"); " AVR_ARCH: avr" STR(__AVR_ARCH__)
#endif
"\n");
return; return;
} }
@ -234,7 +239,7 @@ static void print_status(void)
#ifdef NKRO_ENABLE #ifdef NKRO_ENABLE
print_val_hex8(keyboard_nkro); print_val_hex8(keyboard_nkro);
#endif #endif
print_val_hex32(timer_count); print_val_hex32(timer_read32());
#ifdef PROTOCOL_PJRC #ifdef PROTOCOL_PJRC
print_val_hex8(UDCON); print_val_hex8(UDCON);
@ -360,7 +365,7 @@ static bool command_common(uint8_t code)
stop_all_notes(); stop_all_notes();
shutdown_user(); shutdown_user();
#else #else
_delay_ms(1000); wait_ms(1000);
#endif #endif
bootloader_jump(); // not return bootloader_jump(); // not return
break; break;
@ -430,10 +435,11 @@ static bool command_common(uint8_t code)
case MAGIC_KC(MAGIC_KEY_NKRO): case MAGIC_KC(MAGIC_KEY_NKRO):
clear_keyboard(); // clear to prevent stuck keys clear_keyboard(); // clear to prevent stuck keys
keyboard_nkro = !keyboard_nkro; keyboard_nkro = !keyboard_nkro;
if (keyboard_nkro) if (keyboard_nkro) {
print("NKRO: on\n"); print("NKRO: on\n");
else } else {
print("NKRO: off\n"); print("NKRO: off\n");
}
break; break;
#endif #endif
@ -750,10 +756,11 @@ static bool mousekey_console(uint8_t code)
print("?"); print("?");
return false; return false;
} }
if (mousekey_param) if (mousekey_param) {
xprintf("M%d> ", mousekey_param); xprintf("M%d> ", mousekey_param);
else } else {
print("M>" ); print("M>" );
}
return true; return true;
} }
#endif #endif

@ -1,6 +1,6 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <avr/eeprom.h> #include "eeprom.h"
#include "eeconfig.h" #include "eeconfig.h"
void eeconfig_init(void) void eeconfig_init(void)

@ -0,0 +1,22 @@
#ifndef TMK_CORE_COMMON_EEPROM_H_
#define TMK_CORE_COMMON_EEPROM_H_
#if defined(__AVR__)
#include <avr/eeprom.h>
#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_ */

@ -51,17 +51,20 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#endif #endif
#ifdef MATRIX_HAS_GHOST #ifdef MATRIX_HAS_GHOST
static bool is_row_ghosting(uint8_t row){ static bool has_ghost_in_row(uint8_t row)
matrix_row_t state = matrix_get_row(row); {
/* no ghosting happens when only one key in the row is pressed */ matrix_row_t matrix_row = matrix_get_row(row);
if (!(state - 1 & state)) return false; // No ghost exists when less than 2 keys are down on the row
/* ghosting occurs when two keys in the same column are pressed */ if (((matrix_row - 1) & matrix_row) == 0)
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { return false;
if (r != row && matrix_get_row(r) & state) return true;
// Ghost occurs when the row shares column line with other row
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
if (i != row && (matrix_get_row(i) & matrix_row))
return true;
} }
return false; return false;
} }
#endif #endif
__attribute__ ((weak)) __attribute__ ((weak))
@ -100,72 +103,86 @@ void keyboard_init(void) {
#endif #endif
} }
/* does routine keyboard jobs */ /*
void keyboard_task(void) { * Do keyboard routine jobs: scan mantrix, light LEDs, ...
static uint8_t led_status; * This is repeatedly called as fast as possible.
*/
void keyboard_task(void)
{
static matrix_row_t matrix_prev[MATRIX_ROWS];
#ifdef MATRIX_HAS_GHOST
static matrix_row_t matrix_ghost[MATRIX_ROWS];
#endif
static uint8_t led_status = 0;
matrix_row_t matrix_row = 0;
matrix_row_t matrix_change = 0;
matrix_scan(); matrix_scan();
for (int8_t r = MATRIX_ROWS - 1; r >= 0; --r) { for (uint8_t r = 0; r < MATRIX_ROWS; r++) {
static matrix_row_t previous_matrix[MATRIX_ROWS]; matrix_row = matrix_get_row(r);
matrix_row_t state = matrix_get_row(r); matrix_change = matrix_row ^ matrix_prev[r];
matrix_row_t changes = state ^ previous_matrix[r]; if (matrix_change) {
if (changes) {
#ifdef MATRIX_HAS_GHOST #ifdef MATRIX_HAS_GHOST
static matrix_row_t deghosting_matrix[MATRIX_ROWS]; if (has_ghost_in_row(r)) {
if (is_row_ghosting(r)) { /* Keep track of whether ghosted status has changed for
/* debugs the deghosting mechanism */ * debugging. But don't update matrix_prev until un-ghosted, or
/* doesn't update previous_matrix until the ghosting has stopped * the last key would be lost.
* in order to prevent the last key from being lost
*/ */
if (debug_matrix && deghosting_matrix[r] != state) { if (debug_matrix && matrix_ghost[r] != matrix_row) {
matrix_print(); matrix_print();
} }
deghosting_matrix[r] = state; matrix_ghost[r] = matrix_row;
continue; continue;
} }
deghosting_matrix[r] = state; matrix_ghost[r] = matrix_row;
#endif #endif
if (debug_matrix) matrix_print(); if (debug_matrix) matrix_print();
for (int8_t c = MATRIX_COLS - 1; c >= 0; --c) { for (uint8_t c = 0; c < MATRIX_COLS; c++) {
matrix_row_t mask = (matrix_row_t)1 << c; if (matrix_change & ((matrix_row_t)1<<c)) {
if (changes & mask) { action_exec((keyevent_t){
keyevent_t event; .key = (keypos_t){ .row = r, .col = c },
event.key = (keypos_t){ .row = r, .col = c }; .pressed = (matrix_row & ((matrix_row_t)1<<c)),
event.pressed = state & mask; .time = (timer_read() | 1) /* time should not be 0 */
/* the time should not be 0 */ });
event.time = timer_read() | 1; // record a processed key
action_exec(event); matrix_prev[r] ^= ((matrix_row_t)1<<c);
/* records the processed key event */ // process a key per task call
previous_matrix[r] ^= mask; goto MATRIX_LOOP_END;
/* processes one key event per call */
goto event_processed;
} }
} }
} }
} }
/* sends tick events when the keyboard is idle */ // call with pseudo tick event when no real key event.
action_exec(TICK); action_exec(TICK);
event_processed:
MATRIX_LOOP_END:
#ifdef MOUSEKEY_ENABLE #ifdef MOUSEKEY_ENABLE
/* repeats and accelerates the mouse keys */ // mousekey repeat & acceleration
mousekey_task(); mousekey_task();
#endif #endif
#ifdef PS2_MOUSE_ENABLE #ifdef PS2_MOUSE_ENABLE
ps2_mouse_task(); ps2_mouse_task();
#endif #endif
#ifdef SERIAL_MOUSE_ENABLE #ifdef SERIAL_MOUSE_ENABLE
serial_mouse_task(); serial_mouse_task();
#endif #endif
#ifdef ADB_MOUSE_ENABLE #ifdef ADB_MOUSE_ENABLE
adb_mouse_task(); adb_mouse_task();
#endif #endif
/* updates the LEDs */
// update LED
if (led_status != host_keyboard_leds()) { if (led_status != host_keyboard_leds()) {
led_status = host_keyboard_leds(); led_status = host_keyboard_leds();
keyboard_set_leds(led_status); keyboard_set_leds(led_status);
} }
} }
void keyboard_set_leds(uint8_t leds) { void keyboard_set_leds(uint8_t leds)
if (debug_keyboard) dprintf("Keyboard LEDs state: %x\n", leds); {
if (debug_keyboard) { debug("keyboard_set_led: "); debug_hex8(leds); debug("\n"); }
led_set(leds); led_set(leds);
} }

@ -1,6 +1,8 @@
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#if defined(__AVR__)
#include <util/delay.h> #include <util/delay.h>
#endif
#include "matrix.h" #include "matrix.h"
#include "bootloader.h" #include "bootloader.h"
#include "debug.h" #include "debug.h"
@ -33,4 +35,4 @@ void magic(void)
default_layer = eeconfig_read_default_layer(); default_layer = eeconfig_read_default_layer();
default_layer_set((uint32_t)default_layer); default_layer_set((uint32_t)default_layer);
} }

@ -20,59 +20,48 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#if MATRIX_COLS <= 8
typedef uint8_t matrix_row_t; #if (MATRIX_COLS <= 8)
#elif MATRIX_COLS <= 16 typedef uint8_t matrix_row_t;
typedef uint16_t matrix_row_t; #elif (MATRIX_COLS <= 16)
#elif MATRIX_COLS <= 32 typedef uint16_t matrix_row_t;
typedef uint32_t matrix_row_t; #elif (MATRIX_COLS <= 32)
typedef uint32_t matrix_row_t;
#else #else
# error "There are too many columns." #error "MATRIX_COLS: invalid value"
#endif #endif
#if DIODE_DIRECTION == ROW2COL #define MATRIX_IS_ON(row, col) (matrix_get_row(row) && (1<<col))
# if MATRIX_ROWS <= 8
typedef uint8_t matrix_col_t;
# elif MATRIX_ROWS <= 16
typedef uint16_t matrix_col_t;
# elif MATRIX_ROWS <= 32
typedef uint32_t matrix_col_t;
# else
# error "There are too many rows."
# endif
#endif
typedef struct {
uint8_t input_addr:4;
uint8_t bit:4;
} io_pin_t;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* counts the number of rows in the matrix */
/* number of matrix rows */
uint8_t matrix_rows(void); uint8_t matrix_rows(void);
/* counts the number of columns in the matrix */ /* number of matrix columns */
uint8_t matrix_cols(void); uint8_t matrix_cols(void);
/* sets up the matrix before matrix_init */ /* should be called at early stage of startup before matrix_init.(optional) */
void matrix_setup(void); void matrix_setup(void);
/* intializes the matrix */ /* intialize matrix for scaning. */
void matrix_init(void); void matrix_init(void);
/* scans the entire matrix */ /* scan all key states on matrix */
uint8_t matrix_scan(void); uint8_t matrix_scan(void);
/* checks if the matrix has been modified */ /* whether modified from previous scan. used after matrix_scan. */
bool matrix_is_modified(void) __attribute__ ((deprecated)); bool matrix_is_modified(void) __attribute__ ((deprecated));
/* checks if a key is pressed */ /* whether a swtich is on */
bool matrix_is_on(uint8_t row, uint8_t col); bool matrix_is_on(uint8_t row, uint8_t col);
/* inspects the state of a row in the matrix */ /* matrix state on row */
matrix_row_t matrix_get_row(uint8_t row); matrix_row_t matrix_get_row(uint8_t row);
/* prints the matrix for debugging */ /* print matrix for debug */
void matrix_print(void); void matrix_print(void);
/* counts the total number of keys pressed */
uint8_t matrix_key_count(void);
/* controls power to the matrix */ /* power control */
void matrix_power_up(void); void matrix_power_up(void);
void matrix_power_down(void); void matrix_power_down(void);
/* executes code for Quantum */ /* executes code for Quantum */
void matrix_init_quantum(void); void matrix_init_quantum(void);
void matrix_scan_quantum(void); void matrix_scan_quantum(void);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save