[Keyboard] Handwired Maltron DQz11N1G contoured keyboard (#17237)
* Basic support for Maltron DQz11N1G controller replacement. * Update keyboards/handwired/dqz11n1g/rules.mk * Rehost images to cubeupload.com. (They were previously hosted via github wiki) * Apply suggestions from noroadsleft code review * Update keyboards/handwired/dqz11n1g/dqz11n1g.hhailey_branch
parent
747b33cb81
commit
931c7539d2
@ -0,0 +1,58 @@ |
|||||||
|
/*
|
||||||
|
Copyright (c) 2022 David Kuehling <dvdkhlng TA posteo TOD de> |
||||||
|
|
||||||
|
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 |
||||||
|
|
||||||
|
#include "config_common.h" |
||||||
|
|
||||||
|
/* USB Device descriptor parameter */ |
||||||
|
#define VENDOR_ID 0xFEED |
||||||
|
#define PRODUCT_ID 0x4451 |
||||||
|
#define DEVICE_VER 0x0001 |
||||||
|
#define PRODUCT DQz11N1G Controller Replacement |
||||||
|
|
||||||
|
/* Matrix size */ |
||||||
|
#define MATRIX_ROWS 7 |
||||||
|
#define MATRIX_COLS 19 |
||||||
|
|
||||||
|
/* Pin-out */ |
||||||
|
#define MATRIX_ROW_PINS { D1, D0, D4, C6, D7, E6, B4 } |
||||||
|
|
||||||
|
/* The pin connecting to the SN74HC165 SH/~LD in */ |
||||||
|
#define ROW_SHIFT_PIN B6 |
||||||
|
|
||||||
|
/* Column read via SPI (shift register) */ |
||||||
|
/* #define MATRIX_COL_PINS { } */ |
||||||
|
#define UNUSED_PINS |
||||||
|
|
||||||
|
#define LED_CAPS_LOCK_PIN F7 /* A0 */ |
||||||
|
#define LED_NUM_LOCK_PIN F5 /*A2 */ |
||||||
|
#define LED_SCROLL_LOCK_PIN F4 /*A3 */ |
||||||
|
|
||||||
|
#define LED_FUN_LOCK_PIN F6 /* A1 (handled in layer_state_set_user()) */ |
||||||
|
|
||||||
|
/* audio config */ |
||||||
|
#define AUDIO_PIN B5 |
||||||
|
#define AUDIO_CLICKY |
||||||
|
#define AUDIO_INIT_DELAY |
||||||
|
#define AUDIO_CLICKY_FREQ_RANDOMNESS 0.0f |
||||||
|
#define NO_MUSIC_MODE |
||||||
|
|
||||||
|
/* diodes go row->col, though this is hard-coded in matrix.c and we drive the
|
||||||
|
* matrix differently: we have pull-down on the columns and drive the selected |
||||||
|
* row high */ |
||||||
|
/* #define DIODE_DIRECTION ROW2COL */ |
@ -0,0 +1,51 @@ |
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 David Kuehling <dvdkhlng TA posteo TOD de> |
||||||
|
* |
||||||
|
* 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 |
||||||
|
|
||||||
|
#include "quantum.h" |
||||||
|
|
||||||
|
#define XXX KC_NO |
||||||
|
|
||||||
|
/* Fill actually existing keys into the 7x19 keyboard matrix */ |
||||||
|
#define LAYOUT( \ |
||||||
|
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F, k0G, k0H, k0J, \
|
||||||
|
k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1J, \
|
||||||
|
k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2J, \
|
||||||
|
k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F, k3G, k3H, k3J, \
|
||||||
|
k40, k41, k42, k43, k44, k45, k4D, k4E, k4F, k4G, k4H, k4J, \
|
||||||
|
k51, k52, k53, k54, k5E, k5F, k5G, k5H, \
|
||||||
|
k46, k47, k48, k4A, k4B, k4C, \
|
||||||
|
k56, k57, k58, k5A, k5B, k5C, \
|
||||||
|
k68, k6A \
|
||||||
|
) { \
|
||||||
|
/* left hand */ /* middle/thumb block */ /* right hand */ \
|
||||||
|
{ k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F, k0G, k0H, k0J }, \
|
||||||
|
{ k10, k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1F, k1G, k1H, k1J }, \
|
||||||
|
{ k20, k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, k2G, k2H, k2J }, \
|
||||||
|
{ k30, k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3E, k3F, k3G, k3H, k3J }, \
|
||||||
|
{ k40, k41, k42, k43, k44, k45, k46, k47, k48, XXX, k4A, k4B, k4C, k4D, k4E, k4F, k4G, k4H, k4J }, \
|
||||||
|
{ XXX, k51, k52, k53, k54, XXX, k56, k57, k58, XXX, k5A, k5B, k5C, XXX, k5E, k5F, k5G, k5H, XXX }, \
|
||||||
|
{ XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX, k68, XXX, k6A, XXX, XXX, XXX, XXX, XXX, XXX, XXX, XXX }, \
|
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Local Variables: |
||||||
|
* c-basic-offset:4 |
||||||
|
* fill-column: 76 |
||||||
|
* End: |
||||||
|
*/ |
@ -0,0 +1,141 @@ |
|||||||
|
{ |
||||||
|
"keyboard_name": "DQz11N1G", |
||||||
|
"url": "https://github.com/dvdkhlng/qmk_firmware_dqz11n1g", |
||||||
|
"maintainer": "dvdkhlng", |
||||||
|
"layouts": { |
||||||
|
"LAYOUT": { |
||||||
|
"layout": [ |
||||||
|
{"x": 0, "y": 0, "matrix": [0, 0] }, |
||||||
|
{"x": 1, "y": 0, "matrix": [0, 1] }, |
||||||
|
{"x": 2, "y": 0, "matrix": [0, 2] }, |
||||||
|
{"x": 3, "y": 0, "matrix": [0, 3] }, |
||||||
|
{"x": 4, "y": 0, "matrix": [0, 4] }, |
||||||
|
{"x": 5, "y": 0, "matrix": [0, 5] }, |
||||||
|
|
||||||
|
{"x": 7, "y": 0, "matrix": [0, 6] }, |
||||||
|
{"x": 8, "y": 0, "matrix": [0, 7] }, |
||||||
|
{"x": 9, "y": 0, "matrix": [0, 8] }, |
||||||
|
{"x": 10, "y": 0, "matrix": [0, 9] }, |
||||||
|
{"x": 11, "y": 0, "matrix": [0, 10] }, |
||||||
|
{"x": 12, "y": 0, "matrix": [0, 11] }, |
||||||
|
{"x": 13, "y": 0, "matrix": [0, 12] }, |
||||||
|
|
||||||
|
{"x": 15, "y": 0, "matrix": [0, 13] }, |
||||||
|
{"x": 16, "y": 0, "matrix": [0, 14] }, |
||||||
|
{"x": 17, "y": 0, "matrix": [0, 15] }, |
||||||
|
{"x": 18, "y": 0, "matrix": [0, 16] }, |
||||||
|
{"x": 19, "y": 0, "matrix": [0, 17] }, |
||||||
|
{"x": 20, "y": 0, "matrix": [0, 18] }, |
||||||
|
|
||||||
|
{"x": 0, "y": 1, "matrix": [1, 0] }, |
||||||
|
{"x": 1, "y": 1, "matrix": [1, 1] }, |
||||||
|
{"x": 2, "y": 1, "matrix": [1, 2] }, |
||||||
|
{"x": 3, "y": 1, "matrix": [1, 3] }, |
||||||
|
{"x": 4, "y": 1, "matrix": [1, 4] }, |
||||||
|
{"x": 5, "y": 1, "matrix": [1, 5] }, |
||||||
|
|
||||||
|
{"x": 7, "y": 1, "matrix": [1, 6] }, |
||||||
|
{"x": 8, "y": 1, "matrix": [1, 7] }, |
||||||
|
{"x": 9, "y": 1, "matrix": [1, 8] }, |
||||||
|
{"x": 10, "y": 1, "matrix": [1, 9] }, |
||||||
|
{"x": 11, "y": 1, "matrix": [1, 10] }, |
||||||
|
{"x": 12, "y": 1, "matrix": [1, 11] }, |
||||||
|
{"x": 13, "y": 1, "matrix": [1, 12] }, |
||||||
|
|
||||||
|
{"x": 15, "y": 1, "matrix": [1, 13] }, |
||||||
|
{"x": 16, "y": 1, "matrix": [1, 14] }, |
||||||
|
{"x": 17, "y": 1, "matrix": [1, 15] }, |
||||||
|
{"x": 18, "y": 1, "matrix": [1, 16] }, |
||||||
|
{"x": 19, "y": 1, "matrix": [1, 17] }, |
||||||
|
{"x": 20, "y": 1, "matrix": [1, 18] }, |
||||||
|
|
||||||
|
{"x": 0, "y": 2, "matrix": [2, 0] }, |
||||||
|
{"x": 1, "y": 2, "matrix": [2, 1] }, |
||||||
|
{"x": 2, "y": 2, "matrix": [2, 2] }, |
||||||
|
{"x": 3, "y": 2, "matrix": [2, 3] }, |
||||||
|
{"x": 4, "y": 2, "matrix": [2, 4] }, |
||||||
|
{"x": 5, "y": 2, "matrix": [2, 5] }, |
||||||
|
|
||||||
|
{"x": 7, "y": 2, "matrix": [2, 6] }, |
||||||
|
{"x": 8, "y": 2, "matrix": [2, 7] }, |
||||||
|
{"x": 9, "y": 2, "matrix": [2, 8] }, |
||||||
|
{"x": 10, "y": 2, "matrix": [2, 9] }, |
||||||
|
{"x": 11, "y": 2, "matrix": [2, 10] }, |
||||||
|
{"x": 12, "y": 2, "matrix": [2, 11] }, |
||||||
|
{"x": 13, "y": 2, "matrix": [2, 12] }, |
||||||
|
|
||||||
|
{"x": 15, "y": 2, "matrix": [2, 13] }, |
||||||
|
{"x": 16, "y": 2, "matrix": [2, 14] }, |
||||||
|
{"x": 17, "y": 2, "matrix": [2, 15] }, |
||||||
|
{"x": 18, "y": 2, "matrix": [2, 16] }, |
||||||
|
{"x": 19, "y": 2, "matrix": [2, 17] }, |
||||||
|
{"x": 20, "y": 2, "matrix": [2, 18] }, |
||||||
|
|
||||||
|
{"x": 0, "y": 3, "matrix": [3, 0] }, |
||||||
|
{"x": 1, "y": 3, "matrix": [3, 1] }, |
||||||
|
{"x": 2, "y": 3, "matrix": [3, 2] }, |
||||||
|
{"x": 3, "y": 3, "matrix": [3, 3] }, |
||||||
|
{"x": 4, "y": 3, "matrix": [3, 4] }, |
||||||
|
{"x": 5, "y": 3, "matrix": [3, 5] }, |
||||||
|
|
||||||
|
{"x": 7, "y": 3, "matrix": [3, 6] }, |
||||||
|
{"x": 8, "y": 3, "matrix": [3, 7] }, |
||||||
|
{"x": 9, "y": 3, "matrix": [3, 8] }, |
||||||
|
{"x": 10, "y": 3, "matrix": [3, 9] }, |
||||||
|
{"x": 11, "y": 3, "matrix": [3, 10] }, |
||||||
|
{"x": 12, "y": 3, "matrix": [3, 11] }, |
||||||
|
{"x": 13, "y": 3, "matrix": [3, 12] }, |
||||||
|
|
||||||
|
{"x": 15, "y": 3, "matrix": [3, 13] }, |
||||||
|
{"x": 16, "y": 3, "matrix": [3, 14] }, |
||||||
|
{"x": 17, "y": 3, "matrix": [3, 15] }, |
||||||
|
{"x": 18, "y": 3, "matrix": [3, 16] }, |
||||||
|
{"x": 19, "y": 3, "matrix": [3, 17] }, |
||||||
|
{"x": 20, "y": 3, "matrix": [3, 18] }, |
||||||
|
|
||||||
|
{"x": 0, "y": 4, "h": 2, "matrix": [4, 0] }, |
||||||
|
{"x": 1, "y": 4, "matrix": [4, 1] }, |
||||||
|
{"x": 2, "y": 4, "matrix": [4, 2] }, |
||||||
|
{"x": 3, "y": 4, "matrix": [4, 3] }, |
||||||
|
{"x": 4, "y": 4, "matrix": [4, 4] }, |
||||||
|
{"x": 5, "y": 4, "matrix": [4, 5] }, |
||||||
|
|
||||||
|
{"x": 15, "y": 4, "matrix": [4, 13] }, |
||||||
|
{"x": 16, "y": 4, "matrix": [4, 14] }, |
||||||
|
{"x": 17, "y": 4, "matrix": [4, 15] }, |
||||||
|
{"x": 18, "y": 4, "matrix": [4, 16] }, |
||||||
|
{"x": 19, "y": 4, "matrix": [4, 17] }, |
||||||
|
{"x": 20, "y": 4, "h": 2, "matrix": [4, 18] }, |
||||||
|
|
||||||
|
{"x": 1, "y": 5, "matrix": [5, 1] }, |
||||||
|
{"x": 2, "y": 5, "matrix": [5, 2] }, |
||||||
|
{"x": 3, "y": 5, "matrix": [5, 3] }, |
||||||
|
{"x": 4, "y": 5, "matrix": [5, 4] }, |
||||||
|
|
||||||
|
{"x": 16, "y": 5, "matrix": [5, 14] }, |
||||||
|
{"x": 17, "y": 5, "matrix": [5, 15] }, |
||||||
|
{"x": 18, "y": 5, "matrix": [5, 16] }, |
||||||
|
{"x": 19, "y": 5, "matrix": [5, 17] }, |
||||||
|
|
||||||
|
{"x": 5, "y": 7, "matrix": [4, 6] }, |
||||||
|
{"x": 6, "y": 7, "matrix": [4, 7] }, |
||||||
|
{"x": 7, "y": 7, "matrix": [4, 8] }, |
||||||
|
|
||||||
|
{"x": 13, "y": 7, "matrix": [4, 10] }, |
||||||
|
{"x": 14, "y": 7, "matrix": [4, 11] }, |
||||||
|
{"x": 15, "y": 7, "matrix": [4, 12] }, |
||||||
|
|
||||||
|
{"x": 5, "y": 8, "h": 2, "matrix": [5, 6] }, |
||||||
|
{"x": 6, "y": 8, "h": 2, "matrix": [5, 7] }, |
||||||
|
{"x": 7, "y": 8, "matrix": [5, 8] }, |
||||||
|
|
||||||
|
{"x": 13, "y": 8, "matrix": [5, 10] }, |
||||||
|
{"x": 14, "y": 8, "h": 2, "matrix": [5, 11] }, |
||||||
|
{"x": 15, "y": 8, "h": 2, "matrix": [5, 12] }, |
||||||
|
|
||||||
|
{"x": 7, "y": 9, "matrix": [6, 8] }, |
||||||
|
{"x": 13, "y": 9, "matrix": [6, 10] } |
||||||
|
] |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
/* Copyright (c) 2022 David Kuehling < dvdkhlng TA posteo TOD de >
|
||||||
|
* |
||||||
|
* 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 { _DEFAULT, _FUNCTION }; |
||||||
|
#define KC_FUN TG(_FUNCTION) |
||||||
|
|
||||||
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { |
||||||
|
[_DEFAULT] = LAYOUT( |
||||||
|
KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_FUN, KC_NUM, KC_P7, KC_P8, KC_P9, KC_PSLS, KC_PSCR, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, |
||||||
|
|
||||||
|
KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_VOLU, KC_ESC, KC_P4, KC_P5, KC_P6, KC_PAST, KC_SCRL, KC_7, KC_8, KC_9, KC_0, KC_MINS,KC_EQL,
|
||||||
|
KC_NUBS,KC_Q, KC_W, KC_E, KC_R, KC_T, KC_VOLD, KC_GRV, KC_P1, KC_P2, KC_P3, KC_PMNS, KC_BRK, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC,
|
||||||
|
KC_CAPS,KC_A, KC_S, KC_D, KC_F, KC_G, KC_MUTE, KC_WSCH,KC_P0,KC_PDOT,KC_PENT,KC_PPLS,KC_INS, KC_H, KC_J, KC_K, KC_L, KC_SCLN,KC_QUOT,
|
||||||
|
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_LCTL, KC_LGUI,KC_LALT,KC_RBRC, KC_NUHS,KC_RALT,KC_APP, KC_RCTL, /* */ |
||||||
|
|
||||||
|
/* thumb keys: */ KC_BSPC, KC_HOME, KC_END, KC_LEFT, KC_RGHT, KC_DEL, |
||||||
|
/* thumb keys: */ KC_SPC, KC_TAB, KC_PGUP, KC_UP, KC_ENT, KC_SPC, |
||||||
|
/* thumb keys: */ KC_PGDN, KC_DOWN |
||||||
|
), |
||||||
|
|
||||||
|
/* This is the "function key locked" layer. It is not documented by
|
||||||
|
* Maltron, so just putting some "Quantum" keycodes here for testing that |
||||||
|
* the layer exists and Fun Lock LED works. */ |
||||||
|
[_FUNCTION] = LAYOUT( |
||||||
|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS,KC_TRNS,KC_BTN3,KC_MS_U,KC_WH_U,KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
|
||||||
|
|
||||||
|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, CK_UP, AU_ON, KC_MS_L,KC_BTN1,KC_MS_R,KC_NO, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
|
||||||
|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, CK_DOWN,AU_OFF, KC_BTN2,KC_MS_D,KC_WH_D,KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
|
||||||
|
KC_TRNS,KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, CK_TOGG,KC_NO, KC_ACL0,KC_ACL1,KC_ACL2,KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
|
||||||
|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
|
||||||
|
/* */ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, /* */ |
||||||
|
|
||||||
|
/* thumb keys: */ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
|
||||||
|
/* thumb keys: */ KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO,
|
||||||
|
/* thumb keys: */ KC_NO, KC_NO |
||||||
|
) |
||||||
|
}; |
||||||
|
|
||||||
|
/* Show "Fun Lock" layer state via the "Fun Lock" LED */ |
||||||
|
layer_state_t layer_state_set_user(layer_state_t state) { |
||||||
|
|
||||||
|
setPinOutput(LED_FUN_LOCK_PIN); |
||||||
|
|
||||||
|
if (layer_state_cmp(state, _FUNCTION)) |
||||||
|
writePinHigh(LED_FUN_LOCK_PIN); |
||||||
|
else |
||||||
|
writePinLow(LED_FUN_LOCK_PIN); |
||||||
|
|
||||||
|
return state; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Local Variables: |
||||||
|
* c-basic-offset:4 |
||||||
|
* fill-column: 76 |
||||||
|
* End: |
||||||
|
*/ |
@ -0,0 +1,17 @@ |
|||||||
|
 |
||||||
|
|
||||||
|
# Default Layout for DQz11N1G-DE |
||||||
|
|
||||||
|
This is the layout corresponding to what the Maltron keyboard DQz11N1G-DE I |
||||||
|
own came with (using the original pre-installed controller). Note that this |
||||||
|
differs from German Maltron layout as published on [Maltron's |
||||||
|
website](https://www.maltron.com/germany.html). Use the photo above as a |
||||||
|
reference for the layout implemented here. |
||||||
|
|
||||||
|
I did not find any official documentation about the the Function Lock key on |
||||||
|
the original Maltron keyboards. It seems that it implements some of the |
||||||
|
features that are documented for the one-handed Maltron keyboards. Most |
||||||
|
keys don't send any keycodes at all when function lock is enabed. |
||||||
|
|
||||||
|
We instead map some of the Quantum keycodes (mouse keys and audio control) |
||||||
|
in the middle (keypad) section of the keypad, when Function Lock is enabled. |
@ -0,0 +1,131 @@ |
|||||||
|
/*
|
||||||
|
Copyright (c) 2022 David Kuehling <dvdkhlng TA posteo TOD de> |
||||||
|
|
||||||
|
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 <stdint.h> |
||||||
|
#include <stdbool.h> |
||||||
|
#include <string.h> |
||||||
|
|
||||||
|
#include <avr/io.h> |
||||||
|
|
||||||
|
#include "spi_master.h" |
||||||
|
#include "quantum.h" |
||||||
|
#include "matrix.h" |
||||||
|
|
||||||
|
static pin_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS; |
||||||
|
|
||||||
|
static void unselect_rows(void); |
||||||
|
|
||||||
|
void matrix_init_custom(void) { |
||||||
|
/* initialize row pins */ |
||||||
|
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { |
||||||
|
setPinOutput(row_pins[row]); |
||||||
|
} |
||||||
|
unselect_rows(); |
||||||
|
|
||||||
|
/* columns read via shift-register on SPI lines */ |
||||||
|
|
||||||
|
/* Enable SPI, Master, set clock rate fck/2. First bit already at Qh
|
||||||
|
* output before clock edge (CPHA=0). SN74HC165 shift register shifts |
||||||
|
* on low-to-high transition (CPOL=1). Receive the LSB first (DORD=1). |
||||||
|
*/ |
||||||
|
bool lsbFirst = true; |
||||||
|
uint8_t mode = 2; /* CPOL=1, CPHA=0 */ |
||||||
|
uint16_t divisor = 16; |
||||||
|
|
||||||
|
/* According to Atmega32U4 datasheet, PB0 *must* be set to output,
|
||||||
|
* otherwise it will interfere with SPI master operation. On pro-micro |
||||||
|
* it's connected to a yellew LED. */ |
||||||
|
pin_t slavePin = PB0; |
||||||
|
spi_init(); |
||||||
|
spi_start(slavePin, lsbFirst, mode, divisor); |
||||||
|
|
||||||
|
/* Initialize pin controlling the shift register's SH/~LD pin */ |
||||||
|
setPinOutput(ROW_SHIFT_PIN); |
||||||
|
} |
||||||
|
|
||||||
|
static void select_row(uint8_t row) { |
||||||
|
pin_t pin = row_pins[row]; |
||||||
|
if (pin != NO_PIN) { |
||||||
|
writePinHigh(pin); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void unselect_row(uint8_t row) { |
||||||
|
pin_t pin = row_pins[row]; |
||||||
|
if (pin != NO_PIN) { |
||||||
|
writePinLow(pin); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static void unselect_rows(void) { |
||||||
|
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { |
||||||
|
unselect_row(row); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
bool matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { |
||||||
|
/* Start with a clear matrix row */ |
||||||
|
matrix_row_t current_row_value = 0; |
||||||
|
|
||||||
|
/* Set shift register SH/~LD pin to "load" mode */ |
||||||
|
writePinLow(ROW_SHIFT_PIN); |
||||||
|
select_row(current_row); |
||||||
|
matrix_output_select_delay(); |
||||||
|
|
||||||
|
/* Set shift register SH/~LD pin to "shift" mode */ |
||||||
|
writePinHigh(ROW_SHIFT_PIN); |
||||||
|
|
||||||
|
/* For each octet of columns... */ |
||||||
|
for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index += 8) { |
||||||
|
spi_status_t read_result = spi_read(); |
||||||
|
if (read_result >= 0) { |
||||||
|
/* only if SPI read successful: populate the matrix row with the
|
||||||
|
state of the 8 consecutive column bits */ |
||||||
|
current_row_value |= ((matrix_row_t)read_result << col_index); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* Unselect row & wait for all columns signals to go high. */ |
||||||
|
unselect_row(current_row); |
||||||
|
matrix_output_unselect_delay(current_row, current_row_value != 0);
|
||||||
|
|
||||||
|
/* Update row in matrix. */ |
||||||
|
if (current_row_value != current_matrix[current_row]) { |
||||||
|
current_matrix[current_row] = current_row_value; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
bool matrix_scan_custom(matrix_row_t curr_matrix[]) { |
||||||
|
bool changed = false; |
||||||
|
|
||||||
|
/* set row, read cols */ |
||||||
|
for (uint8_t current_row = 0; current_row < MATRIX_ROWS; current_row++) { |
||||||
|
changed |= matrix_read_cols_on_row(curr_matrix, current_row); |
||||||
|
} |
||||||
|
|
||||||
|
return changed; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Local Variables: |
||||||
|
* c-basic-offset:4 |
||||||
|
* fill-column: 76 |
||||||
|
* End: |
||||||
|
*/ |
@ -0,0 +1,80 @@ |
|||||||
|
# DQz11N1G |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
Firmware for a DIY controller replacement for one of the ortholinear contoured |
||||||
|
keyboards manufactured by [PCD Maltron Ltd](https://www.maltron.com) |
||||||
|
|
||||||
|
This work here in no way officially associated with PCD Maltron Ltd and comes |
||||||
|
with NO WARRANTY. Modifying your Maltron keyboard as described below will |
||||||
|
certainly void your warranty and may cause damage to your keyboard. Proceed |
||||||
|
at your own risk! |
||||||
|
|
||||||
|
* maintainer: [David Kuehling](https://github.com/dvdkhlng/qmk_firmware_dqz11n1g) |
||||||
|
* Hardware Supported: Maltron DQz11N1G with a replacement controller board |
||||||
|
assembled as described below. The work here is based on a german version |
||||||
|
of the keyboard: DQz11N1G-DE. I assume, but don't know for sure, that |
||||||
|
minor or no changes at all are required to make this work on different |
||||||
|
language versions of the keyboard. |
||||||
|
* Hardware Availability: |
||||||
|
* [PCD Maltron Ltd](https://www.maltron.com), for the original keyboard |
||||||
|
* 1x [Arduino Pro Micro](https://www.sparkfun.com/products/12640) |
||||||
|
* 3x [SN74HC165](https://www.ti.com/product/SN74HC165) |
||||||
|
* 1x DIL connector 2 rows a 17 pins. |
||||||
|
* 19x pull-down resistors (10k Ohm), |
||||||
|
* 4 LED current limiting resistors (not sure about the correct resistance, |
||||||
|
using 470 Ohm here) |
||||||
|
|
||||||
|
Make example for this keyboard (after setting up your build environment): |
||||||
|
|
||||||
|
make handwired/dqz11n1g:default |
||||||
|
|
||||||
|
## In Detail |
||||||
|
|
||||||
|
[PCD Maltron Ltd](https://www.maltron.com) manufacturs ergonomic keyboards |
||||||
|
that appear to be hand-wired internally. For the Maltron DQz11N1G-DE |
||||||
|
keyboard that I happen to own, the keyboard matrix is wired to a 34-pin DIL |
||||||
|
connector. This makes it rather easy to replace the proprietary |
||||||
|
controller-board with a self-made board based on the QMK firmware. |
||||||
|
|
||||||
|
I don't really like the default layout of my Maltron DQz11N1G-DE keyboard, |
||||||
|
and modding it to work with QMK allows me to adapt it to my needs. It |
||||||
|
especially allows for the two space keys to assume different roles, thereby |
||||||
|
creating an additional easily reachable thumb-key. |
||||||
|
|
||||||
|
### Internal Details of Keyboard Matrix and DIL Connector |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
### Replacement Keyboard Controller Board |
||||||
|
|
||||||
|
Due to supply chain problems, I decided to base this on an |
||||||
|
Arduino-compatible [Pro Micro](https://www.sparkfun.com/products/12640) |
||||||
|
board which is still easy to source. |
||||||
|
|
||||||
|
Unfortunately pin-count of the DQz11N1G-DE's keyboard matrix is way beyond |
||||||
|
the Pro Micro's available I/O pin count. I'm using three 8-bit |
||||||
|
shift-registers ([SN74HC165](https://www.ti.com/product/SN74HC165) ) to |
||||||
|
connect the 19 colums of the keyboard matrix for readout. Due to diode |
||||||
|
direction in DQz11N1G-DE we also need 19 pull-down resistors one for each of |
||||||
|
the utilized shift-register inputs. |
||||||
|
|
||||||
|
This is a design sketch of the replacement board this is based on. Note how |
||||||
|
we need a custom matrix.c source file to deal with the shift register based |
||||||
|
keyboard readout. |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
This is how the assembled controller board looks like, on the right side you |
||||||
|
see the original PIC-based controller the keyboard ships with. |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
Inside of the keyboard after installing the new controller board: |
||||||
|
|
||||||
|
 |
||||||
|
|
||||||
|
(Not visible in the photo: I drilled hole into the keyboard above the USB |
||||||
|
connector for a reset switch to simplify flashing controller firmware) |
@ -0,0 +1,24 @@ |
|||||||
|
# MCU name
|
||||||
|
MCU = atmega32u4
|
||||||
|
|
||||||
|
# Bootloader selection
|
||||||
|
BOOTLOADER = caterina
|
||||||
|
|
||||||
|
# Keyboard matrix uses shift-registers read via SPI
|
||||||
|
CUSTOM_MATRIX = lite
|
||||||
|
SRC += matrix.c
|
||||||
|
QUANTUM_LIB_SRC += spi_master.c
|
||||||
|
|
||||||
|
# Build Options
|
||||||
|
# change yes to no to disable
|
||||||
|
#
|
||||||
|
BOOTMAGIC_ENABLE = no # Enable Bootmagic Lite
|
||||||
|
MOUSEKEY_ENABLE = yes # Mouse keys
|
||||||
|
EXTRAKEY_ENABLE = yes # Audio control and System control
|
||||||
|
CONSOLE_ENABLE = no # Console for debug
|
||||||
|
COMMAND_ENABLE = yes # Commands for debug and configuration
|
||||||
|
NKRO_ENABLE = no # Enable N-Key Rollover
|
||||||
|
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||||
|
RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow
|
||||||
|
AUDIO_ENABLE = yes # Audio output
|
||||||
|
|
Loading…
Reference in new issue