forked from qmk/qmk_firmware
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Keyboard: add Keyboardio Model 01 (qmk#3900)
* Keyboard: add Keyboardio Model01 This port implements key scanning and everything in their default keymap. It doesn't implement mouse warping; QMK can't do that (yet). LED control is mostly not implemented. The ability to set all LEDs is included because they can get stuck on coming from the bootloader otherwise. Single LED control is also implemented for numpad indication. The scanners also support batch LED transfer which is what you'd need if you wanted to do fast effects. Gamma correction is also not implemented, but is present in the original firmware. The necessary info for further implementation is in the KeyboardioScanner module for Kaleidoscope. To install on your keyboard: make model01:avrdude When prompted, hold the "prog" key on the keyboard to put it into programming mode. This can also be achieved by holding the "prog" key while plugging in the keyboard. This works even if the firmware is corrupt or missing. Hot plugging the halves seems to work fine, but there is no explicit support for eg. making sure the matrix scan rate is reconfigured. * model01: clean up includes and include guards Uses #pragma once everywhere. * model01: split LED and matrix code This makes space if someone wants to implement better LED support later on, the keyboard is a lot more capable than the current code. * model01: separate I2C timeouts for matrix vs. LED If the scanners have no data they don't ACK reads and just time out. So we want a pretty short timeout to keep scan rates high. Meanwhile the LED transfers might take longer - I don't know though, so here we are conservative. * model01: implement better LED control - gamma correction from the manufacturer's firmware - suitable delays to allow back to back LED writes - this is fast enough to write the whole keyboard without noticeable delay, in my experience - minor bug fix: RHS Fn key was not addressable * model01: add license to wire-protocol-constants.h * model01: replace gamma LUT The original was of unclear license origin. This one is functionally identical and includes a generator should people wish to adjust it. * model01: use the already-present CIE1931 lightness curve ...rather than baking in another gamma curve. It's said that CIE1931 is the right thing to be using rather than gamma. OK. Let it be so. * model01: call matrix_init_user() from matrix_init_kb() * model01: remove inapplicable config options from rules.mk * model01: readme.md: update build environment links
- Loading branch information
Showing
14 changed files
with
571 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
/* | ||
Copyright 2018 James Laird-Wah | ||
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 0x1209 | ||
#define PRODUCT_ID 0x2301 | ||
#define DEVICE_VER 0x0001 | ||
#define MANUFACTURER Keyboardio | ||
#define PRODUCT Model 01 | ||
#define DESCRIPTION (QMK) | ||
|
||
/* key matrix size; rows are doubled for split */ | ||
#define MATRIX_ROWS 8 | ||
#define MATRIX_COLS 8 | ||
|
||
/* The scanners already debounce for us */ | ||
#define DEBOUNCING_DELAY 0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"keyboard_name": "model01", | ||
"url": "https://keyboard.io" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/* Copyright 2018 James Laird-Wah | ||
* | ||
* 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 */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
/* Copyright 2018 James Laird-Wah | ||
* | ||
* 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 | ||
|
||
/* layer constants */ | ||
enum { | ||
DEF = 0, | ||
NUM, | ||
FUN, | ||
}; | ||
|
||
|
||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | ||
[DEF] = LAYOUT( | ||
RESET , KC_1 , KC_2 , KC_3 , KC_4 , KC_5 , KC_6 , KC_7 , KC_8 , KC_9 , KC_0 , TG(NUM), | ||
KC_GRV , KC_Q , KC_W , KC_E , KC_R , KC_T , _______, _______, KC_Y , KC_U , KC_I , KC_O , KC_P , KC_EQL , | ||
KC_PGUP, KC_A , KC_S , KC_D , KC_F , KC_G , KC_TAB , KC_ENT , KC_H , KC_J , KC_K , KC_L , KC_SCLN, KC_QUOT, | ||
KC_PGDN, KC_Z , KC_X , KC_C , KC_V , KC_B , KC_ESC , _______, KC_N , KC_M , KC_COMM, KC_DOT , KC_SLSH, KC_MINS, | ||
KC_LCTL, KC_RCTL, | ||
KC_BSPC, KC_SPC , | ||
KC_LGUI, KC_RALT, | ||
KC_LSFT, KC_RSFT, | ||
MO(FUN), MO(FUN) | ||
), | ||
[NUM] = LAYOUT( | ||
_______, _______, _______, _______, _______, _______, _______, KC_P7 , KC_P8 , KC_P9 , KC_PMNS, _______, | ||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_P4 , KC_P5 , KC_P6 , KC_PPLS, _______, | ||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_P1 , KC_P2 , KC_P3 , KC_PEQL, _______, | ||
_______, _______, _______, _______, _______, _______, _______, _______, _______, KC_P0 , KC_PDOT, KC_PAST, KC_PSLS, KC_PENT, | ||
_______, _______, | ||
_______, _______, | ||
_______, _______, | ||
_______, _______, | ||
_______, _______ | ||
), | ||
[FUN] = LAYOUT( | ||
_______, KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11 , | ||
KC_TAB , _______, KC_MS_U, _______, KC_BTN3, _______, _______, KC_MPRV, KC_MNXT, KC_LCBR, KC_RCBR, KC_LBRC, KC_RBRC, KC_F12 , | ||
KC_HOME, KC_MS_L, KC_MS_D, KC_MS_R, KC_BTN1, _______, _______, KC_MPLY, KC_LEFT, KC_DOWN, KC_UP , KC_RGHT, _______, _______, | ||
KC_END , KC_PSCR, KC_INS , _______, KC_BTN2, _______, _______, _______, KC_MUTE, KC_VOLD, KC_VOLU, _______, KC_BSLS, KC_PIPE, | ||
_______, _______, | ||
KC_DEL , KC_ENT , | ||
_______, _______, | ||
_______, _______, | ||
_______, _______ | ||
) | ||
}; | ||
|
||
/* template for new layouts: | ||
LAYOUT( | ||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, | ||
_______, _______, | ||
_______, _______, | ||
_______, _______, | ||
_______, _______, | ||
_______, _______ | ||
) | ||
*/ | ||
|
||
uint32_t layer_state_set_user(uint32_t state) { | ||
switch (biton32(state)) { | ||
case DEF: | ||
set_all_leds_to(0,0,0); | ||
break; | ||
case NUM: | ||
/* highlight the numpad keys when numlock is on */ | ||
for (int i=44; i<=60; i++) { | ||
set_led_to(i, 128,0,0); | ||
} | ||
set_led_to(63, 128, 0, 0); | ||
break; | ||
} | ||
|
||
return state; | ||
} | ||
|
||
/* vim: set ts=2 sw=2 et: */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# The default keymap for Keyboardio's Model01 | ||
|
||
This implements all of their default keymap, except for mouse warping. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# used by default keymap | ||
MOUSEKEY_ENABLE = yes # Mouse keys(+4700) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* Copyright 2018 James Laird-Wah | ||
* | ||
* 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 <quantum.h> | ||
#include <i2c_master.h> | ||
#include <led_tables.h> | ||
#include "model01.h" | ||
|
||
#define I2C_TIMEOUT 1000 | ||
|
||
#define LINCOR(i) pgm_read_byte(&CIE1931_CURVE[i]) | ||
|
||
int set_all_leds_to_raw(uint8_t r, uint8_t g, uint8_t b) { | ||
uint8_t buf[] = { | ||
TWI_CMD_LED_SET_ALL_TO, | ||
b, g, r | ||
}; | ||
int ret = 0; | ||
ret |= i2c_transmit(I2C_ADDR(LEFT), buf, sizeof(buf), I2C_TIMEOUT); | ||
ret |= i2c_transmit(I2C_ADDR(RIGHT), buf, sizeof(buf), I2C_TIMEOUT); | ||
_delay_us(10); | ||
return ret; | ||
} | ||
|
||
int set_all_leds_to(uint8_t r, uint8_t g, uint8_t b) { | ||
return set_all_leds_to_raw(LINCOR(r), LINCOR(g), LINCOR(b)); | ||
} | ||
|
||
int set_led_to_raw(uint8_t led, uint8_t r, uint8_t g, uint8_t b) { | ||
uint8_t buf[] = { | ||
TWI_CMD_LED_SET_ONE_TO, | ||
led & 0x1f, | ||
b, g, r | ||
}; | ||
int hand = (led >= 32) ? RIGHT : LEFT; | ||
int ret = i2c_transmit(I2C_ADDR(hand), buf, sizeof(buf), I2C_TIMEOUT); | ||
_delay_us(10); | ||
return ret; | ||
} | ||
|
||
int set_led_to(uint8_t led, uint8_t r, uint8_t g, uint8_t b) { | ||
return set_led_to_raw(led, LINCOR(r), LINCOR(g), LINCOR(b)); | ||
} | ||
|
||
/* vim: set ts=2 sw=2 et: */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
/* Copyright 2018 James Laird-Wah | ||
* | ||
* 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> | ||
|
||
int set_all_leds_to(uint8_t r, uint8_t g, uint8_t b); | ||
int set_led_to(uint8_t led, uint8_t r, uint8_t g, uint8_t b); | ||
|
||
/* Raw (gamma uncorrected) LED values */ | ||
int set_all_leds_to_raw(uint8_t r, uint8_t g, uint8_t b); | ||
int set_led_to_raw(uint8_t led, uint8_t r, uint8_t g, uint8_t b); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* Copyright 2018 James Laird-Wah | ||
* | ||
* 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 <quantum.h> | ||
#include <i2c_master.h> | ||
#include <string.h> | ||
#include "model01.h" | ||
|
||
/* If no key events have occurred, the scanners will time out on reads. | ||
* So we don't want to be too permissive here. */ | ||
#define I2C_TIMEOUT 10 | ||
|
||
static matrix_row_t rows[MATRIX_ROWS]; | ||
#define ROWS_PER_HAND (MATRIX_ROWS / 2) | ||
|
||
inline | ||
uint8_t matrix_rows(void) { | ||
return MATRIX_ROWS; | ||
} | ||
|
||
inline | ||
uint8_t matrix_cols(void) { | ||
return MATRIX_COLS; | ||
} | ||
|
||
static int i2c_read_hand(int hand) { | ||
uint8_t buf[5]; | ||
i2c_status_t ret = i2c_receive(I2C_ADDR(hand), buf, sizeof(buf), I2C_TIMEOUT); | ||
if (ret != I2C_STATUS_SUCCESS) | ||
return 1; | ||
|
||
if (buf[0] != TWI_REPLY_KEYDATA) | ||
return 2; | ||
|
||
int start_row = hand ? ROWS_PER_HAND : 0; | ||
uint8_t *out = &rows[start_row]; | ||
memcpy(out, &buf[1], 4); | ||
return 0; | ||
} | ||
|
||
static int i2c_set_keyscan_interval(int hand, int delay) { | ||
uint8_t buf[] = {TWI_CMD_KEYSCAN_INTERVAL, delay}; | ||
i2c_status_t ret = i2c_transmit(I2C_ADDR(hand), buf, sizeof(buf), I2C_TIMEOUT); | ||
return ret; | ||
} | ||
|
||
void matrix_init(void) { | ||
/* Ensure scanner power is on - else right hand will not work */ | ||
DDRC |= _BV(7); | ||
PORTC |= _BV(7); | ||
|
||
i2c_init(); | ||
i2c_set_keyscan_interval(LEFT, 2); | ||
i2c_set_keyscan_interval(RIGHT, 2); | ||
memset(rows, 0, sizeof(rows)); | ||
|
||
matrix_init_quantum(); | ||
} | ||
|
||
uint8_t matrix_scan(void) { | ||
uint8_t ret = 0; | ||
ret |= i2c_read_hand(LEFT); | ||
ret |= i2c_read_hand(RIGHT); | ||
matrix_scan_quantum(); | ||
return ret; | ||
} | ||
|
||
inline | ||
matrix_row_t matrix_get_row(uint8_t row) { | ||
return rows[row]; | ||
} | ||
|
||
void matrix_print(void) { | ||
print("\nr/c 0123456789ABCDEF\n"); | ||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | ||
phex(row); print(": "); | ||
pbin_reverse16(matrix_get_row(row)); | ||
print("\n"); | ||
} | ||
} | ||
|
||
/* vim: set ts=2 sw=2 et: */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
/* Copyright 2018 James Laird-Wah | ||
* | ||
* 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 <quantum.h> | ||
#include <i2c_master.h> | ||
#include <string.h> | ||
#include "model01.h" | ||
|
||
void matrix_init_kb(void) { | ||
/* the bootloader can leave LEDs on, so */ | ||
set_all_leds_to(0, 0, 0); | ||
matrix_init_user(); | ||
} | ||
|
||
void matrix_scan_kb(void) { | ||
matrix_scan_user(); | ||
} | ||
|
||
__attribute__ ((weak)) | ||
void matrix_scan_user(void) { | ||
} | ||
|
||
__attribute__ ((weak)) | ||
void matrix_init_user(void) { | ||
} |
Oops, something went wrong.