[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,8 +15,7 @@ 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
#pragma once
#include "config_common.h"
@ -36,9 +35,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
* Keyboard Matrix Assignments
* The KMAC uses demultiplexers for the cols, they are only included here as documentation.
* See matrix.c for more details.
*/
#define MATRIX_ROW_PINS { D0, D1, D2, D3, D5, B7 }
#define MATRIX_COL_PINS { C6, B6, F0, F1, C7, B5 }
*/
#define MATRIX_ROW_PINS \
{ D0, D1, D2, D3, D5, B7 }
#define MATRIX_COL_PINS \
{ B6, C6, C7, F1, F0, B5 }
#define UNUSED_PINS
/* 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) */
//#define MIDI_TONE_KEYCODE_OCTAVES 1
#endif

View file

@ -6,7 +6,8 @@
"width": 18.25,
"height": 6.5,
"layouts": {
"LAYOUT": {
"LAYOUT_tkl_ansi": {
"key_count": 87,
"layout": [
{ "label": "Esc", "x": 0, "y": 0 },
{ "label": "F1", "x": 2, "y": 0 },
@ -97,8 +98,8 @@
{ "label": "\u2192", "x": 17.25, "y": 5.5 }
]
},
"LAYOUT_WKL": {
"LAYOUT_tkl_ansi_wkl": {
"key_count": 84,
"layout": [
{ "label": "Esc", "x": 0, "y": 0 },
{ "label": "F1", "x": 2, "y": 0 },
@ -177,11 +178,9 @@
{ "label": "Shift", "x": 12.25, "y": 4.5, "w": 2.75 },
{ "label": "\u2191", "x": 16.25, "y": 4.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 },
{ "x": 4, "y": 5.5, "w": 7 },
{ "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": "\u2190", "x": 15.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
* 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
* it under the terms of the GNU General Public License as published by
@ -15,79 +15,73 @@
*/
#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
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] = {
[_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_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(_FL), KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT),
[_FL] = LAYOUT(
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), _______, _______, _______,
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
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)
{
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
switch (keycode) {
case MCR_01:
if (record->event.pressed) {
SEND_STRING("The");
return false;
}
break;
case 1:
if (record->event.pressed)
{
case MCR_02:
if (record->event.pressed) {
SEND_STRING("Custom");
return false;
}
break;
case 2:
if (record->event.pressed)
{
case MCR_03:
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);
case MCR_04:
if (record->event.pressed) {
SEND_STRING(SS_LCTRL("c") SS_TAP(X_RIGHT) SS_LCTRL("v"));
}
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)
{
return true;
}
void led_set_user(uint8_t usb_led)
{
}
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.
See [keymap.c](keymap.c) for details.
## Layers
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` |
| 3 | Types `Keyboard` |
| 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
* 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/>.
*/
#ifndef CONFIG_USER_H
#define CONFIG_USER_H
#include "../../config.h"
#pragma once
// 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.
See [keymap.c](keymap.c) for details.
## Layers
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 |
|-----------------------------------------------------------| ,-----------.
|Ctl|Gui|Alt| Space |Alt|Fn |Ctl| |Lef|Dow|Rig|
`-----------------------------------------------------------' `-----------'
|Ctl | |Alt | Space |Fn | |Ctl | |Lef|Dow|Rig|
`----' `-----------------------------------------' `----' `-----------'
### Layer 2: Function Layer
,---. ,---------------. ,---------------. ,---------------. ,-----------.
@ -39,7 +36,7 @@ The keymap have two layers. To access the functions on the second layer, hold do
| | | | | | | | | | | | | | |
|-----------------------------------------------------------| ,-----------.
| | | | | | | | | | | |
`-----------------------------------------------------------' `-----------'
`----' `-----------------------------------------' `----' `-----------'
## Macros
@ -51,7 +48,3 @@ These are mostly useless and serve more like examples I guess.
| 2 | Types `Custom` |
| 3 | Types `Keyboard` |
| 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
* it under the terms of the GNU General Public License as published by
@ -15,13 +15,26 @@
*/
#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) {
// put your keyboard start-up code here
// runs once when the firmware starts up
led_init_ports();
setPinOutput(CAPS_PIN);
setPinOutput(SCROLL_PIN);
matrix_init_user();
}
/*
void matrix_scan_kb(void) {
// put your looping keyboard code here
// runs every cycle (a lot)
@ -36,40 +49,34 @@ bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
return process_record_user(keycode, record);
}
void led_init_ports(void) {
DDRB |= (1<<0); // OUT
DDRE |= (1<<6); // OUT
}
*/
/* LED pin configuration
* Scroll Lock: Low PE6
* Caps Lock: Low PB0
*/
void led_set_kb(uint8_t usb_led) {
if (usb_led & (1<<USB_LED_CAPS_LOCK))
{
PORTB &= ~(1<<0); // LO
}
else
{
PORTB |= (1<<0); // HI
if (IS_LED_ON(usb_led, USB_LED_CAPS_LOCK)) {
writePinLow(CAPS_PIN);
} else {
writePinHigh(CAPS_PIN);
}
if (usb_led & (1<<USB_LED_SCROLL_LOCK))
{
PORTE &= ~(1<<6); // LO
}
else
{
PORTE |= (1<<6); // HI
if (IS_LED_ON(usb_led, USB_LED_SCROLL_LOCK)) {
writePinLow(SCROLL_PIN);
} else {
writePinHigh(SCROLL_PIN);
}
led_set_user(usb_led);
}
void backlight_init_ports(void) {
DDRB |= (1<<1) | (1<<2) | (1<<3) | (1<<4); // OUT
DDRD |= (1<<7); // OUT
setPinOutput(B1);
setPinOutput(B2);
setPinOutput(B3);
setPinOutput(B4);
setPinOutput(D7);
}
/* Backlight pin configuration
@ -79,31 +86,24 @@ void backlight_init_ports(void) {
* S: Low PB3
* D: Low PD7
*/
void backlight_set(uint8_t level)
{
void backlight_set(uint8_t level) {
// F-row
if(level & (1<<0))
{
PORTB |= (1<<1); // HI
}
else
{
PORTB &= ~(1<<1); // LO
if (level & F_ROW_MASK) {
writePinHigh(B1);
} else {
writePinLow(B1);
}
// WASD
if(level & (1<<1))
{
PORTB &= ~(1<<4); // LO
PORTB &= ~(1<<2); // LO
PORTB &= ~(1<<3); // LO
PORTD &= ~(1<<7); // LO
}
else
{
PORTB |= (1<<4); // HI
PORTB |= (1<<2); // HI
PORTB |= (1<<3); // HI
PORTD |= (1<<7); // HI
if (level & WASD_MASK) {
writePinLow(B2);
writePinLow(B3);
writePinLow(B4);
writePinLow(D7);
} else {
writePinHigh(B2);
writePinHigh(B3);
writePinHigh(B4);
writePinHigh(D7);
}
}

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
* 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
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef KMAC_H
#define KMAC_H
#pragma once
#include "quantum.h"
// Keymap for the winkey version of the PCB.
#define LAYOUT( \
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, \
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, \
K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4D, K4F, \
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}, \
/* 1 */ {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}, \
/* 3 */ {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}, \
/* 5 */ { 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 off
#define LAYOUT_tkl_ansi( \
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, \
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, \
k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4D, k4F, \
k50, k51, k52, k55, k58, k5A, k5C, k5D, k5E, k5F, k5G \
) \
{ \
{k00, KC_NO, 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}, \
{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}, \
{k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, KC_NO, KC_NO, k4D, KC_NO, k4F, KC_NO}, \
{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.
#define LAYOUT_WKL( \
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, \
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, \
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, \
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, \
K40, K41, K42, K43, K44, K45, K46, K47, K48, K49, K4A, K4D, K4F, \
K50, K51, K52, K55, K58, K5A, KC_NO, K5D, K5E, K5F, K5G)
#endif
// clang-format off
#define LAYOUT_tkl_ansi_wkl( \
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, \
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, \
k40, k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4D, k4F, \
k50, k52, k55, k58, k5D, k5E, k5F, k5G \
) \
{ \
{k00, KC_NO, 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}, \
{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}, \
{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
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 <stdbool.h>
#if defined(__AVR__)
#include <avr/io.h>
#endif
#include "wait.h"
#include "print.h"
#include "debug.h"
#include "util.h"
#include "matrix.h"
#include "timer.h"
#include "debounce.h"
#include "quantum.h"
/* Set 0 if debouncing isn't needed */
#ifndef DEBOUNCE
# define DEBOUNCE 5
#if (MATRIX_COLS <= 8)
# define print_matrix_header() print("\nr/c 01234567\n")
# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row))
# 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
#define COL_SHIFTER ((uint32_t)1)
static uint16_t debouncing_time;
static bool debouncing = false;
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
static const pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS;
/* 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 raw_matrix[MATRIX_ROWS]; // raw values
static matrix_row_t matrix[MATRIX_ROWS]; // debounced values
static void init_rows(void);
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);
__attribute__((weak)) void matrix_init_quantum(void) { matrix_init_kb(); }
inline
uint8_t matrix_rows(void) {
return MATRIX_ROWS;
}
__attribute__((weak)) void matrix_scan_quantum(void) { matrix_scan_kb(); }
inline
uint8_t matrix_cols(void) {
return MATRIX_COLS;
}
__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); }
void matrix_init(void) {
unselect_cols();
init_rows();
__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); }
// initialize matrix state: all keys off
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
matrix[i] = 0;
matrix_debouncing[i] = 0;
}
__attribute__((weak)) void matrix_init_user(void) {}
matrix_init_quantum();
}
__attribute__((weak)) void matrix_scan_user(void) {}
uint8_t matrix_scan(void)
{
// 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();
}
}
inline uint8_t matrix_rows(void) { return MATRIX_ROWS; }
if (debouncing && (timer_elapsed(debouncing_time) > DEBOUNCE)) {
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
matrix[i] = matrix_debouncing[i];
}
debouncing = false;
}
inline uint8_t matrix_cols(void) { return MATRIX_COLS; }
matrix_scan_quantum();
return 1;
}
inline bool matrix_is_on(uint8_t row, uint8_t col) { return (matrix[row] & ((matrix_row_t)1 << col)); }
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]; }
inline
matrix_row_t matrix_get_row(uint8_t row)
{
return matrix[row];
}
void matrix_print(void)
{
print("\nr/c 0123456789ABCDEFGHIJKLMNOPQRSTUV\n");
void matrix_print(void) {
print_matrix_header();
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
phex(row); print(": ");
print_bin_reverse32(matrix_get_row(row));
phex(row);
print(": ");
print_matrix_row(row);
print("\n");
}
}
uint8_t matrix_key_count(void)
{
uint8_t matrix_key_count(void) {
uint8_t count = 0;
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
count += bitpop32(matrix[i]);
count += matrix_bitpop(i);
}
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;
// 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);
// 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
matrix_row_t last_row_value = current_matrix[row_index];
// Check row pin state
// Use the otherwise unused row: 3, col: 0 for caps lock
if (row_index == 3 && current_col == 0) {
// Pin E2 uses active low
if ((_SFR_IO8(E2 >> 4) & _BV(E2 & 0xF)) == 0)
{
if (readPin(E2) == 0) {
// Pin LO, set col bit
current_matrix[row_index] |= (COL_SHIFTER << current_col);
}
else
{
current_matrix[row_index] |= (ROW_SHIFTER << current_col);
} else {
// Pin HI, clear col bit
current_matrix[row_index] &= ~(COL_SHIFTER << current_col);
current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
}
}
else {
if ((_SFR_IO8(row_pins[row_index] >> 4) & _BV(row_pins[row_index] & 0xF)))
{
// Pin HI, set col bit
current_matrix[row_index] |= (COL_SHIFTER << current_col);
}
else
{
// Pin LO, clear col bit
current_matrix[row_index] &= ~(COL_SHIFTER << current_col);
} else {
if (readPin(row_pins[row_index]) == 0) {
// Pin HI, clear col bit
current_matrix[row_index] &= ~(ROW_SHIFTER << current_col);
} else {
// Pin LO, set col bit
current_matrix[row_index] |= (ROW_SHIFTER << current_col);
}
}
// 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;
}
}
@ -181,131 +190,31 @@ static bool read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)
return matrix_changed;
}
/* 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_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
void matrix_init(void) {
// initialize key pins
init_pins();
DDRE &= ~(1<<2); // IN
PORTE |= (1<<2); // HI
}
/* 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;
// initialize matrix state: all keys off
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
raw_matrix[i] = 0;
matrix[i] = 0;
}
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.
## 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
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.
## Quantum MK Firmware
For the full Quantum feature list, see the [documentation](https://docs.qmk.fm).
## Building
## PCB versions
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
SRC = matrix.c
SRC += matrix.c
# MCU name
#MCU = at90usb1287
@ -42,15 +42,19 @@ F_USB = $(F_CPU)
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
# Boot Section Size in *bytes*
# Teensy halfKay 512
# Teensy++ halfKay 1024
# Atmel DFU loader 4096
# LUFA bootloader 4096
# USBaspLoader 2048
OPT_DEFS += -DBOOTLOADER_SIZE=4096
# Bootloader selection
# Teensy halfkay
# Pro Micro caterina
# Atmel DFU atmel-dfu
# LUFA DFU lufa-dfu
# QMK DFU qmk-dfu
# atmega32a bootloadHID
BOOTLOADER = atmel-dfu
# Supported layouts
LAYOUTS = tkl_ansi
# Build Options
# change yes to no to disable
#