* Added Chimera Ortho keymap * added readme * fixed hardware link * Added KC_KEYMAP * resolving conflict * Added Chimera LS and Chimera Ergo * Added rules file * fixed rule files * Added Chimera Ortho keymap * Added KC_KEYMAP * Added Chimera LS and Chimera Ergo * fixed rule files * fixed rule files * fixed image links * Added KC_KEYMAP * Added Chimera LS and Chimera Ergo * Added Chimera Ortho keymap * fixed rule files * fixed rule files * fixed image links * Fixed KEYMAP vs KC_KEYMAPpull/2371/merge
@ -0,0 +1,31 @@ | |||
#include "chimera_ergo.h" | |||
void uart_init(void) { | |||
SERIAL_UART_INIT(); | |||
} | |||
void led_init(void) { | |||
DDRD |= (1<<1); | |||
PORTD |= (1<<1); | |||
DDRF |= (1<<4) | (1<<5); | |||
PORTF |= (1<<4) | (1<<5); | |||
} | |||
void matrix_init_kb(void) { | |||
// put your keyboard start-up code here | |||
// runs once when the firmware starts up | |||
matrix_init_user(); | |||
uart_init(); | |||
led_init(); | |||
} | |||
void matrix_scan_kb(void) { | |||
// put your looping keyboard code here | |||
// runs every cycle (a lot) | |||
matrix_scan_user(); | |||
} | |||
void led_set_kb(uint8_t usb_led) { | |||
} |
@ -0,0 +1,82 @@ | |||
#ifndef CHIMERA_ERGO_H | |||
#define CHIMERA_ERGO_H | |||
#include "quantum.h" | |||
#include "matrix.h" | |||
#include "backlight.h" | |||
#include <stddef.h> | |||
#define red_led_off PORTF |= (1<<5) | |||
#define red_led_on PORTF &= ~(1<<5) | |||
#define blu_led_off PORTF |= (1<<4) | |||
#define blu_led_on PORTF &= ~(1<<4) | |||
#define grn_led_off PORTD |= (1<<1) | |||
#define grn_led_on PORTD &= ~(1<<1) | |||
#define set_led_off red_led_off; grn_led_off; blu_led_off | |||
#define set_led_red red_led_on; grn_led_off; blu_led_off | |||
#define set_led_blue red_led_off; grn_led_off; blu_led_on | |||
#define set_led_green red_led_off; grn_led_on; blu_led_off | |||
#define set_led_yellow red_led_on; grn_led_on; blu_led_off | |||
#define set_led_magenta red_led_on; grn_led_off; blu_led_on | |||
#define set_led_cyan red_led_off; grn_led_on; blu_led_on | |||
#define set_led_white red_led_on; grn_led_on; blu_led_on | |||
/* | |||
#define LED_B 5 | |||
#define LED_R 6 | |||
#define LED_G 7 | |||
#define all_leds_off PORTF &= ~(1<<LED_B) & ~(1<<LED_R) & ~(1<<LED_G) | |||
#define red_led_on PORTF |= (1<<LED_R) | |||
#define red_led_off PORTF &= ~(1<<LED_R) | |||
#define grn_led_on PORTF |= (1<<LED_G) | |||
#define grn_led_off PORTF &= ~(1<<LED_G) | |||
#define blu_led_on PORTF |= (1<<LED_B) | |||
#define blu_led_off PORTF &= ~(1<<LED_B) | |||
#define set_led_off PORTF &= ~(1<<LED_B) & ~(1<<LED_R) & ~(1<<LED_G) | |||
#define set_led_red PORTF = PORTF & ~(1<<LED_B) & ~(1<<LED_G) | (1<<LED_R) | |||
#define set_led_blue PORTF = PORTF & ~(1<<LED_G) & ~(1<<LED_R) | (1<<LED_B) | |||
#define set_led_green PORTF = PORTF & ~(1<<LED_B) & ~(1<<LED_R) | (1<<LED_G) | |||
#define set_led_yellow PORTF = PORTF & ~(1<<LED_B) | (1<<LED_R) | (1<<LED_G) | |||
#define set_led_magenta PORTF = PORTF & ~(1<<LED_G) | (1<<LED_R) | (1<<LED_B) | |||
#define set_led_cyan PORTF = PORTF & ~(1<<LED_R) | (1<<LED_B) | (1<<LED_G) | |||
#define set_led_white PORTF |= (1<<LED_B) | (1<<LED_R) | (1<<LED_G) | |||
*/ | |||
// This a shortcut to help you visually see your layout. | |||
// The first section contains all of the arguements | |||
// The second converts the arguments into a two-dimensional array | |||
#define KC_KEYMAP( \ | |||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k10, k11, \ | |||
k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, \ | |||
k24, k25, k26, k27, k28, k29, k30, k31, k32, k33, k34, k35, \ | |||
k36, k37, k38, k39, k40, k41, k42, k43, k44, k45, k46, k47, \ | |||
k48, k49, k50, k51 \ | |||
) \ | |||
{ \ | |||
{ KC_NO, KC_NO, KC_##k26, KC_##k15, KC_##k28, KC_##k01, KC_##k42, KC_##k31, KC_##k20, KC_##k33, KC_NO, KC_NO }, \ | |||
{ KC_##k00, KC_NO, KC_##k14, KC_##k27, KC_##k16, KC_##k36, KC_##k47, KC_##k19, KC_##k32, KC_##k21, KC_NO, KC_##k11 }, \ | |||
{ KC_##k12, KC_##k25, KC_##k02, KC_##k39, KC_##k17, KC_##k49, KC_##k50, KC_##k18, KC_##k44, KC_##k09, KC_##k34, KC_##k23 }, \ | |||
{ KC_##k24, KC_##k13, KC_##k38, KC_##k04, KC_##k05, KC_##k48, KC_##k51, KC_##k06, KC_##k07, KC_##k45, KC_##k22, KC_##k35 }, \ | |||
{ KC_##k29, KC_##k41, KC_##k03, KC_##k40, KC_##k37, KC_NO, KC_##k30, KC_##k43, KC_##k08, KC_##k10, KC_##k46, KC_NO }, \ | |||
} | |||
#define KEYMAP( \ | |||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k10, k11, \ | |||
k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, \ | |||
k24, k25, k26, k27, k28, k29, k30, k31, k32, k33, k34, k35, \ | |||
k36, k37, k38, k39, k40, k41, k42, k43, k44, k45, k46, k47, \ | |||
k48, k49, k50, k51 \ | |||
) \ | |||
{ \ | |||
{ KC_NO, KC_NO, k26, k15, k28, k01, k42, k31, k20, k33, KC_NO, KC_NO }, \ | |||
{ k00, KC_NO, k14, k27, k16, k36, k47, k19, k32, k21, KC_NO, k11 }, \ | |||
{ k12, k25, k02, k39, k17, k49, k50, k18, k44, k09, k34, k23 }, \ | |||
{ k24, k13, k38, k04, k05, k48, k51, k06, k07, k45, k22, k35 }, \ | |||
{ k29, k41, k03, k40, k37, KC_NO, k30, k43, k08, k10, k46, KC_NO }, \ | |||
} | |||
#endif |
@ -0,0 +1,87 @@ | |||
/* | |||
Copyright 2012 Jun Wako <wakojun@gmail.com> | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef CONFIG_H | |||
#define CONFIG_H | |||
#include "config_common.h" | |||
/* USB Device descriptor parameter */ | |||
#define VENDOR_ID 0xFEED | |||
#define PRODUCT_ID 0x6060 | |||
#define DEVICE_VER 0x0001 | |||
#define MANUFACTURER unknown | |||
#define PRODUCT Chimera Ergo | |||
#define DESCRIPTION q.m.k. keyboard firmware for Chimera Ergo | |||
/* key matrix size */ | |||
#define MATRIX_ROWS 6 | |||
#define MATRIX_COLS 12 | |||
/* define if matrix has ghost */ | |||
//#define MATRIX_HAS_GHOST | |||
/* number of backlight levels */ | |||
//#define BACKLIGHT_LEVELS 3 | |||
#define ONESHOT_TIMEOUT 500 | |||
/* key combination for command */ | |||
#define IS_COMMAND() ( \ | |||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ | |||
) | |||
/* | |||
* Feature disable options | |||
* These options are also useful to firmware size reduction. | |||
*/ | |||
#define PREVENT_STUCK_MODIFIERS | |||
/* disable debug print */ | |||
//#define NO_DEBUG | |||
/* disable print */ | |||
//#define NO_PRINT | |||
/* disable action features */ | |||
//#define NO_ACTION_LAYER | |||
//#define NO_ACTION_TAPPING | |||
//#define NO_ACTION_ONESHOT | |||
//#define NO_ACTION_MACRO | |||
//#define NO_ACTION_FUNCTION | |||
//UART settings for communication with the RF microcontroller | |||
#define SERIAL_UART_BAUD 1000000 | |||
#define SERIAL_UART_DATA UDR1 | |||
#define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1) | |||
#define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1)) | |||
#define SERIAL_UART_RXD_PRESENT (UCSR1A & _BV(RXC1)) | |||
#define SERIAL_UART_INIT() do { \ | |||
/* baud rate */ \ | |||
UBRR1L = SERIAL_UART_UBRR; \ | |||
/* baud rate */ \ | |||
UBRR1H = SERIAL_UART_UBRR >> 8; \ | |||
/* enable TX and RX */ \ | |||
UCSR1B = _BV(TXEN1) | _BV(RXEN1); \ | |||
/* 8-bit data */ \ | |||
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ | |||
} while(0) | |||
#endif |
@ -0,0 +1,206 @@ | |||
// this is the style you want to emulate. | |||
// This is the canonical layout file for the Quantum project. If you want to add another keyboard, | |||
#include "chimera_ergo.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. | |||
enum chimera_ergo_layers | |||
{ | |||
_QWERTY, | |||
_CAPS, | |||
_NUMPAD, | |||
_SYMBOLS, | |||
_MACROS, | |||
_NAV | |||
}; | |||
#define KC_NMPD TG(_NUMPAD) | |||
#define KC_SYMB TG(_SYMBOLS) | |||
#define KC_SPFN LT(_NAV,KC_EQL) | |||
#define KC_SCTL MT(MOD_LCTL, KC_LBRC) | |||
#define KC_SCTR MT(MOD_LCTL, KC_RBRC) | |||
#define KC_SPLT MT(MOD_LALT, KC_MINS) | |||
#define KC_SPRT MT(MOD_LALT, KC_1) | |||
#define KC_GBRC MT(MOD_RGUI, KC_RBRC) | |||
#define KC_GQOT MT(MOD_LGUI, KC_QUOT) | |||
#define KC_MESC LT(_MACROS, KC_ESC) | |||
#define KC_INCL M(0) | |||
#define KC_PULL M(1) | |||
#define KC_PUSH M(2) | |||
#define KC_SCAP M(3) | |||
#define KC_SCOF M(4) | |||
#define KC_CAD LALT(LCTL(KC_DEL)) | |||
#define LONGPRESS_DELAY 150 | |||
//#define LAYER_TOGGLE_DELAY 300 | |||
// Fillers to make layering more clear | |||
#define _______ KC_TRNS | |||
#define XXXXXXX KC_NO | |||
#define KC_ KC_TRNS | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_QWERTY] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
LBRC, 1 ,SCTL,SPLT,SPFN, 5 , 6 ,GBRC,SPRT,SCTR, 0 ,RBRC, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
MESC, Q , W , E , R , T , Y , U , I , O , P ,QUOT, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
TAB , A , S , D , F , G , H , J , K , L ,SCLN,ENT , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
LSPO, Z , X , C , V , B , N , M ,COMM,DOT ,SLSH,RSPC, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
NMPD,BSPC, SPC ,SYMB | |||
// \------------------+----+----/ \---+----+----+--------------/ | |||
), | |||
[_CAPS] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
,UNDS, , , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , , , , ,COLN, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
SCOF, , , , , , , , , , ,SCOF, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , | |||
// \------------------+----+----/ \---+----+----+--------------/ | |||
), | |||
[_NUMPAD] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
, , , , , , , , , ,MINS, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, ,COLN, , , , , 7 , 8 , 9 ,ASTR, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, ,DOT , , , , , 4 , 5 , 6 ,PLUS, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , , 1 , 2 , 3 ,SLSH, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , 0 | |||
// \------------------+----+----/ \---+----+----+--------------/ | |||
), | |||
[_SYMBOLS] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
, , , , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
,EXLM, AT ,HASH,DLR ,PERC, CIRC,AMPR,ASTR,LPRN,RPRN,BSLS, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
F1 , F2 , F3 , F4 , F5 , F6 , TILD,EQL ,UNDS,LCBR,RCBR, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
F7 , F8 , F9 ,F10 ,F11 ,F12 , GRV ,PLUS,MINS,LBRC,RBRC, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
PIPE, , , | |||
// \------------------+----+----/ \---+----+----+--------------/ | |||
), | |||
[_MACROS] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
, , , , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , , ,INCL, , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , ,CAD , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
SCAP, , , , , , , ,PULL,PUSH, , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , | |||
// \------------------+----+----/ \---+----+----+--------------/ | |||
), | |||
[_NAV] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
, , , , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , ,PGUP, UP ,PGDN,PSCR, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , ,LEFT,DOWN,RGHT, , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
,DEL , , | |||
// \------------------+----+----/ \---+----+----+--------------/ | |||
), | |||
}; | |||
const uint16_t PROGMEM fn_actions[] = { | |||
}; | |||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
{ | |||
switch(id) { | |||
/* include some kind of library or header */ | |||
case 0: | |||
if (record->event.pressed) { | |||
SEND_STRING("#include <>"); | |||
return MACRO( T(LEFT), END); | |||
} | |||
break; | |||
case 1: | |||
if (record->event.pressed) { | |||
SEND_STRING("git pull"); | |||
return MACRO( T(ENT), END ); | |||
} | |||
break; | |||
case 2: | |||
if (record->event.pressed){ | |||
SEND_STRING("git push"); | |||
return MACRO( T(ENT), END ); | |||
} | |||
break; | |||
case 3: | |||
if (record->event.pressed){ | |||
layer_on(_CAPS); | |||
register_code(KC_CAPSLOCK); | |||
unregister_code(KC_CAPSLOCK); | |||
} | |||
break; | |||
case 4: | |||
if (record->event.pressed){ | |||
layer_off(_CAPS); | |||
register_code(KC_CAPSLOCK); | |||
unregister_code(KC_CAPSLOCK); | |||
} | |||
break; | |||
} | |||
return MACRO_NONE; | |||
}; | |||
void matrix_scan_user(void) { | |||
uint8_t layer = biton32(layer_state); | |||
switch (layer) { | |||
case _QWERTY: | |||
set_led_green; | |||
break; | |||
case _CAPS: | |||
set_led_white; | |||
break; | |||
case _NUMPAD: | |||
set_led_blue; | |||
break; | |||
case _SYMBOLS: | |||
set_led_red; | |||
break; | |||
case _NAV: | |||
set_led_magenta; | |||
break; | |||
case _MACROS: | |||
set_led_cyan; | |||
break; | |||
default: | |||
set_led_green; | |||
break; | |||
} | |||
}; |
@ -0,0 +1,164 @@ | |||
/* | |||
Copyright 2012 Jun Wako | |||
Copyright 2014 Jack Humbert | |||
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> | |||
#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" | |||
#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 | |||
/* matrix state(1:on, 0:off) */ | |||
static matrix_row_t matrix[MATRIX_ROWS]; | |||
__attribute__ ((weak)) | |||
void matrix_init_quantum(void) { | |||
matrix_init_kb(); | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_scan_quantum(void) { | |||
matrix_scan_kb(); | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_init_kb(void) { | |||
matrix_init_user(); | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_scan_kb(void) { | |||
matrix_scan_user(); | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_init_user(void) { | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_scan_user(void) { | |||
} | |||
inline | |||
uint8_t matrix_rows(void) { | |||
return MATRIX_ROWS; | |||
} | |||
inline | |||
uint8_t matrix_cols(void) { | |||
return MATRIX_COLS; | |||
} | |||
void matrix_init(void) { | |||
matrix_init_quantum(); | |||
} | |||
uint8_t matrix_scan(void) | |||
{ | |||
SERIAL_UART_INIT(); | |||
uint32_t timeout = 0; | |||
//the s character requests the RF slave to send the matrix | |||
SERIAL_UART_DATA = 's'; | |||
//trust the external keystates entirely, erase the last data | |||
uint8_t uart_data[14] = {0}; | |||
//there are 10 bytes corresponding to 10 columns, and an end byte | |||
for (uint8_t i = 0; i < 14; i++) { | |||
//wait for the serial data, timeout if it's been too long | |||
//this only happened in testing with a loose wire, but does no | |||
//harm to leave it in here | |||
while(!SERIAL_UART_RXD_PRESENT){ | |||
timeout++; | |||
if (timeout > 10000){ | |||
break; | |||
} | |||
} | |||
uart_data[i] = SERIAL_UART_DATA; | |||
} | |||
//check for the end packet, the key state bytes use the LSBs, so 0xE0 | |||
//will only show up here if the correct bytes were recieved | |||
if (uart_data[10] == 0xE0) | |||
{ | |||
//shifting and transferring the keystates to the QMK matrix variable | |||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||
matrix[i] = (uint16_t) uart_data[i*2] | (uint16_t) uart_data[i*2+1] << 6; | |||
} | |||
} | |||
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 | |||
matrix_row_t matrix_get_row(uint8_t row) | |||
{ | |||
return matrix[row]; | |||
} | |||
void matrix_print(void) | |||
{ | |||
print_matrix_header(); | |||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | |||
phex(row); print(": "); | |||
print_matrix_row(row); | |||
print("\n"); | |||
} | |||
} | |||
uint8_t matrix_key_count(void) | |||
{ | |||
uint8_t count = 0; | |||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||
count += matrix_bitpop(i); | |||
} | |||
return count; | |||
} |
@ -0,0 +1,19 @@ | |||
# Chimera Ergo | |||
![Chimera Ergo](https://imgur.com/AA6ycMQ.jpg) | |||
A split wireless 40% ergonomic keyboard | |||
Keyboard Maintainer: [William Wilson](https://github.com/GlenPickle) | |||
Hardware Supported: Chimera Ergo PCB, WaveShare core nRF51822 | |||
Hardware Availability: [Gerbers](https://github.com/GlenPickle/Chimera/tree/master/ergo/gerbers) | |||
Make example for this keyboard (after setting up your build environment): | |||
make chimera_ergo:default | |||
See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information. | |||
@ -0,0 +1,82 @@ | |||
OPT_DEFS += -DCHIMERA_ERGO_PROMICRO | |||
CHIMERA_ERGO_UPLOAD_COMMAND = while [ ! -r $(USB) ]; do sleep 1; done; \ | |||
avrdude -p $(MCU) -c avr109 -U flash:w:$(TARGET).hex -P $(USB) | |||
# # project specific files | |||
SRC = matrix.c | |||
# MCU name | |||
#MCU = at90usb1287 | |||
MCU = atmega32u4 | |||
# Processor frequency. | |||
# This will define a symbol, F_CPU, in all source code files equal to the | |||
# processor frequency in Hz. You can then use this symbol in your source code to | |||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done | |||
# automatically to create a 32-bit value in your source code. | |||
# | |||
# This will be an integer division of F_USB below, as it is sourced by | |||
# F_USB after it has run through any CPU prescalers. Note that this value | |||
# does not *change* the processor frequency - it should merely be updated to | |||
# reflect the processor speed set externally so that the code can use accurate | |||
# software delays. | |||
F_CPU = 16000000 | |||
# | |||
# LUFA specific | |||
# | |||
# Target architecture (see library "Board Types" documentation). | |||
ARCH = AVR8 | |||
# Input clock frequency. | |||
# This will define a symbol, F_USB, in all source code files equal to the | |||
# input clock frequency (before any prescaling is performed) in Hz. This value may | |||
# differ from F_CPU if prescaling is used on the latter, and is required as the | |||
# raw input clock is fed directly to the PLL sections of the AVR for high speed | |||
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' | |||
# at the end, this will be done automatically to create a 32-bit value in your | |||
# source code. | |||
# | |||
# If no clock division is performed on the input clock inside the AVR (via the | |||
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. | |||
F_USB = $(F_CPU) | |||
# Bootloader | |||
# This definition is optional, and if your keyboard supports multiple bootloaders of | |||
# different sizes, comment this out, and the correct address will be loaded | |||
# automatically (+60). See bootloader.mk for all options. | |||
BOOTLOADER = caterina | |||
# Interrupt driven control endpoint task(+60) | |||
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 | |||
# Build Options | |||
# comment out to disable the options. | |||
# | |||
#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 = yes # Console for debug(+400) | |||
COMMAND_ENABLE = yes # Commands for debug and configuration | |||
CUSTOM_MATRIX = yes # Remote matrix from the wireless bridge | |||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE | |||
# SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend | |||
NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA | |||
# BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality | |||
# MIDI_ENABLE = YES # MIDI controls | |||
UNICODE_ENABLE = YES # Unicode | |||
# BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID | |||
USB = /dev/ttyACM0 |
@ -0,0 +1,31 @@ | |||
#include "chimera_ls.h" | |||
void uart_init(void) { | |||
SERIAL_UART_INIT(); | |||
} | |||
void led_init(void) { | |||
DDRD |= (1<<1); | |||
PORTD |= (1<<1); | |||
DDRF |= (1<<4) | (1<<5); | |||
PORTF |= (1<<4) | (1<<5); | |||
} | |||
void matrix_init_kb(void) { | |||
// put your keyboard start-up code here | |||
// runs once when the firmware starts up | |||
matrix_init_user(); | |||
uart_init(); | |||
led_init(); | |||
} | |||
void matrix_scan_kb(void) { | |||
// put your looping keyboard code here | |||
// runs every cycle (a lot) | |||
matrix_scan_user(); | |||
} | |||
void led_set_kb(uint8_t usb_led) { | |||
} |
@ -0,0 +1,82 @@ | |||
#ifndef CHIMERA_LETS_SPLIT_H | |||
#define CHIMERA_LETS_SPLIT_H | |||
#include "quantum.h" | |||
#include "matrix.h" | |||
#include "backlight.h" | |||
#include <stddef.h> | |||
#define red_led_off PORTF |= (1<<5) | |||
#define red_led_on PORTF &= ~(1<<5) | |||
#define blu_led_off PORTF |= (1<<4) | |||
#define blu_led_on PORTF &= ~(1<<4) | |||
#define grn_led_off PORTD |= (1<<1) | |||
#define grn_led_on PORTD &= ~(1<<1) | |||
#define set_led_off red_led_off; grn_led_off; blu_led_off | |||
#define set_led_red red_led_on; grn_led_off; blu_led_off | |||
#define set_led_blue red_led_off; grn_led_off; blu_led_on | |||
#define set_led_green red_led_off; grn_led_on; blu_led_off | |||
#define set_led_yellow red_led_on; grn_led_on; blu_led_off | |||
#define set_led_magenta red_led_on; grn_led_off; blu_led_on | |||
#define set_led_cyan red_led_off; grn_led_on; blu_led_on | |||
#define set_led_white red_led_on; grn_led_on; blu_led_on | |||
/* | |||
#define LED_B 5 | |||
#define LED_R 6 | |||
#define LED_G 7 | |||
#define all_leds_off PORTF &= ~(1<<LED_B) & ~(1<<LED_R) & ~(1<<LED_G) | |||
#define red_led_on PORTF |= (1<<LED_R) | |||
#define red_led_off PORTF &= ~(1<<LED_R) | |||
#define grn_led_on PORTF |= (1<<LED_G) | |||
#define grn_led_off PORTF &= ~(1<<LED_G) | |||
#define blu_led_on PORTF |= (1<<LED_B) | |||
#define blu_led_off PORTF &= ~(1<<LED_B) | |||
#define set_led_off PORTF &= ~(1<<LED_B) & ~(1<<LED_R) & ~(1<<LED_G) | |||
#define set_led_red PORTF = PORTF & ~(1<<LED_B) & ~(1<<LED_G) | (1<<LED_R) | |||
#define set_led_blue PORTF = PORTF & ~(1<<LED_G) & ~(1<<LED_R) | (1<<LED_B) | |||
#define set_led_green PORTF = PORTF & ~(1<<LED_B) & ~(1<<LED_R) | (1<<LED_G) | |||
#define set_led_yellow PORTF = PORTF & ~(1<<LED_B) | (1<<LED_R) | (1<<LED_G) | |||
#define set_led_magenta PORTF = PORTF & ~(1<<LED_G) | (1<<LED_R) | (1<<LED_B) | |||
#define set_led_cyan PORTF = PORTF & ~(1<<LED_R) | (1<<LED_B) | (1<<LED_G) | |||
#define set_led_white PORTF |= (1<<LED_B) | (1<<LED_R) | (1<<LED_G) | |||
*/ | |||
// This a shortcut to help you visually see your layout. | |||
// The first section contains all of the arguements | |||
// The second converts the arguments into a two-dimensional array | |||
#define KC_KEYMAP( \ | |||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k10, k11, \ | |||
k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, \ | |||
k24, k25, k26, k27, k28, k29, k30, k31, k32, k33, k34, k35, \ | |||
k36, k37, k38, k39, k40, k41, k42, k43, k44, k45, k46, k47 \ | |||
) \ | |||
{ \ | |||
{ KC_##k43, KC_##k45, KC_##k34, KC_##k11, KC_##k23, KC_##k40, KC_##k38, KC_##k25, KC_##k00, KC_##k12 }, \ | |||
{ KC_##k31, KC_##k44, KC_##k46, KC_##k35, KC_##k22, KC_##k28, KC_##k39, KC_##k37, KC_##k24, KC_##k13 }, \ | |||
{ KC_##k30, KC_##k32, KC_##k33, KC_##k47, KC_##k09, KC_##k29, KC_##k27, KC_##k26, KC_##k36, KC_##k02 }, \ | |||
{ KC_##k19, KC_##k20, KC_##k21, KC_##k42, KC_##k18, KC_##k16, KC_##k15, KC_##k14, KC_##k41, KC_##k17 }, \ | |||
{ KC_##k06, KC_##k07, KC_##k08, KC_##k10, KC_NO, KC_##k05, KC_##k04, KC_##k03, KC_##k01, KC_NO }, \ | |||
} | |||
#define KEYMAP( \ | |||
k00, k01, k02, k03, k04, k05, k06, k07, k08, k09, k10, k11, \ | |||
k12, k13, k14, k15, k16, k17, k18, k19, k20, k21, k22, k23, \ | |||
k24, k25, k26, k27, k28, k29, k30, k31, k32, k33, k34, k35, \ | |||
k36, k37, k38, k39, k40, k41, k42, k43, k44, k45, k46, k47 \ | |||
) \ | |||
{ \ | |||
{ k43, k45, k34, k11, k23, k40, k38, k25, k00, k12 }, \ | |||
{ k31, k44, k46, k35, k22, k28, k39, k37, k24, k13 }, \ | |||
{ k30, k32, k33, k47, k09, k29, k27, k26, k36, k02 }, \ | |||
{ k19, k20, k21, k42, k18, k16, k15, k14, k41, k17 }, \ | |||
{ k06, k07, k08, k10, KC_NO, k05, k04, k03, k01, KC_NO }, \ | |||
} | |||
#endif |
@ -0,0 +1,87 @@ | |||
/* | |||
Copyright 2012 Jun Wako <wakojun@gmail.com> | |||
This program is free software: you can redistribute it and/or modify | |||
it under the terms of the GNU General Public License as published by | |||
the Free Software Foundation, either version 2 of the License, or | |||
(at your option) any later version. | |||
This program is distributed in the hope that it will be useful, | |||
but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
GNU General Public License for more details. | |||
You should have received a copy of the GNU General Public License | |||
along with this program. If not, see <http://www.gnu.org/licenses/>. | |||
*/ | |||
#ifndef CONFIG_H | |||
#define CONFIG_H | |||
#include "config_common.h" | |||
/* USB Device descriptor parameter */ | |||
#define VENDOR_ID 0xFEED | |||
#define PRODUCT_ID 0x6060 | |||
#define DEVICE_VER 0x0001 | |||
#define MANUFACTURER unknown | |||
#define PRODUCT Chimera Lets Split | |||
#define DESCRIPTION q.m.k. keyboard firmware for Chimera Lets Split | |||
/* key matrix size */ | |||
#define MATRIX_ROWS 5 | |||
#define MATRIX_COLS 12 | |||
/* define if matrix has ghost */ | |||
//#define MATRIX_HAS_GHOST | |||
/* number of backlight levels */ | |||
//#define BACKLIGHT_LEVELS 3 | |||
#define ONESHOT_TIMEOUT 500 | |||
/* key combination for command */ | |||
#define IS_COMMAND() ( \ | |||
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \ | |||
) | |||
/* | |||
* Feature disable options | |||
* These options are also useful to firmware size reduction. | |||
*/ | |||
#define PREVENT_STUCK_MODIFIERS | |||
/* disable debug print */ | |||
//#define NO_DEBUG | |||
/* disable print */ | |||
//#define NO_PRINT | |||
/* disable action features */ | |||
//#define NO_ACTION_LAYER | |||
//#define NO_ACTION_TAPPING | |||
//#define NO_ACTION_ONESHOT | |||
//#define NO_ACTION_MACRO | |||
//#define NO_ACTION_FUNCTION | |||
//UART settings for communication with the RF microcontroller | |||
#define SERIAL_UART_BAUD 1000000 | |||
#define SERIAL_UART_DATA UDR1 | |||
#define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1) | |||
#define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1)) | |||
#define SERIAL_UART_RXD_PRESENT (UCSR1A & _BV(RXC1)) | |||
#define SERIAL_UART_INIT() do { \ | |||
/* baud rate */ \ | |||
UBRR1L = SERIAL_UART_UBRR; \ | |||
/* baud rate */ \ | |||
UBRR1H = SERIAL_UART_UBRR >> 8; \ | |||
/* enable TX and RX */ \ | |||
UCSR1B = _BV(TXEN1) | _BV(RXEN1); \ | |||
/* 8-bit data */ \ | |||
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \ | |||
} while(0) | |||
#endif |
@ -0,0 +1,191 @@ | |||
// this is the style you want to emulate. | |||
// This is the canonical layout file for the Quantum project. If you want to add another keyboard, | |||
#include "chimera_ls.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. | |||
enum chimera_lets_split_layers | |||
{ | |||
_QWERTY, | |||
_CAPS, | |||
_NUMPAD, | |||
_SYMBOLS, | |||
_MACROS, | |||
_NAV | |||
}; | |||
#define KC_NMPD TG(_NUMPAD) | |||
#define KC_SYMB TG(_SYMBOLS) | |||
#define KC_SPFN LT(_NAV,KC_EQL) | |||
#define KC_SCTL MT(MOD_LCTL, KC_BSLS) | |||
#define KC_SCTR MT(MOD_LCTL, KC_RBRC) | |||
#define KC_SPLT MT(MOD_LALT, KC_MINS) | |||
#define KC_MESC LT(_MACROS, KC_ESC) | |||
#define KC_INCL M(0) | |||
#define KC_PULL M(1) | |||
#define KC_PUSH M(2) | |||
#define KC_SCAP M(3) | |||
#define KC_SCOF M(4) | |||
#define KC_CAD LALT(LCTL(KC_DEL)) | |||
#define LONGPRESS_DELAY 150 | |||
//#define LAYER_TOGGLE_DELAY 300 | |||
// Fillers to make layering more clear | |||
#define _______ KC_TRNS | |||
#define XXXXXXX KC_NO | |||
#define KC_ KC_TRNS | |||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { | |||
[_QWERTY] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
MESC, Q , W , E , R , T , Y , U , I , O , P ,BSPC, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
TAB , A , S , D , F , G , H , J , K , L ,SCLN, ENT, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
LSPO, Z , X , C , V , B , N , M ,COMM,DOT ,SLSH,RSPC, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
SCTL,SPFN,SPLT,AMPR,NMPD,SPC , SPC ,SYMB,ASTR,EXLM,LBRC,SCTR | |||
//`----+----+----+----+----+----' `----+----+----+----+----+----' | |||
), | |||
[_CAPS] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
, , , , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , , , , ,COLN, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, ,UNDS, , , , , , , , , | |||
//`----+----+----+----+----+----' `----+----+----+----+----+----' | |||
), | |||
[_NUMPAD] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
, , , , , , , 7 , 8 , 9 ,MINS,QUOT, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , , 4 , 5 , 6 ,PLUS, ENT, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
LSFT, , , , , , , 1 , 2 , 3 ,ASTR, EQL, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , ,BSPC, SPC , 0 , 0 , DOT,SLSH, | |||
//`----+----+----+----+----+----' `----+----+----+----+----+----' | |||
), | |||
[_SYMBOLS] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
,EXLM, AT ,HASH,DLR ,PERC, CIRC,AMPR,ASTR,LPRN,RPRN,QUOT, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
F1 , F2 , F3 , F4 , F5 , F6 , TILD,EQL ,UNDS,LCBR,RCBR,PIPE, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
F7 , F8 , F9 , F10, F11, F12, GRV ,PLUS,MINS,LBRC,RBRC,BSLS, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , NO ,BSPC, SPC , , , , , | |||
//`----+----+----+----+----+----' `----+----+----+----+----+----' | |||
), | |||
[_NAV] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
, , , , DEL,BSPC, ,HOME, UP , END, INS,PSCR, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , ,LSFT,LCTL, ENT, ,LEFT,DOWN,RGHT, DEL, , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , ,PGUP,PGDN, , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , ,DEL , , , , , , | |||
//`----+----+----+----+----+----' `----+----+----+----+----+----' | |||
), | |||
[_MACROS] = KC_KEYMAP( | |||
//,----+----+----+----+----+----. ,----+----+----+----+----+----. | |||
, , , , , , , ,INCL, , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , ,CAD , , , , , , , , , | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
SCAP, , , , , , , ,PULL,PUSH, ,SCAP, | |||
//|----+----+----+----+----+----| |----+----+----+----+----+----| | |||
, , , , , , , , , , , | |||
//`----+----+----+----+----+----' `----+----+----+----+----+----' | |||
), | |||
}; | |||
const uint16_t PROGMEM fn_actions[] = { | |||
}; | |||
const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) | |||
{ | |||
switch(id) { | |||
/* include some kind of library or header */ | |||
case 0: | |||
if (record->event.pressed) { | |||
SEND_STRING("#include <>"); | |||
return MACRO( T(LEFT), END); | |||
} | |||
break; | |||
case 1: | |||
if (record->event.pressed) { | |||
SEND_STRING("git pull"); | |||
return MACRO( T(ENT), END ); | |||
} | |||
break; | |||
case 2: | |||
if (record->event.pressed){ | |||
SEND_STRING("git push"); | |||
return MACRO( T(ENT), END ); | |||
} | |||
break; | |||
case 3: | |||
if (record->event.pressed){ | |||
layer_on(_CAPS); | |||
register_code(KC_CAPSLOCK); | |||
unregister_code(KC_CAPSLOCK); | |||
} | |||
break; | |||
case 4: | |||
if (record->event.pressed){ | |||
layer_off(_CAPS); | |||
register_code(KC_CAPSLOCK); | |||
unregister_code(KC_CAPSLOCK); | |||
} | |||
break; | |||
} | |||
return MACRO_NONE; | |||
}; | |||
void matrix_scan_user(void) { | |||
uint8_t layer = biton32(layer_state); | |||
switch (layer) { | |||
case _QWERTY: | |||
set_led_green; | |||
break; | |||
case _CAPS: | |||
set_led_white; | |||
break; | |||
case _NUMPAD: | |||
set_led_blue; | |||
break; | |||
case _SYMBOLS: | |||
set_led_red; | |||
break; | |||
case _NAV: | |||
set_led_magenta; | |||
break; | |||
case _MACROS: | |||
set_led_cyan; | |||
break; | |||
default: | |||
set_led_green; | |||
break; | |||
} | |||
}; |
@ -0,0 +1,168 @@ | |||
/* | |||
Copyright 2012 Jun Wako | |||
Copyright 2014 Jack Humbert | |||
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> | |||
#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" | |||
#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) | |||
#elif (MATRIX_COLS <= 64) | |||
# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF\n") | |||
# define print_matrix_row(row) print_bin_reverse64(matrix_get_row(row)) | |||
# define matrix_bitpop(i) bitpop64(matrix[i]) | |||
# define ROW_SHIFTER ((uint64_t)1) | |||
#endif | |||
/* matrix state(1:on, 0:off) */ | |||
static matrix_row_t matrix[MATRIX_ROWS]; | |||
__attribute__ ((weak)) | |||
void matrix_init_quantum(void) { | |||
matrix_init_kb(); | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_scan_quantum(void) { | |||
matrix_scan_kb(); | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_init_kb(void) { | |||
matrix_init_user(); | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_scan_kb(void) { | |||
matrix_scan_user(); | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_init_user(void) { | |||
} | |||
__attribute__ ((weak)) | |||
void matrix_scan_user(void) { | |||
} | |||
inline | |||
uint8_t matrix_rows(void) { | |||
return MATRIX_ROWS; | |||
} | |||
inline | |||
uint8_t matrix_cols(void) { | |||
return MATRIX_COLS; | |||
} | |||
void matrix_init(void) { | |||
matrix_init_quantum(); | |||
} | |||
uint8_t matrix_scan(void) | |||
{ | |||
SERIAL_UART_INIT(); | |||
uint32_t timeout = 0; | |||
//the s character requests the RF slave to send the matrix | |||
SERIAL_UART_DATA = 's'; | |||
//trust the external keystates entirely, erase the last data | |||
uint8_t uart_data[11] = {0}; | |||
//there are 10 bytes corresponding to 10 columns, and an end byte | |||
for (uint8_t i = 0; i < 11; i++) { | |||
//wait for the serial data, timeout if it's been too long | |||
//this only happened in testing with a loose wire, but does no | |||
//harm to leave it in here | |||
while(!SERIAL_UART_RXD_PRESENT){ | |||
timeout++; | |||
if (timeout > 10000){ | |||
break; | |||
} | |||
} | |||
uart_data[i] = SERIAL_UART_DATA; | |||
} | |||
//check for the end packet, the key state bytes use the LSBs, so 0xE0 | |||
//will only show up here if the correct bytes were recieved | |||
if (uart_data[10] == 0xE0) | |||
{ | |||
//shifting and transferring the keystates to the QMK matrix variable | |||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||
matrix[i] = (uint16_t) uart_data[i*2] | (uint16_t) uart_data[i*2+1] << 5; | |||
} | |||
} | |||
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 | |||
matrix_row_t matrix_get_row(uint8_t row) | |||
{ | |||
return matrix[row]; | |||
} | |||
void matrix_print(void) | |||
{ | |||
print_matrix_header(); | |||
for (uint8_t row = 0; row < MATRIX_ROWS; row++) { | |||
phex(row); print(": "); | |||
print_matrix_row(row); | |||
print("\n"); | |||
} | |||
} | |||
uint8_t matrix_key_count(void) | |||
{ | |||
uint8_t count = 0; | |||
for (uint8_t i = 0; i < MATRIX_ROWS; i++) { | |||
count += matrix_bitpop(i); | |||
} | |||
return count; | |||
} |
@ -0,0 +1,19 @@ | |||
# Chimera LS | |||
![Chimera LS](https://imgur.com/FOGlO4M.jpg) | |||
A wireless version of the let's split: a split 40% ortholinear keyboard | |||
Keyboard Maintainer: [William Wilson](https://github.com/GlenPickle) | |||
Hardware Supported: Chimera LS PCB, WaveShare core nRF51822 | |||
Hardware Availability: [Gerbers](https://github.com/GlenPickle/Chimera/tree/master/ls/gerbers) | |||
Make example for this keyboard (after setting up your build environment): | |||
make chimera_ls:default | |||
See [build environment setup](https://docs.qmk.fm/build_environment_setup.html) then the [make instructions](https://docs.qmk.fm/make_instructions.html) for more information. | |||
@ -0,0 +1,82 @@ | |||
OPT_DEFS += -DCHIMERA_LS_PROMICRO | |||
CHIMERA_LS_UPLOAD_COMMAND = while [ ! -r $(USB) ]; do sleep 1; done; \ | |||
avrdude -p $(MCU) -c avr109 -U flash:w:$(TARGET).hex -P $(USB) | |||
# # project specific files | |||
SRC = matrix.c | |||
# MCU name | |||
#MCU = at90usb1287 | |||
MCU = atmega32u4 | |||
# Processor frequency. | |||
# This will define a symbol, F_CPU, in all source code files equal to the | |||
# processor frequency in Hz. You can then use this symbol in your source code to | |||
# calculate timings. Do NOT tack on a 'UL' at the end, this will be done | |||
# automatically to create a 32-bit value in your source code. | |||
# | |||
# This will be an integer division of F_USB below, as it is sourced by | |||
# F_USB after it has run through any CPU prescalers. Note that this value | |||
# does not *change* the processor frequency - it should merely be updated to | |||
# reflect the processor speed set externally so that the code can use accurate | |||
# software delays. | |||
F_CPU = 16000000 | |||
# | |||
# LUFA specific | |||
# | |||
# Target architecture (see library "Board Types" documentation). | |||
ARCH = AVR8 | |||
# Input clock frequency. | |||
# This will define a symbol, F_USB, in all source code files equal to the | |||
# input clock frequency (before any prescaling is performed) in Hz. This value may | |||
# differ from F_CPU if prescaling is used on the latter, and is required as the | |||
# raw input clock is fed directly to the PLL sections of the AVR for high speed | |||
# clock generation for the USB and other AVR subsections. Do NOT tack on a 'UL' | |||
# at the end, this will be done automatically to create a 32-bit value in your | |||
# source code. | |||
# | |||
# If no clock division is performed on the input clock inside the AVR (via the | |||
# CPU clock adjust registers or the clock division fuses), this will be equal to F_CPU. | |||
F_USB = $(F_CPU) | |||
# Bootloader | |||
# This definition is optional, and if your keyboard supports multiple bootloaders of | |||
# different sizes, comment this out, and the correct address will be loaded | |||
# automatically (+60). See bootloader.mk for all options. | |||
BOOTLOADER = caterina | |||
# Interrupt driven control endpoint task(+60) | |||
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 | |||
# Build Options | |||
# comment out to disable the options. | |||
# | |||
#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 = yes # Console for debug(+400) | |||
COMMAND_ENABLE = yes # Commands for debug and configuration | |||
CUSTOM_MATRIX = yes # Remote matrix from the wireless bridge | |||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE | |||
# SLEEP_LED_ENABLE = yes # Breathing sleep LED during USB suspend | |||
NKRO_ENABLE = yes # USB Nkey Rollover - not yet supported in LUFA | |||
# BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality | |||
# MIDI_ENABLE = YES # MIDI controls | |||
UNICODE_ENABLE = YES # Unicode | |||
# BLUETOOTH_ENABLE = yes # Enable Bluetooth with the Adafruit EZ-Key HID | |||
USB = /dev/ttyACM0 |