[Keyboard] Modernize KMAC (#6131)

* [Keyboard] Modernize the KMAC implementation

This brings the matrix implementation more in line with the current
default matrix code.
It also simplifies the implementation quite a bit.

* [Keyboard] Add layout support to KMAC
This commit is contained in:
Mathias Andersson 2019-06-26 09:32:03 +02:00 committed by Drashna Jaelre
parent 8fd3f42281
commit 3483c51f62
19 changed files with 573 additions and 624 deletions

View File

@ -15,17 +15,16 @@ You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef CONFIG_H #pragma once
#define CONFIG_H
#include "config_common.h" #include "config_common.h"
/* USB Device descriptor parameter */ /* USB Device descriptor parameter */
#define VENDOR_ID 0xFEED #define VENDOR_ID 0xFEED
#define PRODUCT_ID 0x6050 #define PRODUCT_ID 0x6050
#define DEVICE_VER 0x0104 #define DEVICE_VER 0x0104
#define MANUFACTURER KBDMania #define MANUFACTURER KBDMania
#define PRODUCT KMAC #define PRODUCT KMAC
#define DESCRIPTION QMK keyboard firmware for KMAC #define DESCRIPTION QMK keyboard firmware for KMAC
/* key matrix size */ /* key matrix size */
@ -36,9 +35,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* Keyboard Matrix Assignments * Keyboard Matrix Assignments
* The KMAC uses demultiplexers for the cols, they are only included here as documentation. * The KMAC uses demultiplexers for the cols, they are only included here as documentation.
* See matrix.c for more details. * See matrix.c for more details.
*/ */
#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5, B7 } #define MATRIX_ROW_PINS \
#define MATRIX_COL_PINS { C6, B6, F0, F1, C7, B5 } { D0, D1, D2, D3, D5, B7 }
#define MATRIX_COL_PINS \
{ B6, C6, C7, F1, F0, B5 }
#define UNUSED_PINS #define UNUSED_PINS
/* COL2ROW, ROW2COL*/ /* COL2ROW, ROW2COL*/
@ -169,5 +170,3 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
/* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */ /* override number of MIDI tone keycodes (each octave adds 12 keycodes and allocates 12 bytes) */
//#define MIDI_TONE_KEYCODE_OCTAVES 1 //#define MIDI_TONE_KEYCODE_OCTAVES 1
#endif

View File

@ -6,7 +6,8 @@
"width": 18.25, "width": 18.25,
"height": 6.5, "height": 6.5,
"layouts": { "layouts": {
"LAYOUT": { "LAYOUT_tkl_ansi": {
"key_count": 87,
"layout": [ "layout": [
{ "label": "Esc", "x": 0, "y": 0 }, { "label": "Esc", "x": 0, "y": 0 },
{ "label": "F1", "x": 2, "y": 0 }, { "label": "F1", "x": 2, "y": 0 },
@ -97,8 +98,8 @@
{ "label": "\u2192", "x": 17.25, "y": 5.5 } { "label": "\u2192", "x": 17.25, "y": 5.5 }
] ]
}, },
"LAYOUT_tkl_ansi_wkl": {
"LAYOUT_WKL": { "key_count": 84,
"layout": [ "layout": [
{ "label": "Esc", "x": 0, "y": 0 }, { "label": "Esc", "x": 0, "y": 0 },
{ "label": "F1", "x": 2, "y": 0 }, { "label": "F1", "x": 2, "y": 0 },
@ -177,11 +178,9 @@
{ "label": "Shift", "x": 12.25, "y": 4.5, "w": 2.75 }, { "label": "Shift", "x": 12.25, "y": 4.5, "w": 2.75 },
{ "label": "\u2191", "x": 16.25, "y": 4.5 }, { "label": "\u2191", "x": 16.25, "y": 4.5 },
{ "label": "Ctrl", "x": 0, "y": 5.5, "w": 1.5 }, { "label": "Ctrl", "x": 0, "y": 5.5, "w": 1.5 },
{ "label": "Win", "x": 1.5, "y": 5.5 },
{ "label": "Alt", "x": 2.5, "y": 5.5, "w": 1.5 }, { "label": "Alt", "x": 2.5, "y": 5.5, "w": 1.5 },
{ "x": 4, "y": 5.5, "w": 7 }, { "x": 4, "y": 5.5, "w": 7 },
{ "label": "Alt", "x": 11, "y": 5.5, "w": 1.5 }, { "label": "Alt", "x": 11, "y": 5.5, "w": 1.5 },
{ "label": "Win", "x": 12.5, "y": 5.5 },
{ "label": "Ctrl", "x": 13.5, "y": 5.5, "w": 1.5 }, { "label": "Ctrl", "x": 13.5, "y": 5.5, "w": 1.5 },
{ "label": "\u2190", "x": 15.25, "y": 5.5 }, { "label": "\u2190", "x": 15.25, "y": 5.5 },
{ "label": "\u2193", "x": 16.25, "y": 5.5 }, { "label": "\u2193", "x": 16.25, "y": 5.5 },

View File

@ -1,4 +1,4 @@
/* Copyright 2017 Mathias Andersson <wraul@dbox.se> /* Copyright 2019 Mathias Andersson <wraul@dbox.se>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@ -1,4 +1,4 @@
/* Copyright 2017 Mathias Andersson <wraul@dbox.se> /* Copyright 2017-2019 Mathias Andersson <wraul@dbox.se>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -15,79 +15,73 @@
*/ */
#include QMK_KEYBOARD_H #include QMK_KEYBOARD_H
// Each layer gets a name for readability, which is then used in the keymap matrix below. enum layer_names {
// The underscores don't mean anything - you can have a layer called STUFF or any other name. _QW,
// Layer names don't all need to be of the same length, obviously, and you can also skip them _FN,
// entirely and just use numbers. };
#define _BL 0
#define _FL 1
// Defines the keycodes used by our macros in process_record_user
enum custom_keycodes {
MCR_01 = SAFE_RANGE,
MCR_02,
MCR_03,
MCR_04,
MCR_05,
MCR_06,
MCR_07,
MCR_08,
MCR_09,
MCR_10,
MCR_11,
};
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_BL] = LAYOUT( [_QW] = LAYOUT_tkl_ansi(
KC_ESC, 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_PSCR, KC_SLCK, KC_BRK, KC_ESC, 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_PSCR, KC_SLCK, KC_BRK,
KC_GRV, 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_INS, KC_HOME, KC_PGUP, KC_GRV, 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_INS, KC_HOME, KC_PGUP,
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_DEL, KC_END, KC_PGDN, 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_DEL, KC_END, KC_PGDN,
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_ENT, 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_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, KC_UP, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(_FL), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(_FN), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
[_FL] = LAYOUT( [_FN] = LAYOUT_tkl_ansi(
BL_STEP, M(0), M(1), M(2), M(3), M(4), M(5), M(6), M(7), M(8), M(9), M(10), M(11), _______, _______, _______, BL_STEP, MCR_01, MCR_02, MCR_03, MCR_03, MCR_04, MCR_05, MCR_06, MCR_07, MCR_08, MCR_09, MCR_10, MCR_11, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
}; };
// clang-format on
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) bool process_record_user(uint16_t keycode, keyrecord_t *record) {
{ switch (keycode) {
// MACRODOWN only works in this function case MCR_01:
switch (id) if (record->event.pressed) {
{ SEND_STRING("The");
case 0: }
if (record->event.pressed) break;
{ case MCR_02:
SEND_STRING("The"); if (record->event.pressed) {
return false; SEND_STRING("Custom");
} }
break; break;
case 1: case MCR_03:
if (record->event.pressed) if (record->event.pressed) {
{ SEND_STRING("Keyboard");
SEND_STRING("Custom"); }
return false; break;
} case MCR_04:
break; if (record->event.pressed) {
case 2: SEND_STRING(SS_LCTRL("c") SS_TAP(X_RIGHT) SS_LCTRL("v"));
if (record->event.pressed) }
{ break;
SEND_STRING("Keyboard");
return false;
}
break;
case 3:
if (record->event.pressed)
{
return MACRO(D(LCTL), T(C), U(LCTL), T(RGHT), D(LCTL), T(V), U(LCTL), END);
}
break;
} }
return MACRO_NONE; return true;
}; };
void matrix_init_user(void) void matrix_init_user(void) {}
{
}
void matrix_scan_user(void) void matrix_scan_user(void) {}
{
}
bool process_record_user(uint16_t keycode, keyrecord_t *record) void led_set_user(uint8_t usb_led) {}
{
return true;
}
void led_set_user(uint8_t usb_led)
{
}

View File

@ -2,8 +2,6 @@
This is the default keymap for the winkey version of the PCB. It implements the same features as the official default KMAC firmware. This is the default keymap for the winkey version of the PCB. It implements the same features as the official default KMAC firmware.
See [keymap.c](keymap.c) for details.
## Layers ## Layers
The keymap have two layers. To access the functions on the second layer, hold down `Fn` and press the corresponding key. The keymap have two layers. To access the functions on the second layer, hold down `Fn` and press the corresponding key.
@ -50,7 +48,3 @@ These are mostly useless and serve more like examples I guess.
| 2 | Types `Custom` | | 2 | Types `Custom` |
| 3 | Types `Keyboard` | | 3 | Types `Keyboard` |
| 4 | Inputs `<Ctrl+c>` `<Right>` `<Ctrl+v>` | | 4 | Inputs `<Ctrl+c>` `<Right>` `<Ctrl+v>` |
## Building
To build the firmware with the default keymap, run `make default`.

View File

@ -1,34 +0,0 @@
# Copyright 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/>.
# QMK Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI support (+2400 to 4200, depending on config)
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend

View File

@ -1,4 +1,4 @@
/* Copyright 2017 Mathias Andersson <wraul@dbox.se> /* Copyright 2019 Mathias Andersson <wraul@dbox.se>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -14,11 +14,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef CONFIG_USER_H #pragma once
#define CONFIG_USER_H
#include "../../config.h"
// place overrides here // place overrides here
#endif

View File

@ -0,0 +1,87 @@
/* Copyright 2017-2019 Mathias Andersson <wraul@dbox.se>
*
* 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 QMK_KEYBOARD_H
enum layer_names {
_QW,
_FN,
};
// Defines the keycodes used by our macros in process_record_user
enum custom_keycodes {
MCR_01 = SAFE_RANGE,
MCR_02,
MCR_03,
MCR_04,
MCR_05,
MCR_06,
MCR_07,
MCR_08,
MCR_09,
MCR_10,
MCR_11,
};
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QW] = LAYOUT_tkl_ansi(
KC_ESC, 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_PSCR, KC_SLCK, KC_BRK,
KC_GRV, 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_INS, KC_HOME, KC_PGUP,
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_DEL, KC_END, KC_PGDN,
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_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, KC_UP,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, MO(_FN), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
[_FN] = LAYOUT_tkl_ansi(
BL_STEP, MCR_01, MCR_02, MCR_03, MCR_03, MCR_04, MCR_05, MCR_06, MCR_07, MCR_08, MCR_09, MCR_10, MCR_11, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
};
// clang-format on
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case MCR_01:
if (record->event.pressed) {
SEND_STRING("The");
}
break;
case MCR_02:
if (record->event.pressed) {
SEND_STRING("Custom");
}
break;
case MCR_03:
if (record->event.pressed) {
SEND_STRING("Keyboard");
}
break;
case MCR_04:
if (record->event.pressed) {
SEND_STRING(SS_LCTRL("c") SS_TAP(X_RIGHT) SS_LCTRL("v"));
}
break;
}
return true;
};
void matrix_init_user(void) {}
void matrix_scan_user(void) {}
void led_set_user(uint8_t usb_led) {}

View File

@ -0,0 +1,50 @@
# Keymap for the winkey version of KMAC
This is the default keymap for the winkey version of the PCB. It implements the same features as the official default KMAC firmware.
## Layers
The keymap have two layers. To access the functions on the second layer, hold down `Fn` and press the corresponding key.
### Layer 1: Default Layer
,---. ,---------------. ,---------------. ,---------------. ,-----------.
|Esc| |F1 |F2 |F3 |F4 | |F5 |F6 |F7 |F8 | |F9 |F10|F11|F12| |PrS|ScL|Pau|
`---' `---------------' `---------------' `---------------' `-----------'
,-----------------------------------------------------------. ,-----------.
|~ | 1| 2| 3| 4| 5| 6| 7| 8| 9| 0| -| =|Backsp | |Ins|Hom|PgU|
|-----------------------------------------------------------| |-----------|
|Tab | Q| W| E| R| T| Y| U| I| O| P| [| ]| \| |Del|End|PgD|
|-----------------------------------------------------------| '-----------'
|Caps | A| S| D| F| G| H| J| K| L| ;| '|Return |
|-----------------------------------------------------------| ,---.
|Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | |Up |
|-----------------------------------------------------------| ,-----------.
|Ctl|Gui|Alt| Space |Alt|Gui|Fn |Ctl| |Lef|Dow|Rig|
`-----------------------------------------------------------' `-----------'
### Layer 2: Function Layer
,---. ,---------------. ,---------------. ,---------------. ,-----------.
|Led| |M1 |M2 |M3 |M4 | |M5 |M6 |M7 |M8 | |M9 |M10|M11|M12| | | | |
`---' `---------------' `---------------' `---------------' `-----------'
,-----------------------------------------------------------. ,-----------.
| | | | | | | | | | | | | | | | | | |
|-----------------------------------------------------------| |-----------|
| | | | | | | | | | | | | | | | | | |
|-----------------------------------------------------------| '-----------'
| | | | | | | | | | | | | |
|-----------------------------------------------------------| ,---.
| | | | | | | | | | | | | | |
|-----------------------------------------------------------| ,-----------.
| | | | | | | | | | | | |
`-----------------------------------------------------------' `-----------'
## Macros
These are mostly useless and serve more like examples I guess.
| Macro | Action |
|:-----:| -------------------------------------- |
| 1 | Types `The` |
| 2 | Types `Custom` |
| 3 | Types `Keyboard` |
| 4 | Inputs `<Ctrl+c>` `<Right>` `<Ctrl+v>` |

View File

@ -0,0 +1,19 @@
/* Copyright 2019 Mathias Andersson <wraul@dbox.se>
*
* 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/>.
*/
#pragma once
// place overrides here

View File

@ -0,0 +1,87 @@
/* Copyright 2017-2019 Mathias Andersson <wraul@dbox.se>
*
* 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 QMK_KEYBOARD_H
enum layer_names {
_QW,
_FN,
};
// Defines the keycodes used by our macros in process_record_user
enum custom_keycodes {
MCR_01 = SAFE_RANGE,
MCR_02,
MCR_03,
MCR_04,
MCR_05,
MCR_06,
MCR_07,
MCR_08,
MCR_09,
MCR_10,
MCR_11,
};
// clang-format off
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
[_QW] = LAYOUT_tkl_ansi_wkl(
KC_ESC, 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_PSCR, KC_SLCK, KC_BRK,
KC_GRV, 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_INS, KC_HOME, KC_PGUP,
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_DEL, KC_END, KC_PGDN,
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_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, KC_UP,
KC_LCTL, KC_LALT, KC_SPC, MO(_FN), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
[_FN] = LAYOUT_tkl_ansi_wkl(
BL_STEP, MCR_01, MCR_02, MCR_03, MCR_03, MCR_04, MCR_05, MCR_06, MCR_07, MCR_08, MCR_09, MCR_10, MCR_11, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______),
};
// clang-format on
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case MCR_01:
if (record->event.pressed) {
SEND_STRING("The");
}
break;
case MCR_02:
if (record->event.pressed) {
SEND_STRING("Custom");
}
break;
case MCR_03:
if (record->event.pressed) {
SEND_STRING("Keyboard");
}
break;
case MCR_04:
if (record->event.pressed) {
SEND_STRING(SS_LCTRL("c") SS_TAP(X_RIGHT) SS_LCTRL("v"));
}
break;
}
return true;
};
void matrix_init_user(void) {}
void matrix_scan_user(void) {}
void led_set_user(uint8_t usb_led) {}

View File

@ -2,9 +2,6 @@
This is the default keymap for the winkeyless version of the PCB. It implements the same features as the official default KMAC firmware. This is the default keymap for the winkeyless version of the PCB. It implements the same features as the official default KMAC firmware.
See [keymap.c](keymap.c) for details.
## Layers ## Layers
The keymap have two layers. To access the functions on the second layer, hold down `Fn` and press the corresponding key. The keymap have two layers. To access the functions on the second layer, hold down `Fn` and press the corresponding key.
@ -22,8 +19,8 @@ The keymap have two layers. To access the functions on the second layer, hold do
|-----------------------------------------------------------| ,---. |-----------------------------------------------------------| ,---.
|Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | |Up | |Shift | Z| X| C| V| B| N| M| ,| .| /|Shift | |Up |
|-----------------------------------------------------------| ,-----------. |-----------------------------------------------------------| ,-----------.
|Ctl|Gui|Alt| Space |Alt|Fn |Ctl| |Lef|Dow|Rig| |Ctl | |Alt | Space |Fn | |Ctl | |Lef|Dow|Rig|
`-----------------------------------------------------------' `-----------' `----' `-----------------------------------------' `----' `-----------'
### Layer 2: Function Layer ### Layer 2: Function Layer
,---. ,---------------. ,---------------. ,---------------. ,-----------. ,---. ,---------------. ,---------------. ,---------------. ,-----------.
@ -38,8 +35,8 @@ The keymap have two layers. To access the functions on the second layer, hold do
|-----------------------------------------------------------| ,---. |-----------------------------------------------------------| ,---.
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
|-----------------------------------------------------------| ,-----------. |-----------------------------------------------------------| ,-----------.
| | | | | | | | | | | | | | | | | | | | | | | |
`-----------------------------------------------------------' `-----------' `----' `-----------------------------------------' `----' `-----------'
## Macros ## Macros
@ -51,7 +48,3 @@ These are mostly useless and serve more like examples I guess.
| 2 | Types `Custom` | | 2 | Types `Custom` |
| 3 | Types `Keyboard` | | 3 | Types `Keyboard` |
| 4 | Inputs `<Ctrl+c>` `<Right>` `<Ctrl+v>` | | 4 | Inputs `<Ctrl+c>` `<Right>` `<Ctrl+v>` |
## Building
To build the firmware with the keymap for the winkeyless version, run `make winkeyless`.

View File

@ -1,93 +0,0 @@
/* Copyright 2017 Mathias Andersson <wraul@dbox.se>
*
* 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 QMK_KEYBOARD_H
// 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] = {
[_BL] = LAYOUT_WKL(
KC_ESC, 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_PSCR, KC_SLCK, KC_BRK,
KC_GRV, 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_INS, KC_HOME, KC_PGUP,
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_DEL, KC_END, KC_PGDN,
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_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, KC_UP,
KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(_FL), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
[_FL] = LAYOUT_WKL(
BL_STEP, M(0), M(1), M(2), M(3), M(4), M(5), M(6), M(7), M(8), M(9), M(10), M(11), _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______),
};
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt)
{
// MACRODOWN only works in this function
switch (id)
{
case 0:
if (record->event.pressed)
{
SEND_STRING("The");
return false;
}
break;
case 1:
if (record->event.pressed)
{
SEND_STRING("Custom");
return false;
}
break;
case 2:
if (record->event.pressed)
{
SEND_STRING("Keyboard");
return false;
}
break;
case 3:
if (record->event.pressed)
{
return MACRO(D(LCTL), T(C), U(LCTL), T(RGHT), D(LCTL), T(V), U(LCTL), END);
}
break;
}
return MACRO_NONE;
};
void matrix_init_user(void)
{
}
void matrix_scan_user(void)
{
}
bool process_record_user(uint16_t keycode, keyrecord_t *record)
{
return true;
}
void led_set_user(uint8_t usb_led)
{
}

View File

@ -1,34 +0,0 @@
# Copyright 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/>.
# QMK Build Options
# change to "no" to disable the options, or define them in the Makefile in
# the appropriate keymap folder that will get included automatically
#
BOOTMAGIC_ENABLE = yes # Virtual DIP switch configuration(+1000)
MOUSEKEY_ENABLE = yes # Mouse keys(+4700)
EXTRAKEY_ENABLE = yes # Audio control and System control(+450)
CONSOLE_ENABLE = no # Console for debug(+400)
COMMAND_ENABLE = yes # Commands for debug and configuration
NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality
MIDI_ENABLE = no # MIDI support (+2400 to 4200, depending on config)
AUDIO_ENABLE = no # Audio output on port C6
UNICODE_ENABLE = no # Unicode
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend

View File

@ -1,4 +1,4 @@
/* Copyright 2017 Mathias Andersson <wraul@dbox.se> /* Copyright 2017-2019 Mathias Andersson <wraul@dbox.se>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -15,61 +15,68 @@
*/ */
#include "kmac.h" #include "kmac.h"
#define CAPS_PIN B0
#define SCROLL_PIN E6
#define F_ROW_MASK 0b01
#define WASD_MASK 0b10
// Optional override functions below.
// You can leave any or all of these undefined.
// These are only required if you want to perform custom actions.
void matrix_init_kb(void) { void matrix_init_kb(void) {
// put your keyboard start-up code here // put your keyboard start-up code here
// runs once when the firmware starts up // runs once when the firmware starts up
led_init_ports(); setPinOutput(CAPS_PIN);
setPinOutput(SCROLL_PIN);
matrix_init_user(); matrix_init_user();
} }
void matrix_scan_kb(void) { /*
// put your looping keyboard code here
// runs every cycle (a lot)
matrix_scan_user(); void matrix_scan_kb(void) {
// put your looping keyboard code here
// runs every cycle (a lot)
matrix_scan_user();
} }
bool process_record_kb(uint16_t keycode, keyrecord_t *record) { bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
// put your per-action keyboard code here // put your per-action keyboard code here
// runs for every action, just before processing by the firmware // runs for every action, just before processing by the firmware
return process_record_user(keycode, record); return process_record_user(keycode, record);
} }
void led_init_ports(void) { */
DDRB |= (1<<0); // OUT
DDRE |= (1<<6); // OUT
}
/* LED pin configuration /* LED pin configuration
* Scroll Lock: Low PE6 * Scroll Lock: Low PE6
* Caps Lock: Low PB0 * Caps Lock: Low PB0
*/ */
void led_set_kb(uint8_t usb_led) { void led_set_kb(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_CAPS_LOCK)) if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
{ writePinLow(CAPS_PIN);
PORTB &= ~(1<<0); // LO } else {
} writePinHigh(CAPS_PIN);
else
{
PORTB |= (1<<0); // HI
} }
if (usb_led & (1<<USB_LED_SCROLL_LOCK)) if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
{ writePinLow(SCROLL_PIN);
PORTE &= ~(1<<6); // LO } else {
} writePinHigh(SCROLL_PIN);
else
{
PORTE |= (1<<6); // HI
} }
led_set_user(usb_led); led_set_user(usb_led);
} }
void backlight_init_ports(void) { void backlight_init_ports(void) {
DDRB |= (1<<1) | (1<<2) | (1<<3) | (1<<4); // OUT setPinOutput(B1);
DDRD |= (1<<7); // OUT setPinOutput(B2);
setPinOutput(B3);
setPinOutput(B4);
setPinOutput(D7);
} }
/* Backlight pin configuration /* Backlight pin configuration
@ -79,31 +86,24 @@ void backlight_init_ports(void) {
* S: Low PB3 * S: Low PB3
* D: Low PD7 * D: Low PD7
*/ */
void backlight_set(uint8_t level) void backlight_set(uint8_t level) {
{
// F-row // F-row
if(level & (1<<0)) if (level & F_ROW_MASK) {
{ writePinHigh(B1);
PORTB |= (1<<1); // HI } else {
} writePinLow(B1);
else
{
PORTB &= ~(1<<1); // LO
} }
// WASD // WASD
if(level & (1<<1)) if (level & WASD_MASK) {
{ writePinLow(B2);
PORTB &= ~(1<<4); // LO writePinLow(B3);
PORTB &= ~(1<<2); // LO writePinLow(B4);
PORTB &= ~(1<<3); // LO writePinLow(D7);
PORTD &= ~(1<<7); // LO } else {
} writePinHigh(B2);
else writePinHigh(B3);
{ writePinHigh(B4);
PORTB |= (1<<4); // HI writePinHigh(D7);
PORTB |= (1<<2); // HI
PORTB |= (1<<3); // HI
PORTD |= (1<<7); // HI
} }
} }

View File

@ -1,4 +1,4 @@
/* Copyright 2017 Mathias Andersson <wraul@dbox.se> /* Copyright 2017-2019 Mathias Andersson <wraul@dbox.se>
* *
* This program is free software: you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -13,41 +13,44 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef KMAC_H #pragma once
#define KMAC_H
#include "quantum.h" #include "quantum.h"
// Keymap for the winkey version of the PCB. // clang-format off
#define LAYOUT( \ #define LAYOUT_tkl_ansi( \
K00, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G, \ k00, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F, k0G, \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G, \ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, K2G, \ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, \
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3D, \ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3D, \
K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4D, K4F, \ k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4D, k4F, \
K50, K51, K52, K55, K58, K5A, K5C, K5D, K5E, K5F, K5G) \ k50, k51, k52, k55, k58, k5A, k5C, k5D, k5E, k5F, k5G \
{ \ ) \
/* 0 1 2 3 4 5 6 7 8 9 A B C D E F G */ \ { \
/* 0 */ {K00, KC_NO, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G}, \ {k00, KC_NO, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F, k0G}, \
/* 1 */ {K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G}, \ {k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G}, \
/* 2 */ {K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, K2G}, \ {k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G}, \
/* 3 */ {K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, KC_NO, K3D, KC_NO, KC_NO, KC_NO}, \ {k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, KC_NO, k3D, KC_NO, KC_NO, KC_NO}, \
/* 4 */ {K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, KC_NO, KC_NO, K4D, KC_NO, K4F, KC_NO}, \ {k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, KC_NO, KC_NO, k4D, KC_NO, k4F, KC_NO}, \
/* 5 */ { K50, K51, K52, KC_NO, KC_NO, K55, KC_NO, KC_NO, K58, KC_NO, K5A, KC_NO, K5C, K5D, K5E, K5F, K5G } \ {k50, k51, k52, KC_NO, KC_NO, k55, KC_NO, KC_NO, k58, KC_NO, k5A, KC_NO, k5C, k5D, k5E, k5F, k5G } \
} }
// clang-format on
// Keymap for the winkeyless version of the PCB. // clang-format off
#define LAYOUT_WKL( \ #define LAYOUT_tkl_ansi_wkl( \
K00, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G, \ k00, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F, k0G, \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G, \ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, K2G, \ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, \
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3D, \ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3D, \
K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4D, K4F, \ k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4D, k4F, \
K50, K51, K52, K55, K58, K5A, K5D, K5E, K5F, K5G) LAYOUT(K00, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C, K0D, K0E, K0F, K0G, \ k50, k52, k55, k58, k5D, k5E, k5F, k5G \
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, K1C, K1D, K1E, K1F, K1G, \ ) \
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B, K2C, K2D, K2E, K2F, K2G, \ { \
K30, K31, K32, K33, K34, K35, K36, K37, K38, K39, K3A, K3B, K3D, \ {k00, KC_NO, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F, k0G}, \
K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4D, K4F, \ {k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G}, \
K50, K51, K52, K55, K58, K5A, KC_NO, K5D, K5E, K5F, K5G) {k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G}, \
{k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, KC_NO, k3D, KC_NO, KC_NO, KC_NO}, \
#endif {k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, KC_NO, KC_NO, k4D, KC_NO, k4F, KC_NO}, \
{k50, KC_NO, k52, KC_NO, KC_NO, k55, KC_NO, KC_NO, k58, KC_NO, KC_NO, KC_NO, KC_NO, k5D, k5E, k5F, k5G } \
}
// clang-format on

View File

@ -1,5 +1,5 @@
/* /*
Copyright 2017 Mathias Andersson <wraul@dbox.se> Copyright 2017-2019 Mathias Andersson <wraul@dbox.se>
This program is free software: you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
@ -16,118 +16,137 @@ 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>
#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"
#include "timer.h" #include "debounce.h"
#include "quantum.h"
#if (MATRIX_COLS <= 8)
/* Set 0 if debouncing isn't needed */ # define print_matrix_header() print("\nr/c 01234567\n")
#ifndef DEBOUNCE # define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
# define DEBOUNCE 5 # define matrix_bitpop(i) bitpop(matrix[i])
# define ROW_SHIFTER ((uint8_t)1)
#elif (MATRIX_COLS <= 16)
# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n")
# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row))
# define matrix_bitpop(i) bitpop16(matrix[i])
# define ROW_SHIFTER ((uint16_t)1)
#elif (MATRIX_COLS <= 32)
# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n")
# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row))
# define matrix_bitpop(i) bitpop32(matrix[i])
# define ROW_SHIFTER ((uint32_t)1)
#endif #endif
#define COL_SHIFTER ((uint32_t)1) static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
static uint16_t debouncing_time;
static bool debouncing = false;
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
/* matrix state(1:on, 0:off) */ /* matrix state(1:on, 0:off) */
static matrix_row_t matrix[MATRIX_ROWS]; static matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values
static matrix_row_t matrix_debouncing[MATRIX_ROWS]; static matrix_row_t matrix[MATRIX_ROWS]; // debounced values
static void init_rows(void); __attribute__((weak)) void matrix_init_quantum(void) { matrix_init_kb(); }
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col);
static void unselect_cols(void);
static void select_col(uint8_t col);
inline __attribute__((weak)) void matrix_scan_quantum(void) { matrix_scan_kb(); }
uint8_t matrix_rows(void) {
return MATRIX_ROWS;
}
inline __attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
uint8_t matrix_cols(void) {
return MATRIX_COLS;
}
void matrix_init(void) { __attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
unselect_cols();
init_rows();
// initialize matrix state: all keys off __attribute__((weak)) void matrix_init_user(void) {}
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
matrix[i] = 0;
matrix_debouncing[i] = 0;
}
matrix_init_quantum(); __attribute__((weak)) void matrix_scan_user(void) {}
}
uint8_t matrix_scan(void) inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
{
// Set col, read rows
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
bool matrix_changed = read_rows_on_col(matrix_debouncing, current_col);
if (matrix_changed) {
debouncing = true;
debouncing_time = timer_read();
}
}
if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCE)) { inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i];
}
debouncing = false;
}
matrix_scan_quantum(); inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
return 1;
}
inline inline matrix_row_t matrix_get_row(uint8_t row) { return matrix[row]; }
bool matrix_is_on(uint8_t row, uint8_t col)
{
return (matrix[row] & ((matrix_row_t)1<<col));
}
inline void matrix_print(void) {
matrix_row_t matrix_get_row(uint8_t row) print_matrix_header();
{
return matrix[row];
}
void matrix_print(void)
{
print("\nr/c 0123456789ABCDEFGHIJKLMNOPQRSTUV\n");
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
phex(row); print(": "); phex(row);
print_bin_reverse32(matrix_get_row(row)); print(": ");
print_matrix_row(row);
print("\n"); print("\n");
} }
} }
uint8_t matrix_key_count(void) uint8_t matrix_key_count(void) {
{
uint8_t count = 0; uint8_t count = 0;
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
count += bitpop32(matrix[i]); count += matrix_bitpop(i);
} }
return count; return count;
} }
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) /* Columns 0 - 15
{ * These columns uses two 74HC237D 3 to 8 bit demultiplexers.
* col / pin: PB6 PC6 PC7 PF1 PF0
* 0: 0 1 0 0 0
* 1: 0 1 0 0 1
* 2: 0 1 0 1 0
* 3: 0 1 0 1 1
* 4: 0 1 1 0 0
* 5: 0 1 1 0 1
* 6: 0 1 1 1 0
* 7: 0 1 1 1 1
* 8: 1 0 0 0 0
* 9: 1 0 0 0 1
* 10: 1 0 0 1 0
* 11: 1 0 0 1 1
* 12: 1 0 1 0 0
* 13: 1 0 1 0 1
* 14: 1 0 1 1 0
* 15: 1 0 1 1 1
*
* col: 16
* pin: PB5
*/
static void unselect_cols(void) {
for (uint8_t x = 0; x < 6; x++) {
setPinOutput(col_pins[x]);
writePinLow(col_pins[x]);
}
}
static void select_col(uint8_t col) {
if (col < 16) {
uint8_t c = col + 8;
writePin(B6, c & 0b10000);
writePin(C6, c & 0b01000);
writePin(C7, c & 0b00100);
writePin(F1, c & 0b00010);
writePin(F0, c & 0b00001);
} else {
writePinHigh(B5);
}
}
/* Row pin configuration
* row: 0 1 2 3 4 5
* pin: D0 D1 D2 D3 D5 B7
*
* Caps lock uses its own pin E2
*/
static void init_pins(void) {
unselect_cols();
for (uint8_t x = 0; x < MATRIX_ROWS; x++) {
setPinInput(row_pins[x]);
}
setPinInputHigh(E2);
}
static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col) {
bool matrix_changed = false; bool matrix_changed = false;
// Select col and wait for col selecton to stabilize // Select col and wait for col selecton to stabilize
@ -135,42 +154,32 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
wait_us(30); wait_us(30);
// For each row... // For each row...
for(uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) for (uint8_t row_index = 0; row_index < MATRIX_ROWS; row_index++) {
{
// Store last value of row prior to reading // Store last value of row prior to reading
matrix_row_t last_row_value = current_matrix[row_index]; matrix_row_t last_row_value = current_matrix[row_index];
// Check row pin state // Check row pin state
// Use the otherwise unused row: 3, col: 0 for caps lock // Use the otherwise unused row: 3, col: 0 for caps lock
if (row_index == 3 && current_col == 0) { if (row_index == 3 && current_col == 0) {
// Pin E2 uses active low if (readPin(E2) == 0) {
if ((_SFR_IO8(E2 >> 4) & _BV(E2 & 0xF)) == 0)
{
// Pin LO, set col bit // Pin LO, set col bit
current_matrix[row_index] |= (COL_SHIFTER << current_col); current_matrix[row_index] |= (ROW_SHIFTER << current_col);
} } else {
else
{
// Pin HI, clear col bit // Pin HI, clear col bit
current_matrix[row_index] &= ~(COL_SHIFTER << current_col); current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
} }
} } else {
else { if (readPin(row_pins[row_index]) == 0) {
if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF))) // Pin HI, clear col bit
{ current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
// Pin HI, set col bit } else {
current_matrix[row_index] |= (COL_SHIFTER << current_col); // Pin LO, set col bit
} current_matrix[row_index] |= (ROW_SHIFTER << current_col);
else
{
// Pin LO, clear col bit
current_matrix[row_index] &= ~(COL_SHIFTER << current_col);
} }
} }
// Determine if the matrix changed state // Determine if the matrix changed state
if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) if ((last_row_value != current_matrix[row_index]) && !(matrix_changed)) {
{
matrix_changed = true; matrix_changed = true;
} }
} }
@ -181,131 +190,31 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
return matrix_changed; return matrix_changed;
} }
/* Row pin configuration void matrix_init(void) {
* row: 0 1 2 3 4 5 // initialize key pins
* pin: D0 D1 D2 D3 D5 B7 init_pins();
*
* Caps lock uses its own pin E2
*/
static void init_rows(void)
{
DDRD &= ~((1<<0)| (1<<1) | (1<<2) | (1<<3) | (1<<5)); // IN
PORTD &= ~((1<<0)| (1<<1) | (1<<2) | (1<<3) | (1<<5)); // LO
DDRB &= ~(1<<7); // IN
PORTB &= ~(1<<7); // LO
DDRE &= ~(1<<2); // IN // initialize matrix state: all keys off
PORTE |= (1<<2); // HI for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
} raw_matrix[i] = 0;
matrix[i] = 0;
/* Columns 0 - 15
* These columns uses two 74HC237D 3 to 8 bit demultiplexers.
* col / pin: PC6 PB6 PF0 PF1 PC7
* 0: 1 0 0 0 0
* 1: 1 0 1 0 0
* 2: 1 0 0 1 0
* 3: 1 0 1 1 0
* 4: 1 0 0 0 1
* 5: 1 0 1 0 1
* 6: 1 0 0 1 1
* 7: 1 0 1 1 1
* 8: 0 1 0 0 0
* 9: 0 1 1 0 0
* 10: 0 1 0 1 0
* 11: 0 1 1 1 0
* 12: 0 1 0 0 1
* 13: 0 1 1 0 1
* 14: 0 1 0 1 1
* 15: 0 1 1 1 1
*
* col: 16
* pin: PB5
*/
static void unselect_cols(void)
{
DDRB |= (1<<5) | (1<<6); // OUT
PORTB &= ~((1<<5) | (1<<6)); // LO
DDRC |= (1<<6) | (1<<7); // OUT
PORTC &= ~((1<<6) | (1<<7)); // LO
DDRF |= (1<<0) | (1<<1); // OUT
PORTF &= ~((1<<0) | (1<<1)); // LO
}
static void select_col(uint8_t col)
{
switch (col) {
case 0:
PORTC |= (1<<6); // HI
break;
case 1:
PORTC |= (1<<6); // HI
PORTF |= (1<<0); // HI
break;
case 2:
PORTC |= (1<<6); // HI
PORTF |= (1<<1); // HI
break;
case 3:
PORTC |= (1<<6); // HI
PORTF |= (1<<0) | (1<<1); // HI
break;
case 4:
PORTC |= (1<<6); // HI
PORTC |= (1<<7); // HI
break;
case 5:
PORTC |= (1<<6); // HI
PORTF |= (1<<0); // HI
PORTC |= (1<<7); // HI
break;
case 6:
PORTC |= (1<<6); // HI
PORTF |= (1<<1); // HI
PORTC |= (1<<7); // HI
break;
case 7:
PORTC |= (1<<6); // HI
PORTF |= (1<<0) | (1<<1); // HI
PORTC |= (1<<7); // HI
break;
case 8:
PORTB |= (1<<6); // HI
break;
case 9:
PORTB |= (1<<6); // HI
PORTF |= (1<<0); // HI
break;
case 10:
PORTB |= (1<<6); // HI
PORTF |= (1<<1); // HI
break;
case 11:
PORTB |= (1<<6); // HI
PORTF |= (1<<0) | (1<<1); // HI
break;
case 12:
PORTB |= (1<<6); // HI
PORTC |= (1<<7); // HI
break;
case 13:
PORTB |= (1<<6); // HI
PORTF |= (1<<0); // HI
PORTC |= (1<<7); // HI
break;
case 14:
PORTB |= (1<<6); // HI
PORTF |= (1<<1); // HI
PORTC |= (1<<7); // HI
break;
case 15:
PORTB |= (1<<6); // HI
PORTF |= (1<<0) | (1<<1); // HI
PORTC |= (1<<7); // HI
break;
case 16:
PORTB |= (1<<5); // HI
break;
} }
debounce_init(MATRIX_ROWS);
matrix_init_quantum();
}
uint8_t matrix_scan(void) {
bool changed = false;
for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++) {
changed |= read_rows_on_col(raw_matrix, current_col);
}
debounce(raw_matrix, matrix, MATRIX_ROWS, changed);
matrix_scan_quantum();
return (uint8_t)changed;
} }

View File

@ -1,44 +1,21 @@
# KMAC keyboard firmware # KMAC
A Korean custom keyboard designed by Byungho Kim and the KBDMania community. A Korean custom keyboard designed by Byungho Kim and the KBDMania community.
## Supported models Keyboard Maintainer: [Mathias Andersson](https://github.com/wraul)
Hardware Supported: KMAC & KMAC 2
Hardware Availability: http://www.kbdmania.net/xe/news/5232321
All the tenkeyless models should be supported. Make example for this keyboard (after setting up your build environment):
make kmac:default
See the [build environment setup](https://docs.qmk.fm/#/getting_started_build_tools) and the [make instructions](https://docs.qmk.fm/#/getting_started_make_guide) for more information. Brand new to QMK? Start with our [Complete Newbs Guide](https://docs.qmk.fm/#/newbs).
## Bootloader ## Bootloader
The PCB is hardwired to run the bootloader if the key at the `Caps Lock` position is held down when connecting the keyboard. The PCB is hardwired to run the bootloader if the key at the `Caps Lock` position is held down when connecting the keyboard.
It is also possible to use Boot Magic and Command to access the bootloader. ## PCB versions
## Quantum MK Firmware
For the full Quantum feature list, see the [documentation](https://docs.qmk.fm).
## Building
The KMAC are available with two different PCB layouts, a winkey version and a winkeyless version. A default keymap are provided for each versions of the PCB. The KMAC are available with two different PCB layouts, a winkey version and a winkeyless version. A default keymap are provided for each versions of the PCB.
Depending on which PCB and keymap you would like to use, you will have to compile the firmware slightly differently. All of the commands should be run in the [qmk root](https://github.com/qmk/qmk_firmware/) folder.
### Winkey keymap
The [default keymap](keymaps/default) are designed for the winkey version of the PCB.
### Winkeyless Keymap
A [keymap](keymaps/winkeyless) for the winkeyless version of the PCB are also provided.
### Custom keymaps
To define your own keymap, copy one of the [existing keymap](keymaps) folders and give it the name of your keymap. Then check the [keymap documentation](https://docs.qmk.fm/faq_keymap.html) for details on how to modify the keymap.
To make it easy to define keymaps for the different versions of the PCB two macros are provided.
| PCB | Macro |
| -------------- | -------------- |
| Winkey PCB | `LAYOUT()` |
| Winkeyless PCB | `LAYOUT_WKL()` |
To build the firmware with a custom keymap, run `make <keymap name>`

View File

@ -1,5 +1,5 @@
# Project specific files # Project specific files
SRC = matrix.c SRC += matrix.c
# MCU name # MCU name
#MCU = at90usb1287 #MCU = at90usb1287
@ -42,15 +42,19 @@ F_USB = $(F_CPU)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes* # Bootloader selection
# Teensy halfKay 512 # Teensy halfkay
# Teensy++ halfKay 1024 # Pro Micro caterina
# Atmel DFU loader 4096 # Atmel DFU atmel-dfu
# LUFA bootloader 4096 # LUFA DFU lufa-dfu
# USBaspLoader 2048 # QMK DFU qmk-dfu
OPT_DEFS += -DBOOTLOADER_SIZE=4096 # atmega32a bootloadHID
BOOTLOADER = atmel-dfu
# Supported layouts
LAYOUTS = tkl_ansi
# Build Options # Build Options
# change yes to no to disable # change yes to no to disable
# #