Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66e40529aa | ||
|
|
80ccbc7b54 | ||
|
|
644efe48bf | ||
|
|
10d287d1aa | ||
|
|
eb89a372ec | ||
|
|
1c6b9323b2 | ||
|
|
4ad37331d3 | ||
|
|
4674664c4a | ||
|
|
32446eeeb6 | ||
|
|
1feb42a108 | ||
|
|
7d08e48c50 | ||
|
|
d1481172bc |
No files matched your search
@@ -0,0 +1 @@
|
|||||||
|
#include "bfo9000.h"
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef BFO9000_H
|
||||||
|
#define BFO9000_H
|
||||||
|
|
||||||
|
#include "quantum.h"
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
#include <stddef.h>
|
||||||
|
#ifdef __AVR__
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define LAYOUT( \
|
||||||
|
L00, L01, L02, L03, L04, L05, L06, L07, L08, R00, R01, R02, R03, R04, R05, R06, R07, R08, \
|
||||||
|
L10, L11, L12, L13, L14, L15, L16, L17, L18, R10, R11, R12, R13, R14, R15, R16, R17, R18, \
|
||||||
|
L20, L21, L22, L23, L24, L25, L26, L27, L28, R20, R21, R22, R23, R24, R25, R26, R27, R28, \
|
||||||
|
L30, L31, L32, L33, L34, L35, L36, L37, L38, R30, R31, R32, R33, R34, R35, R36, R37, R38, \
|
||||||
|
L40, L41, L42, L43, L44, L45, L46, L47, L48, R40, R41, R42, R43, R44, R45, R46, R47, R48, \
|
||||||
|
L50, L51, L52, L53, L54, L55, L56, L57, L58, R50, R51, R52, R53, R54, R55, R56, R57, R58 \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
{ L00, L01, L02, L03, L04, L05, L06, L07, L08 }, \
|
||||||
|
{ L10, L11, L12, L13, L14, L15, L16, L17, L18 }, \
|
||||||
|
{ L20, L21, L22, L23, L24, L25, L26, L27, L28 }, \
|
||||||
|
{ L30, L31, L32, L33, L34, L35, L36, L37, L38 }, \
|
||||||
|
{ L40, L41, L42, L43, L44, L45, L46, L47, L48 }, \
|
||||||
|
{ L50, L51, L52, L53, L54, L55, L56, L57, L58 }, \
|
||||||
|
{ R00, R01, R02, R03, R04, R05, R06, R07, R08 }, \
|
||||||
|
{ R10, R11, R12, R13, R14, R15, R16, R17, R18 }, \
|
||||||
|
{ R20, R21, R22, R23, R24, R25, R26, R27, R28 }, \
|
||||||
|
{ R30, R31, R32, R33, R34, R35, R36, R37, R38 }, \
|
||||||
|
{ R40, R41, R42, R43, R44, R45, R46, R47, R48 }, \
|
||||||
|
{ R50, R51, R52, R53, R54, R55, R56, R57, R58 } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <[email protected]>
|
||||||
|
Copyright 2015 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_H
|
||||||
|
#define CONFIG_H
|
||||||
|
|
||||||
|
#include "config_common.h"
|
||||||
|
|
||||||
|
/* USB Device descriptor parameter */
|
||||||
|
#define VENDOR_ID 0xCEEB
|
||||||
|
#define PRODUCT_ID 0x1169
|
||||||
|
#define DEVICE_VER 0x0100
|
||||||
|
#define MANUFACTURER Keebio
|
||||||
|
#define PRODUCT BFO-9000
|
||||||
|
#define DESCRIPTION Really big split ortholinear keyboard
|
||||||
|
|
||||||
|
/* key matrix size */
|
||||||
|
// Rows are doubled-up
|
||||||
|
#define MATRIX_ROWS 12
|
||||||
|
#define MATRIX_COLS 9
|
||||||
|
|
||||||
|
// wiring of each half
|
||||||
|
#define MATRIX_ROW_PINS { D3, D2, D4, C6, D7, E6 }
|
||||||
|
#define MATRIX_COL_PINS { B5, B6, B2, B3, B1, F7, F6, F5, F4 }
|
||||||
|
|
||||||
|
/* Set 0 if debouncing isn't needed */
|
||||||
|
#define DEBOUNCING_DELAY 5
|
||||||
|
|
||||||
|
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
|
||||||
|
#define LOCKING_SUPPORT_ENABLE
|
||||||
|
/* Locking resynchronize hack */
|
||||||
|
#define LOCKING_RESYNC_ENABLE
|
||||||
|
|
||||||
|
/* key combination for command */
|
||||||
|
#define IS_COMMAND() ( \
|
||||||
|
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
/* ws2812 RGB LED */
|
||||||
|
#define RGB_DI_PIN B4
|
||||||
|
#define RGBLIGHT_TIMER
|
||||||
|
#define RGBLED_NUM 20 // Number of LEDs
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Feature disable options
|
||||||
|
* These options are also useful to firmware size reduction.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,162 @@
|
|||||||
|
#include <util/twi.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <util/twi.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "i2c.h"
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
|
||||||
|
// Limits the amount of we wait for any one i2c transaction.
|
||||||
|
// Since were running SCL line 100kHz (=> 10μs/bit), and each transactions is
|
||||||
|
// 9 bits, a single transaction will take around 90μs to complete.
|
||||||
|
//
|
||||||
|
// (F_CPU/SCL_CLOCK) => # of μC cycles to transfer a bit
|
||||||
|
// poll loop takes at least 8 clock cycles to execute
|
||||||
|
#define I2C_LOOP_TIMEOUT (9+1)*(F_CPU/SCL_CLOCK)/8
|
||||||
|
|
||||||
|
#define BUFFER_POS_INC() (slave_buffer_pos = (slave_buffer_pos+1)%SLAVE_BUFFER_SIZE)
|
||||||
|
|
||||||
|
volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
static volatile uint8_t slave_buffer_pos;
|
||||||
|
static volatile bool slave_has_register_set = false;
|
||||||
|
|
||||||
|
// Wait for an i2c operation to finish
|
||||||
|
inline static
|
||||||
|
void i2c_delay(void) {
|
||||||
|
uint16_t lim = 0;
|
||||||
|
while(!(TWCR & (1<<TWINT)) && lim < I2C_LOOP_TIMEOUT)
|
||||||
|
lim++;
|
||||||
|
|
||||||
|
// easier way, but will wait slightly longer
|
||||||
|
// _delay_us(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup twi to run at 100kHz
|
||||||
|
void i2c_master_init(void) {
|
||||||
|
// no prescaler
|
||||||
|
TWSR = 0;
|
||||||
|
// Set TWI clock frequency to SCL_CLOCK. Need TWBR>10.
|
||||||
|
// Check datasheets for more info.
|
||||||
|
TWBR = ((F_CPU/SCL_CLOCK)-16)/2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start a transaction with the given i2c slave address. The direction of the
|
||||||
|
// transfer is set with I2C_READ and I2C_WRITE.
|
||||||
|
// returns: 0 => success
|
||||||
|
// 1 => error
|
||||||
|
uint8_t i2c_master_start(uint8_t address) {
|
||||||
|
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);
|
||||||
|
|
||||||
|
i2c_delay();
|
||||||
|
|
||||||
|
// check that we started successfully
|
||||||
|
if ( (TW_STATUS != TW_START) && (TW_STATUS != TW_REP_START))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
TWDR = address;
|
||||||
|
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||||
|
|
||||||
|
i2c_delay();
|
||||||
|
|
||||||
|
if ( (TW_STATUS != TW_MT_SLA_ACK) && (TW_STATUS != TW_MR_SLA_ACK) )
|
||||||
|
return 1; // slave did not acknowledge
|
||||||
|
else
|
||||||
|
return 0; // success
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Finish the i2c transaction.
|
||||||
|
void i2c_master_stop(void) {
|
||||||
|
TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
|
||||||
|
|
||||||
|
uint16_t lim = 0;
|
||||||
|
while(!(TWCR & (1<<TWSTO)) && lim < I2C_LOOP_TIMEOUT)
|
||||||
|
lim++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write one byte to the i2c slave.
|
||||||
|
// returns 0 => slave ACK
|
||||||
|
// 1 => slave NACK
|
||||||
|
uint8_t i2c_master_write(uint8_t data) {
|
||||||
|
TWDR = data;
|
||||||
|
TWCR = (1<<TWINT) | (1<<TWEN);
|
||||||
|
|
||||||
|
i2c_delay();
|
||||||
|
|
||||||
|
// check if the slave acknowledged us
|
||||||
|
return (TW_STATUS == TW_MT_DATA_ACK) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read one byte from the i2c slave. If ack=1 the slave is acknowledged,
|
||||||
|
// if ack=0 the acknowledge bit is not set.
|
||||||
|
// returns: byte read from i2c device
|
||||||
|
uint8_t i2c_master_read(int ack) {
|
||||||
|
TWCR = (1<<TWINT) | (1<<TWEN) | (ack<<TWEA);
|
||||||
|
|
||||||
|
i2c_delay();
|
||||||
|
return TWDR;
|
||||||
|
}
|
||||||
|
|
||||||
|
void i2c_reset_state(void) {
|
||||||
|
TWCR = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void i2c_slave_init(uint8_t address) {
|
||||||
|
TWAR = address << 0; // slave i2c address
|
||||||
|
// TWEN - twi enable
|
||||||
|
// TWEA - enable address acknowledgement
|
||||||
|
// TWINT - twi interrupt flag
|
||||||
|
// TWIE - enable the twi interrupt
|
||||||
|
TWCR = (1<<TWIE) | (1<<TWEA) | (1<<TWINT) | (1<<TWEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
ISR(TWI_vect);
|
||||||
|
|
||||||
|
ISR(TWI_vect) {
|
||||||
|
uint8_t ack = 1;
|
||||||
|
switch(TW_STATUS) {
|
||||||
|
case TW_SR_SLA_ACK:
|
||||||
|
// this device has been addressed as a slave receiver
|
||||||
|
slave_has_register_set = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TW_SR_DATA_ACK:
|
||||||
|
// this device has received data as a slave receiver
|
||||||
|
// The first byte that we receive in this transaction sets the location
|
||||||
|
// of the read/write location of the slaves memory that it exposes over
|
||||||
|
// i2c. After that, bytes will be written at slave_buffer_pos, incrementing
|
||||||
|
// slave_buffer_pos after each write.
|
||||||
|
if(!slave_has_register_set) {
|
||||||
|
slave_buffer_pos = TWDR;
|
||||||
|
// don't acknowledge the master if this memory loctaion is out of bounds
|
||||||
|
if ( slave_buffer_pos >= SLAVE_BUFFER_SIZE ) {
|
||||||
|
ack = 0;
|
||||||
|
slave_buffer_pos = 0;
|
||||||
|
}
|
||||||
|
slave_has_register_set = true;
|
||||||
|
} else {
|
||||||
|
i2c_slave_buffer[slave_buffer_pos] = TWDR;
|
||||||
|
BUFFER_POS_INC();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TW_ST_SLA_ACK:
|
||||||
|
case TW_ST_DATA_ACK:
|
||||||
|
// master has addressed this device as a slave transmitter and is
|
||||||
|
// requesting data.
|
||||||
|
TWDR = i2c_slave_buffer[slave_buffer_pos];
|
||||||
|
BUFFER_POS_INC();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TW_BUS_ERROR: // something went wrong, reset twi state
|
||||||
|
TWCR = 0;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Reset everything, so we are ready for the next TWI interrupt
|
||||||
|
TWCR |= (1<<TWIE) | (1<<TWINT) | (ack<<TWEA) | (1<<TWEN);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
#ifndef I2C_H
|
||||||
|
#define I2C_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#ifndef F_CPU
|
||||||
|
#define F_CPU 16000000UL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define I2C_READ 1
|
||||||
|
#define I2C_WRITE 0
|
||||||
|
|
||||||
|
#define I2C_ACK 1
|
||||||
|
#define I2C_NACK 0
|
||||||
|
|
||||||
|
#define SLAVE_BUFFER_SIZE 0x10
|
||||||
|
|
||||||
|
// i2c SCL clock frequency
|
||||||
|
#define SCL_CLOCK 400000L
|
||||||
|
|
||||||
|
extern volatile uint8_t i2c_slave_buffer[SLAVE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
void i2c_master_init(void);
|
||||||
|
uint8_t i2c_master_start(uint8_t address);
|
||||||
|
void i2c_master_stop(void);
|
||||||
|
uint8_t i2c_master_write(uint8_t data);
|
||||||
|
uint8_t i2c_master_read(int);
|
||||||
|
void i2c_reset_state(void);
|
||||||
|
void i2c_slave_init(uint8_t address);
|
||||||
|
|
||||||
|
|
||||||
|
static inline unsigned char i2c_start_read(unsigned char addr) {
|
||||||
|
return i2c_master_start((addr << 1) | I2C_READ);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline unsigned char i2c_start_write(unsigned char addr) {
|
||||||
|
return i2c_master_start((addr << 1) | I2C_WRITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// from SSD1306 scrips
|
||||||
|
extern unsigned char i2c_rep_start(unsigned char addr);
|
||||||
|
extern void i2c_start_wait(unsigned char addr);
|
||||||
|
extern unsigned char i2c_readAck(void);
|
||||||
|
extern unsigned char i2c_readNak(void);
|
||||||
|
extern unsigned char i2c_read(unsigned char ack);
|
||||||
|
|
||||||
|
#define i2c_read(ack) (ack) ? i2c_readAck() : i2c_readNak();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
This is the c configuration file for the keymap
|
||||||
|
|
||||||
|
Copyright 2012 Jun Wako <[email protected]>
|
||||||
|
Copyright 2015 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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CONFIG_USER_H
|
||||||
|
#define CONFIG_USER_H
|
||||||
|
|
||||||
|
#include "config_common.h"
|
||||||
|
|
||||||
|
/* Use I2C or Serial, not both */
|
||||||
|
|
||||||
|
#define USE_SERIAL
|
||||||
|
// #define USE_I2C
|
||||||
|
|
||||||
|
/* Select hand configuration */
|
||||||
|
|
||||||
|
#define MASTER_LEFT
|
||||||
|
// #define MASTER_RIGHT
|
||||||
|
// #define EE_HANDS
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#include QMK_KEYBOARD_H
|
||||||
|
|
||||||
|
#define _BASE 0
|
||||||
|
|
||||||
|
// Fillers to make layering more clear
|
||||||
|
#define _______ KC_TRNS
|
||||||
|
#define XXXXXXX KC_NO
|
||||||
|
|
||||||
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
|
|
||||||
|
[_BASE] = LAYOUT( \
|
||||||
|
KC_ESC, KC_VOLU, KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, KC_DEL, \
|
||||||
|
KC_HOME, KC_VOLD, KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, KC_EQL, KC_BSPC, \
|
||||||
|
KC_END, KC_TAB, KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC, KC_BSLS, \
|
||||||
|
KC_PGUP, KC_CAPS, KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, KC_ENT, \
|
||||||
|
KC_PGDN, KC_UP, KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, XXXXXXX, \
|
||||||
|
KC_LEFT, KC_DOWN, KC_RGHT, KC_LCTL, KC_LALT, KC_LGUI, KC_SPC, KC_SPC, KC_ENT, KC_BSPC, KC_SPC, KC_SPC, KC_RGUI, KC_RALT, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT \
|
||||||
|
)
|
||||||
|
};
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <[email protected]>
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* scan matrix
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#ifdef USE_I2C
|
||||||
|
// provides memcpy for copying TWI slave buffer
|
||||||
|
// #include <string.h>
|
||||||
|
#endif
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include "print.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
#include "split_util.h"
|
||||||
|
#include "pro_micro.h"
|
||||||
|
#include "config.h"
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
# include "i2c.h"
|
||||||
|
#else // USE_SERIAL
|
||||||
|
# include "serial.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef DEBOUNCE
|
||||||
|
# define DEBOUNCE 5
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ERROR_DISCONNECT_COUNT 5
|
||||||
|
|
||||||
|
static uint8_t debouncing = DEBOUNCE;
|
||||||
|
static const int ROWS_PER_HAND = MATRIX_ROWS/2;
|
||||||
|
static uint8_t error_count = 0;
|
||||||
|
|
||||||
|
static const uint8_t row_pins[MATRIX_ROWS] = MATRIX_ROW_PINS;
|
||||||
|
static const uint8_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 read_cols(void);
|
||||||
|
static void init_cols(void);
|
||||||
|
static void unselect_rows(void);
|
||||||
|
static void select_row(uint8_t row);
|
||||||
|
|
||||||
|
|
||||||
|
__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)
|
||||||
|
{
|
||||||
|
debug_enable = true;
|
||||||
|
debug_matrix = true;
|
||||||
|
debug_mouse = true;
|
||||||
|
// initialize row and col
|
||||||
|
unselect_rows();
|
||||||
|
init_cols();
|
||||||
|
|
||||||
|
TX_RX_LED_INIT;
|
||||||
|
|
||||||
|
// initialize matrix state: all keys off
|
||||||
|
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||||
|
matrix[i] = 0;
|
||||||
|
matrix_debouncing[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix_init_quantum();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t _matrix_scan(void)
|
||||||
|
{
|
||||||
|
// Right hand is stored after the left in the matrix so, we need to offset it
|
||||||
|
int offset = isLeftHand ? 0 : (ROWS_PER_HAND);
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
|
||||||
|
select_row(i);
|
||||||
|
_delay_us(30); // without this wait read unstable value.
|
||||||
|
matrix_row_t cols = read_cols();
|
||||||
|
if (matrix_debouncing[i+offset] != cols) {
|
||||||
|
matrix_debouncing[i+offset] = cols;
|
||||||
|
debouncing = DEBOUNCE;
|
||||||
|
}
|
||||||
|
unselect_rows();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debouncing) {
|
||||||
|
if (--debouncing) {
|
||||||
|
_delay_ms(1);
|
||||||
|
} else {
|
||||||
|
for (uint8_t i = 0; i < ROWS_PER_HAND; i++) {
|
||||||
|
matrix[i+offset] = matrix_debouncing[i+offset];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
|
||||||
|
// Get rows from other half over i2c
|
||||||
|
int i2c_transaction(void) {
|
||||||
|
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||||
|
|
||||||
|
int err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_WRITE);
|
||||||
|
if (err) goto i2c_error;
|
||||||
|
|
||||||
|
// start of matrix stored at 0x00
|
||||||
|
err = i2c_master_write(0x00);
|
||||||
|
if (err) goto i2c_error;
|
||||||
|
|
||||||
|
// Start read
|
||||||
|
err = i2c_master_start(SLAVE_I2C_ADDRESS + I2C_READ);
|
||||||
|
if (err) goto i2c_error;
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
/*
|
||||||
|
// read from TWI byte-by-byte into matrix_row_t memory space
|
||||||
|
size_t i;
|
||||||
|
for (i = 0; i < SLAVE_BUFFER_SIZE-1; ++i) {
|
||||||
|
*((uint8_t*)&matrix[slaveOffset]+i) = i2c_master_read(I2C_ACK);
|
||||||
|
}
|
||||||
|
// last byte to be read / end of chunk
|
||||||
|
*((uint8_t*)&matrix[slaveOffset]+i) = i2c_master_read(I2C_NACK);
|
||||||
|
*/
|
||||||
|
|
||||||
|
// kludge for column #9: unpack bits for keys (2,9) and (3,9) from (1,7) and (1,8)
|
||||||
|
// i2c_master_read(I2C_ACK);
|
||||||
|
matrix[slaveOffset+0] = i2c_master_read(I2C_ACK);
|
||||||
|
// i2c_master_read(I2C_ACK);
|
||||||
|
matrix[slaveOffset+1] = (matrix_row_t)i2c_master_read(I2C_ACK)\
|
||||||
|
| (matrix[slaveOffset+0]&0x40U)<<2;
|
||||||
|
// i2c_master_read(I2C_ACK);
|
||||||
|
matrix[slaveOffset+2] = (matrix_row_t)i2c_master_read(I2C_NACK)\
|
||||||
|
| (matrix[slaveOffset+0]&0x80U)<<1;
|
||||||
|
// clear highest two bits on row 1, where the col9 bits were transported
|
||||||
|
matrix[slaveOffset+0] &= 0x3F;
|
||||||
|
|
||||||
|
i2c_master_stop();
|
||||||
|
} else {
|
||||||
|
i2c_error: // the cable is disconnected, or something else went wrong
|
||||||
|
i2c_reset_state();
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else // USE_SERIAL
|
||||||
|
|
||||||
|
int serial_transaction(void) {
|
||||||
|
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||||
|
|
||||||
|
if (serial_update_buffers()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||||
|
matrix[slaveOffset+i] = serial_slave_buffer[i];
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
uint8_t matrix_scan(void)
|
||||||
|
{
|
||||||
|
int ret = _matrix_scan();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
if( i2c_transaction() ) {
|
||||||
|
#else // USE_SERIAL
|
||||||
|
if( serial_transaction() ) {
|
||||||
|
#endif
|
||||||
|
// turn on the indicator led when halves are disconnected
|
||||||
|
TXLED1;
|
||||||
|
|
||||||
|
error_count++;
|
||||||
|
|
||||||
|
if (error_count > ERROR_DISCONNECT_COUNT) {
|
||||||
|
// reset other half if disconnected
|
||||||
|
int slaveOffset = (isLeftHand) ? (ROWS_PER_HAND) : 0;
|
||||||
|
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||||
|
matrix[slaveOffset+i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// turn off the indicator led on no error
|
||||||
|
TXLED0;
|
||||||
|
error_count = 0;
|
||||||
|
}
|
||||||
|
matrix_scan_quantum();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_slave_scan(void) {
|
||||||
|
_matrix_scan();
|
||||||
|
|
||||||
|
int offset = (isLeftHand) ? 0 : ROWS_PER_HAND;
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
// SLAVE_BUFFER_SIZE is from i2c.h
|
||||||
|
// (MATRIX_ROWS/2*sizeof(matrix_row_t))
|
||||||
|
// memcpy((void*)i2c_slave_buffer, (const void*)&matrix[offset], (ROWS_PER_HAND*sizeof(matrix_row_t)));
|
||||||
|
|
||||||
|
// kludge for column #9: put bits for keys (2,9) and (3,9) into (1,7) and (1,8)
|
||||||
|
i2c_slave_buffer[0] = (uint8_t)(matrix[offset+0])\
|
||||||
|
| (matrix[offset+1]&0x100U)>>2\
|
||||||
|
| (matrix[offset+2]&0x100U)>>1;
|
||||||
|
i2c_slave_buffer[1] = (uint8_t)(matrix[offset+1]);
|
||||||
|
i2c_slave_buffer[2] = (uint8_t)(matrix[offset+2]);
|
||||||
|
// note: looks like a possible operator-precedence bug here, in last version?
|
||||||
|
/*
|
||||||
|
i2c_slave_buffer[1] = (uint8_t)matrix[offset+0];
|
||||||
|
i2c_slave_buffer[2] = (uint8_t)(matrix[offset+1]>>8);
|
||||||
|
i2c_slave_buffer[3] = (uint8_t)(matrix[offset+1]>>8);
|
||||||
|
i2c_slave_buffer[4] = (uint8_t)(matrix[offset+2]>>8);
|
||||||
|
i2c_slave_buffer[5] = (uint8_t)matrix[offset+2];
|
||||||
|
*/
|
||||||
|
#else // USE_SERIAL
|
||||||
|
for (int i = 0; i < ROWS_PER_HAND; ++i) {
|
||||||
|
serial_slave_buffer[i] = matrix[offset+i];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matrix_is_modified(void)
|
||||||
|
{
|
||||||
|
if (debouncing) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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("\nr/c 0123456789ABCDEF\n");
|
||||||
|
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||||
|
phex(row); print(": ");
|
||||||
|
pbin_reverse16(matrix_get_row(row));
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t matrix_key_count(void)
|
||||||
|
{
|
||||||
|
uint8_t count = 0;
|
||||||
|
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||||
|
count += bitpop16(matrix[i]);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init_cols(void)
|
||||||
|
{
|
||||||
|
for(int x = 0; x < MATRIX_COLS; x++) {
|
||||||
|
_SFR_IO8((col_pins[x] >> 4) + 1) &= ~_BV(col_pins[x] & 0xF);
|
||||||
|
_SFR_IO8((col_pins[x] >> 4) + 2) |= _BV(col_pins[x] & 0xF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static matrix_row_t read_cols(void)
|
||||||
|
{
|
||||||
|
matrix_row_t result = 0;
|
||||||
|
for(int x = 0; x < MATRIX_COLS; x++) {
|
||||||
|
result |= (_SFR_IO8(col_pins[x] >> 4) & _BV(col_pins[x] & 0xF)) ? 0 : (1 << x);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unselect_rows(void)
|
||||||
|
{
|
||||||
|
for(int x = 0; x < ROWS_PER_HAND; x++) {
|
||||||
|
_SFR_IO8((row_pins[x] >> 4) + 1) &= ~_BV(row_pins[x] & 0xF);
|
||||||
|
_SFR_IO8((row_pins[x] >> 4) + 2) |= _BV(row_pins[x] & 0xF);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void select_row(uint8_t row)
|
||||||
|
{
|
||||||
|
_SFR_IO8((row_pins[row] >> 4) + 1) |= _BV(row_pins[row] & 0xF);
|
||||||
|
_SFR_IO8((row_pins[row] >> 4) + 2) &= ~_BV(row_pins[row] & 0xF);
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
BFO-9000
|
||||||
|
========
|
||||||
|
|
||||||
|
A split full-size ortholinear keyboard made and sold by Keebio. Each half is a 6x9 arrangement, with breakable pieces to allow the number of rows to be customized between 4 to 6, and the number of columns to be between 7 to 9. [More info at Keebio](https://keeb.io).
|
||||||
|
|
||||||
|
Keyboard Maintainer: [Bakingpy/nooges](https://github.com/nooges)
|
||||||
|
Hardware Supported: Pro Micro
|
||||||
|
Hardware Availability: [Keebio](https://keeb.io)
|
||||||
|
|
||||||
|
Make example for this keyboard (after setting up your build environment):
|
||||||
|
|
||||||
|
make bfo9000:default
|
||||||
|
|
||||||
|
Example of flashing this keyboard:
|
||||||
|
|
||||||
|
make bfo9000:default:avrdude
|
||||||
|
|
||||||
|
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,70 @@
|
|||||||
|
SRC += matrix.c \
|
||||||
|
i2c.c \
|
||||||
|
split_util.c \
|
||||||
|
serial.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
|
||||||
|
|
||||||
|
# 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 = no # 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 = no # Nkey Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||||
|
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality
|
||||||
|
MIDI_ENABLE = no # MIDI controls
|
||||||
|
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.
|
||||||
|
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||||
|
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||||
|
|
||||||
|
CUSTOM_MATRIX = yes
|
||||||
@@ -0,0 +1,230 @@
|
|||||||
|
/*
|
||||||
|
* WARNING: be careful changing this code, it is very timing dependent
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef F_CPU
|
||||||
|
#define F_CPU 16000000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "serial.h"
|
||||||
|
|
||||||
|
#ifdef USE_SERIAL
|
||||||
|
|
||||||
|
// Serial pulse period in microseconds. Its probably a bad idea to lower this
|
||||||
|
// value.
|
||||||
|
#define SERIAL_DELAY 24
|
||||||
|
|
||||||
|
matrix_row_t volatile serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH] = {0};
|
||||||
|
matrix_row_t volatile serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH] = {0};
|
||||||
|
|
||||||
|
#define ROW_MASK (((matrix_row_t)0-1)>>(8*sizeof(matrix_row_t)-MATRIX_COLS))
|
||||||
|
|
||||||
|
#define SLAVE_DATA_CORRUPT (1<<0)
|
||||||
|
volatile uint8_t status = 0;
|
||||||
|
|
||||||
|
inline static
|
||||||
|
void serial_delay(void) {
|
||||||
|
_delay_us(SERIAL_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static
|
||||||
|
void serial_output(void) {
|
||||||
|
SERIAL_PIN_DDR |= SERIAL_PIN_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// make the serial pin an input with pull-up resistor
|
||||||
|
inline static
|
||||||
|
void serial_input(void) {
|
||||||
|
SERIAL_PIN_DDR &= ~SERIAL_PIN_MASK;
|
||||||
|
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static
|
||||||
|
matrix_row_t serial_read_pin(void) {
|
||||||
|
return !!(SERIAL_PIN_INPUT & SERIAL_PIN_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static
|
||||||
|
void serial_low(void) {
|
||||||
|
SERIAL_PIN_PORT &= ~SERIAL_PIN_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline static
|
||||||
|
void serial_high(void) {
|
||||||
|
SERIAL_PIN_PORT |= SERIAL_PIN_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_master_init(void) {
|
||||||
|
serial_output();
|
||||||
|
serial_high();
|
||||||
|
}
|
||||||
|
|
||||||
|
void serial_slave_init(void) {
|
||||||
|
serial_input();
|
||||||
|
|
||||||
|
// Enable INT0
|
||||||
|
EIMSK |= _BV(INT0);
|
||||||
|
// Trigger on falling edge of INT0
|
||||||
|
EICRA &= ~(_BV(ISC00) | _BV(ISC01));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by the master to synchronize timing with the slave.
|
||||||
|
static
|
||||||
|
void sync_recv(void) {
|
||||||
|
serial_input();
|
||||||
|
// This shouldn't hang if the slave disconnects because the
|
||||||
|
// serial line will float to high if the slave does disconnect.
|
||||||
|
while (!serial_read_pin());
|
||||||
|
serial_delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Used by the slave to send a synchronization signal to the master.
|
||||||
|
static
|
||||||
|
void sync_send(void) {
|
||||||
|
serial_output();
|
||||||
|
|
||||||
|
serial_low();
|
||||||
|
serial_delay();
|
||||||
|
|
||||||
|
serial_high();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reads a byte from the serial line
|
||||||
|
static
|
||||||
|
matrix_row_t serial_read_byte(void) {
|
||||||
|
matrix_row_t byte = 0;
|
||||||
|
serial_input();
|
||||||
|
for ( uint8_t i = 0; i < MATRIX_COLS; ++i) {
|
||||||
|
byte = (byte << 1) | serial_read_pin();
|
||||||
|
serial_delay();
|
||||||
|
_delay_us(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return byte;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sends a byte with MSB ordering
|
||||||
|
static
|
||||||
|
void serial_write_byte(matrix_row_t data) {
|
||||||
|
matrix_row_t b = MATRIX_COLS;
|
||||||
|
serial_output();
|
||||||
|
while( b-- ) {
|
||||||
|
if(data & (1UL << b)) {
|
||||||
|
serial_high();
|
||||||
|
} else {
|
||||||
|
serial_low();
|
||||||
|
}
|
||||||
|
serial_delay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// interrupt handle to be used by the slave device
|
||||||
|
ISR(SERIAL_PIN_INTERRUPT) {
|
||||||
|
sync_send();
|
||||||
|
|
||||||
|
matrix_row_t checksum = 0;
|
||||||
|
for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {
|
||||||
|
serial_write_byte(serial_slave_buffer[i]);
|
||||||
|
sync_send();
|
||||||
|
checksum += ROW_MASK & serial_slave_buffer[i];
|
||||||
|
}
|
||||||
|
serial_write_byte(checksum);
|
||||||
|
sync_send();
|
||||||
|
|
||||||
|
// wait for the sync to finish sending
|
||||||
|
serial_delay();
|
||||||
|
|
||||||
|
// read the middle of pulses
|
||||||
|
_delay_us(SERIAL_DELAY/2);
|
||||||
|
|
||||||
|
matrix_row_t checksum_computed = 0;
|
||||||
|
for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {
|
||||||
|
serial_master_buffer[i] = serial_read_byte();
|
||||||
|
sync_send();
|
||||||
|
checksum_computed += ROW_MASK & serial_master_buffer[i];
|
||||||
|
}
|
||||||
|
matrix_row_t checksum_received = serial_read_byte();
|
||||||
|
sync_send();
|
||||||
|
|
||||||
|
serial_input(); // end transaction
|
||||||
|
|
||||||
|
if ( checksum_computed != checksum_received ) {
|
||||||
|
status |= SLAVE_DATA_CORRUPT;
|
||||||
|
} else {
|
||||||
|
status &= ~SLAVE_DATA_CORRUPT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
bool serial_slave_DATA_CORRUPT(void) {
|
||||||
|
return status & SLAVE_DATA_CORRUPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copies the serial_slave_buffer to the master and sends the
|
||||||
|
// serial_master_buffer to the slave.
|
||||||
|
//
|
||||||
|
// Returns:
|
||||||
|
// 0 => no error
|
||||||
|
// 1 => slave did not respond
|
||||||
|
int serial_update_buffers(void) {
|
||||||
|
// this code is very time dependent, so we need to disable interrupts
|
||||||
|
cli();
|
||||||
|
|
||||||
|
// signal to the slave that we want to start a transaction
|
||||||
|
serial_output();
|
||||||
|
serial_low();
|
||||||
|
_delay_us(1);
|
||||||
|
|
||||||
|
// wait for the slaves response
|
||||||
|
serial_input();
|
||||||
|
serial_high();
|
||||||
|
_delay_us(SERIAL_DELAY);
|
||||||
|
|
||||||
|
// check if the slave is present
|
||||||
|
if (serial_read_pin()) {
|
||||||
|
// slave failed to pull the line low, assume not present
|
||||||
|
sei();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the slave is present syncronize with it
|
||||||
|
sync_recv();
|
||||||
|
|
||||||
|
matrix_row_t checksum_computed = 0;
|
||||||
|
// receive data from the slave
|
||||||
|
for (int i = 0; i < SERIAL_SLAVE_BUFFER_LENGTH; ++i) {
|
||||||
|
serial_slave_buffer[i] = serial_read_byte();
|
||||||
|
sync_recv();
|
||||||
|
checksum_computed += ROW_MASK & serial_slave_buffer[i];
|
||||||
|
}
|
||||||
|
matrix_row_t checksum_received = serial_read_byte();
|
||||||
|
sync_recv();
|
||||||
|
|
||||||
|
if (checksum_computed != checksum_received) {
|
||||||
|
sei();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix_row_t checksum = 0;
|
||||||
|
// send data to the slave
|
||||||
|
for (int i = 0; i < SERIAL_MASTER_BUFFER_LENGTH; ++i) {
|
||||||
|
serial_write_byte(serial_master_buffer[i]);
|
||||||
|
sync_recv();
|
||||||
|
checksum += ROW_MASK & serial_master_buffer[i];
|
||||||
|
}
|
||||||
|
serial_write_byte(checksum);
|
||||||
|
sync_recv();
|
||||||
|
|
||||||
|
// always, release the line when not in use
|
||||||
|
serial_output();
|
||||||
|
serial_high();
|
||||||
|
|
||||||
|
sei();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
#ifndef MY_SERIAL_H
|
||||||
|
#define MY_SERIAL_H
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/* TODO: some defines for interrupt setup */
|
||||||
|
#define SERIAL_PIN_DDR DDRD
|
||||||
|
#define SERIAL_PIN_PORT PORTD
|
||||||
|
#define SERIAL_PIN_INPUT PIND
|
||||||
|
#define SERIAL_PIN_MASK _BV(PD0)
|
||||||
|
#define SERIAL_PIN_INTERRUPT INT0_vect
|
||||||
|
|
||||||
|
#define SERIAL_SLAVE_BUFFER_LENGTH MATRIX_ROWS/2
|
||||||
|
#define SERIAL_MASTER_BUFFER_LENGTH 1
|
||||||
|
|
||||||
|
// Buffers for master - slave communication
|
||||||
|
extern volatile matrix_row_t serial_slave_buffer[SERIAL_SLAVE_BUFFER_LENGTH];
|
||||||
|
extern volatile matrix_row_t serial_master_buffer[SERIAL_MASTER_BUFFER_LENGTH];
|
||||||
|
|
||||||
|
void serial_master_init(void);
|
||||||
|
void serial_slave_init(void);
|
||||||
|
int serial_update_buffers(void);
|
||||||
|
bool serial_slave_data_corrupt(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
#include <avr/io.h>
|
||||||
|
#include <avr/wdt.h>
|
||||||
|
#include <avr/power.h>
|
||||||
|
#include <avr/interrupt.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include <avr/eeprom.h>
|
||||||
|
#include "split_util.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
#include "keyboard.h"
|
||||||
|
#include "config.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
#ifdef USE_I2C
|
||||||
|
# include "i2c.h"
|
||||||
|
#else
|
||||||
|
# include "serial.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
volatile bool isLeftHand = true;
|
||||||
|
|
||||||
|
static void setup_handedness(void) {
|
||||||
|
#ifdef EE_HANDS
|
||||||
|
isLeftHand = eeprom_read_byte(EECONFIG_HANDEDNESS);
|
||||||
|
#else
|
||||||
|
// I2C_MASTER_RIGHT is deprecated, use MASTER_RIGHT instead, since this works for both serial and i2c
|
||||||
|
#if defined(I2C_MASTER_RIGHT) || defined(MASTER_RIGHT)
|
||||||
|
isLeftHand = !has_usb();
|
||||||
|
#else
|
||||||
|
isLeftHand = has_usb();
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void keyboard_master_setup(void) {
|
||||||
|
#ifdef USE_I2C
|
||||||
|
i2c_master_init();
|
||||||
|
#ifdef SSD1306OLED
|
||||||
|
matrix_master_OLED_init();
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
serial_master_init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static void keyboard_slave_setup(void) {
|
||||||
|
timer_init();
|
||||||
|
#ifdef USE_I2C
|
||||||
|
i2c_slave_init(SLAVE_I2C_ADDRESS);
|
||||||
|
#else
|
||||||
|
serial_slave_init();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_usb(void) {
|
||||||
|
USBCON |= (1 << OTGPADE); //enables VBUS pad
|
||||||
|
_delay_us(5);
|
||||||
|
return (USBSTA & (1<<VBUS)); //checks state of VBUS
|
||||||
|
}
|
||||||
|
|
||||||
|
void split_keyboard_setup(void) {
|
||||||
|
setup_handedness();
|
||||||
|
|
||||||
|
if (has_usb()) {
|
||||||
|
keyboard_master_setup();
|
||||||
|
} else {
|
||||||
|
keyboard_slave_setup();
|
||||||
|
}
|
||||||
|
sei();
|
||||||
|
}
|
||||||
|
|
||||||
|
void keyboard_slave_loop(void) {
|
||||||
|
matrix_init();
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
matrix_slave_scan();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this code runs before the usb and keyboard is initialized
|
||||||
|
void matrix_setup(void) {
|
||||||
|
split_keyboard_setup();
|
||||||
|
|
||||||
|
if (!has_usb()) {
|
||||||
|
keyboard_slave_loop();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef SPLIT_KEYBOARD_UTIL_H
|
||||||
|
#define SPLIT_KEYBOARD_UTIL_H
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include "eeconfig.h"
|
||||||
|
|
||||||
|
#define SLAVE_I2C_ADDRESS 0x32
|
||||||
|
|
||||||
|
extern volatile bool isLeftHand;
|
||||||
|
|
||||||
|
// slave version of matix scan, defined in matrix.c
|
||||||
|
void matrix_slave_scan(void);
|
||||||
|
|
||||||
|
void split_keyboard_setup(void);
|
||||||
|
bool has_usb(void);
|
||||||
|
void keyboard_slave_loop(void);
|
||||||
|
|
||||||
|
void matrix_master_OLED_init (void);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -110,8 +110,8 @@ void click(uint16_t freq, uint16_t duration);
|
|||||||
#define LAYOUT_iso( \
|
#define LAYOUT_iso( \
|
||||||
k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F, k0G, \
|
k01, k02, k03, k04, k05, k06, k07, k08, k09, k0A, k0B, k0C, k0D, k0E, k0F, k0G, \
|
||||||
k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1G, \
|
k11, k12, k13, k14, k15, k16, k17, k18, k19, k1A, k1B, k1C, k1D, k1E, k1G, \
|
||||||
k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k3D, k2F, \
|
k21, k22, k23, k24, k25, k26, k27, k28, k29, k2A, k2B, k2C, k2D, k2E, k2F, \
|
||||||
k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k2E, k3F, \
|
k31, k32, k33, k34, k35, k36, k37, k38, k39, k3A, k3B, k3C, k3D, k3F, \
|
||||||
k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F, \
|
k41, k42, k43, k44, k45, k46, k47, k48, k49, k4A, k4B, k4C, k4D, k4E, k4F, \
|
||||||
k51, k52, k53, k54, k57, k59, k5A, k5B, k5C, k5D, k5E, k5F \
|
k51, k52, k53, k54, k57, k59, k5A, k5B, k5C, k5D, k5E, k5F \
|
||||||
) { \
|
) { \
|
||||||
|
|||||||
@@ -59,3 +59,11 @@ void action_function(keyrecord_t *record, uint8_t id, uint8_t opt) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void led_set_user(uint8_t usb_led) {
|
||||||
|
if (usb_led & (1 << USB_LED_CAPS_LOCK)) {
|
||||||
|
DDRB |= (1 << 2); PORTB &= ~(1 << 2);
|
||||||
|
} else {
|
||||||
|
DDRB &= ~(1 << 2); PORTB &= ~(1 << 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,7 +32,7 @@
|
|||||||
{ K0A, K0B, K0C, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, K0J, KC_NO, K0K, K0L, K0M, K0N, K0O } \
|
{ K0A, K0B, K0C, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, K0J, KC_NO, K0K, K0L, K0M, K0N, K0O } \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LAYOUT_eagle( \
|
#define LAYOUT_60_ansi( \
|
||||||
K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4M, K4O, \
|
K4A, K4B, K4C, K4D, K4E, K4F, K4G, K4H, K4I, K4J, K4K, K4L, K4M, K4O, \
|
||||||
K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3O, \
|
K3A, K3B, K3C, K3D, K3E, K3F, K3G, K3H, K3I, K3J, K3K, K3L, K3M, K3O, \
|
||||||
K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2O, \
|
K2A, K2B, K2C, K2D, K2E, K2F, K2G, K2H, K2I, K2J, K2K, K2L, K2O, \
|
||||||
@@ -75,4 +75,4 @@
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define LAYOUT_60_ansi LAYOUT_eagle
|
#define LAYOUT_eagle LAYOUT_60_ansi
|
||||||
@@ -10,7 +10,8 @@ Linux page]. Some distributions provide a binary, maybe called
|
|||||||
|
|
||||||
To flash the firmware:
|
To flash the firmware:
|
||||||
|
|
||||||
- Build the firmware with `make keymapname`, for example `make default`
|
- Build the firmware with `make <keyboardname>:<keymapname>`, for example `make ergodox_ez:default`
|
||||||
|
|
||||||
- This will result in a hex file called `ergodox_ez_keymapname.hex`, e.g.
|
- This will result in a hex file called `ergodox_ez_keymapname.hex`, e.g.
|
||||||
`ergodox_ez_default.hex`
|
`ergodox_ez_default.hex`
|
||||||
|
|
||||||
@@ -19,10 +20,12 @@ To flash the firmware:
|
|||||||
- Load the .hex file into it.
|
- Load the .hex file into it.
|
||||||
|
|
||||||
- Press the Reset button by inserting a paperclip gently into the reset hole
|
- Press the Reset button by inserting a paperclip gently into the reset hole
|
||||||
in the top right corder.
|
in the top right corner.
|
||||||
|
|
||||||
- Click the button in the Teensy app to download the firmware.
|
- Click the button in the Teensy app to download the firmware.
|
||||||
|
|
||||||
|
See also [video demonstration](https://www.youtube.com/watch?v=9PyiGUO9_KQ) using Teensy in auto mode.
|
||||||
|
|
||||||
To flash with ´teensy-loader-cli´:
|
To flash with ´teensy-loader-cli´:
|
||||||
|
|
||||||
- Build the firmware with `make keymapname`, for example `make default`
|
- Build the firmware with `make keymapname`, for example `make default`
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
/* ws2812 RGB LED */
|
/* ws2812 RGB LED */
|
||||||
#define RGB_DI_PIN D3
|
#define RGB_DI_PIN D3
|
||||||
#define RGBLIGHT_TIMER
|
#define RGBLIGHT_TIMER
|
||||||
#define RGBLED_NUM 12 // Number of LEDs
|
//#define RGBLED_NUM 12 // Number of LEDs. see ./keymaps/default/config.h
|
||||||
#define ws2812_PORTREG PORTD
|
#define ws2812_PORTREG PORTD
|
||||||
#define ws2812_DDRREG DDRD
|
#define ws2812_DDRREG DDRD
|
||||||
|
|
||||||
|
|||||||
@@ -36,11 +36,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// #define EE_HANDS
|
// #define EE_HANDS
|
||||||
|
|
||||||
// Helix keyboard OLED support
|
// Helix keyboard OLED support
|
||||||
//#define SSD1306OLED
|
// see ./rules.mk: OLED_ENABLE=yes or no
|
||||||
|
#ifdef OLED_ENABLE
|
||||||
|
#define SSD1306OLED
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Select rows configuration */
|
/* Select rows configuration */
|
||||||
// Rows are 4 or 5
|
// Rows are 4 or 5
|
||||||
#define HELIX_ROWS 5
|
// #define HELIX_ROWS 5 see ./rules.mk
|
||||||
|
|
||||||
/* key matrix size */
|
/* key matrix size */
|
||||||
// Rows are doubled-up
|
// Rows are doubled-up
|
||||||
@@ -62,12 +65,19 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define TAPPING_FORCE_HOLD
|
#define TAPPING_FORCE_HOLD
|
||||||
#define TAPPING_TERM 100
|
#define TAPPING_TERM 100
|
||||||
|
|
||||||
|
// Helix keyboard RGB LED support
|
||||||
|
//#define RGBLIGHT_ANIMATIONS : see ./rules.mk: LED_ANIMATIONS = yes or no
|
||||||
|
// see ./rules.mk: LED_BACK_ENABLE or LED_UNDERGLOW_ENABLE set yes
|
||||||
|
#ifdef RGBLED_BACK
|
||||||
|
#if HELIX_ROWS == 4
|
||||||
|
#define RGBLED_NUM 25
|
||||||
|
#elif HELIX_ROWS == 5
|
||||||
|
#define RGBLED_NUM 32
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define RGBLED_NUM 6
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef RGBLED_NUM
|
|
||||||
#define RGBLIGHT_ANIMATIONS
|
|
||||||
// Helix keyboard : see ./rules.mk: RGBLIGHT_ENABLE = yes or no
|
|
||||||
// Helix keyboard : RGBLED_NUM 6 or 32
|
|
||||||
#define RGBLED_NUM 6
|
|
||||||
#if RGBLED_NUM <= 6
|
#if RGBLED_NUM <= 6
|
||||||
#define RGBLIGHT_LIMIT_VAL 255
|
#define RGBLIGHT_LIMIT_VAL 255
|
||||||
#else
|
#else
|
||||||
|
|||||||
@@ -1,25 +1,141 @@
|
|||||||
SSD1306 OLED Display via I2C
|
# The Default Helix Layout
|
||||||
======
|
## Layout
|
||||||
|
|
||||||
Features
|
### Qwerty
|
||||||
--------
|
|
||||||
|
|
||||||
Some features supported by the firmware:
|
```
|
||||||
|
,-----------------------------------------. ,-----------------------------------------.
|
||||||
|
| ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| Ctrl | A | S | D | F | G | | H | J | K | L | ; | ' |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| Shift| Z | X | C | V | B | [ | ] | N | M | , | . | / |Enter |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
|Adjust| Esc | Alt | GUI | EISU |Lower |Space |Space |Raise | KANA | Left | Down | Up |Right |
|
||||||
|
`-------------------------------------------------------------------------------------------------'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Colemak
|
||||||
|
```
|
||||||
|
,-----------------------------------------. ,-----------------------------------------.
|
||||||
|
| ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| Tab | Q | W | F | P | G | | J | L | U | Y | ; | Bksp |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| Ctrl | A | R | S | T | D | | H | N | E | I | O | ' |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| Shift| Z | X | C | V | B | [ | ] | K | M | , | . | / |Enter |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
|Adjust| Esc | Alt | GUI | EISU |Lower |Space |Space |Raise | KANA | Left | Down | Up |Right |
|
||||||
|
`-------------------------------------------------------------------------------------------------'
|
||||||
|
```
|
||||||
|
|
||||||
* I2C connection between the two halves is required as the OLED display will use this connection as well. Note this
|
### Dvorak
|
||||||
requires pull-up resistors on the data and clock lines.
|
```
|
||||||
* OLED display will connect from either side
|
,-----------------------------------------. ,-----------------------------------------.
|
||||||
|
| ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bksp |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| Tab | ' | , | . | P | Y | | F | G | C | R | L | Del |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| Ctrl | A | O | E | U | I | | D | H | T | N | S | / |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| Shift| ; | Q | J | K | X | [ | ] | B | M | W | V | Z |Enter |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
|Adjust| Esc | Alt | GUI | EISU |Lower |Space |Space |Raise | KANA | Left | Down | Up |Right |
|
||||||
|
`-------------------------------------------------------------------------------------------------'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Layers
|
||||||
|
|
||||||
Wiring
|
|Priority|number|name|description|
|
||||||
------
|
| ---- | ---- | --- | --- |
|
||||||
|
|high|16|Adjust|Functions|
|
||||||
|
||4|Raise|Numeric charactors|
|
||||||
|
||3|Lower|Other charactors|
|
||||||
|
||2|Dvorak|Dvorak leyout|
|
||||||
|
||1|Colemak|Colemak leyout|
|
||||||
|
|low|0|Qwerty|QWERTY leyout(base)|
|
||||||
|
|
||||||
|
### Lower
|
||||||
|
```
|
||||||
|
,-----------------------------------------. ,-----------------------------------------.
|
||||||
|
| ~ | ! | @ | # | $ | % | | ^ | & | * | ( | ) | |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| ~ | ! | @ | # | $ | % | | ^ | & | * | ( | ) | |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| | F1 | F2 | F3 | F4 | F5 | | F6 | _ | + | { | } | | |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| | F7 | F8 | F9 | F10 | F11 | ( | ) | F12 | | | Home | End | |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| | | | | | | | | | | Next | Vol- | Vol+ | Play |
|
||||||
|
`-------------------------------------------------------------------------------------------------'
|
||||||
|
```
|
||||||
|
|
||||||
Work in progress...
|
### Raise
|
||||||
|
```
|
||||||
|
,-----------------------------------------. ,-----------------------------------------.
|
||||||
|
| ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Bksp |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| | F1 | F2 | F3 | F4 | F5 | | F6 | - | = | [ | ] | \ |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| | F7 | F8 | F9 | F10 | F11 | | | F12 | | |PageDn|PageUp| |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| | | | | | | | | | | Next | Vol- | Vol+ | Play |
|
||||||
|
`-------------------------------------------------------------------------------------------------'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Adjust (Lower + Raise)
|
||||||
|
```
|
||||||
|
,-----------------------------------------. ,-----------------------------------------.
|
||||||
|
| F1 | F2 | F3 | F4 | F5 | F6 | | F7 | F8 | F9 | F10 | F11 | F12 |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| | Reset|RGBRST| | | | | | | | | | Del |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| | | |Aud on|Audoff| Mac | | Win |Qwerty|Colemk|Dvorak| | |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| | | | | | | | | | |RGB ON| HUE+ | SAT+ | VAL+ |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| | | | | | | | | | | MODE | HUE- | SAT- | VAL- |
|
||||||
|
`-------------------------------------------------------------------------------------------------'
|
||||||
|
```
|
||||||
|
|
||||||
OLED Configuration
|
## Customize
|
||||||
-------------------------------
|
|
||||||
|
see `qmk_firmware/keyboards/helix/rev2/keymaps/default/rules.mk`
|
||||||
|
|
||||||
|
```
|
||||||
|
# Helix keyboard customize
|
||||||
|
# you can edit follows 5 Variables
|
||||||
|
# jp: 以下の5つの変数を必要に応じて編集します。
|
||||||
|
HELIX_ROWS = 5 # Helix Rows is 4 or 5
|
||||||
|
OLED_ENABLE = no # OLED_ENABLE
|
||||||
|
LED_BACK_ENABLE = no # LED backlight (Enable WS2812 RGB underlight.)
|
||||||
|
LED_UNDERGLOW_ENABLE = no # LED underglow (Enable WS2812 RGB underlight.)
|
||||||
|
LED_ANIMATIONS = yes # LED animations
|
||||||
|
|
||||||
|
```
|
||||||
|
## Compile
|
||||||
|
|
||||||
|
go to qmk top directory.
|
||||||
|
```
|
||||||
|
$ cd qmk_firmware
|
||||||
|
```
|
||||||
|
|
||||||
|
build
|
||||||
|
```
|
||||||
|
$ make helix:default
|
||||||
|
```
|
||||||
|
|
||||||
|
flash to keyboard
|
||||||
|
```
|
||||||
|
$ make helix:default:avrdude
|
||||||
|
```
|
||||||
|
|
||||||
|
## Link
|
||||||
|
* more detail wrote in Japanese [helix/Doc/firmware_jp.md](https://github.com/MakotoKurauchi/helix/blob/master/Doc/firmware_jp.md)
|
||||||
|
* [Helix top](https://github.com/MakotoKurauchi/helix)
|
||||||
|
|
||||||
Work in progress...
|
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
# The Default Helix Layout
|
||||||
|
## 配列
|
||||||
|
|
||||||
|
### Qwerty配列
|
||||||
|
|
||||||
|
```
|
||||||
|
,-----------------------------------------. ,-----------------------------------------.
|
||||||
|
| ` | 1 | 2 | 3 | 4 | 5 | | 6 | 7 | 8 | 9 | 0 | Del |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| Tab | Q | W | E | R | T | | Y | U | I | O | P | Bksp |
|
||||||
|
|------+------+------+------+------+------| |------+------+------+------+------+------|
|
||||||
|
| Ctrl | A | S | D | F | G | | H | J | K | L | ; | ' |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
| Shift| Z | X | C | V | B | [ | ] | N | M | , | . | / |Enter |
|
||||||
|
|------+------+------+------+------+------+------+------+------+------+------+------+------+------|
|
||||||
|
|Adjust| Esc | Alt | GUI | EISU |Lower |Space |Space |Raise | KANA | Left | Down | Up |Right |
|
||||||
|
`-------------------------------------------------------------------------------------------------'
|
||||||
|
```
|
||||||
|
|
||||||
|
他の配列(Colemak,Dvorak)は、[readme.md](readme.md) を参照
|
||||||
|
|
||||||
|
## コンパイルの仕方
|
||||||
|
|
||||||
|
コンパイルは、qmk_firmware のトップディレクトリで行います。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ cd qmk_firmware
|
||||||
|
```
|
||||||
|
qmk_firmwareでは各キーボードのコンパイルは、`<キーボード名>:<キーマップ名>`という指定で行います。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make helix:default
|
||||||
|
```
|
||||||
|
|
||||||
|
キーボードへの書き込みまで同時に行うには下記のように`:avrdude`を付けます。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make helix:default:avrdude
|
||||||
|
```
|
||||||
|
|
||||||
|
コンパイル結果と中間生成物を消去したい場合は以下のようにします。
|
||||||
|
|
||||||
|
```
|
||||||
|
$ make helix:default:clean
|
||||||
|
```
|
||||||
|
|
||||||
|
## カスタマイズ
|
||||||
|
|
||||||
|
Helix キーボードを4行版として製作したり、オプションの OLED をつけたり、
|
||||||
|
RGB バックライトまたは、RGB Underglow をつけた場合は、
|
||||||
|
`qmk_firmware/keyboards/helix/rev2/keymaps/default/rules.mk` の以下の部分を編集して機能を有効化してください。
|
||||||
|
|
||||||
|
```
|
||||||
|
# Helix keyboard customize
|
||||||
|
# you can edit follows 5 Variables
|
||||||
|
# jp: 以下の5つの変数を必要に応じて編集します。
|
||||||
|
HELIX_ROWS = 5 # Helix Rows is 4 or 5
|
||||||
|
OLED_ENABLE = no # OLED_ENABLE
|
||||||
|
LED_BACK_ENABLE = no # LED backlight (Enable WS2812 RGB underlight.)
|
||||||
|
LED_UNDERGLOW_ENABLE = no # LED underglow (Enable WS2812 RGB underlight.)
|
||||||
|
LED_ANIMATIONS = yes # LED animations
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4行版Helix に対応する
|
||||||
|
|
||||||
|
rules.mk の下記の部分を編集して 5 を 4 に変更してください。
|
||||||
|
|
||||||
|
```
|
||||||
|
HELIX_ROWS = 4 # Helix Rows is 4 or 5
|
||||||
|
```
|
||||||
|
|
||||||
|
## RGB バックライトを有効にする
|
||||||
|
|
||||||
|
rules.mk の下記の部分を編集して no を yes に変更してください。
|
||||||
|
|
||||||
|
```
|
||||||
|
LED_BACK_ENABLE = yes # LED backlight (Enable WS2812 RGB underlight.)
|
||||||
|
```
|
||||||
|
|
||||||
|
## RGB Underglow を有効にする
|
||||||
|
|
||||||
|
rules.mk の下記の部分を編集して no を yes に変更してください。
|
||||||
|
```
|
||||||
|
LED_UNDERGLOW_ENABLE = yes # LED underglow (Enable WS2812 RGB underlight.)
|
||||||
|
```
|
||||||
|
|
||||||
|
## OLEDを有効にする
|
||||||
|
|
||||||
|
rules.mk の下記の部分を編集して no を yes に変更してください。
|
||||||
|
```
|
||||||
|
OLED_ENABLE = yes # OLED_ENABLE
|
||||||
|
```
|
||||||
|
|
||||||
|
## リンク
|
||||||
|
|
||||||
|
* さらに詳細は、[こちら helix/Doc/firmware_jp.md](https://github.com/MakotoKurauchi/helix/blob/master/Doc/firmware_jp.md)をご覧ください。
|
||||||
|
* [Helix top](https://github.com/MakotoKurauchi/helix)
|
||||||
@@ -14,14 +14,70 @@ MIDI_ENABLE = no # MIDI controls
|
|||||||
AUDIO_ENABLE = no # Audio output on port C6
|
AUDIO_ENABLE = no # Audio output on port C6
|
||||||
UNICODE_ENABLE = no # Unicode
|
UNICODE_ENABLE = no # Unicode
|
||||||
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
|
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
|
||||||
# Helix keyboard : see ./config.h: RGBLED_NUM 6 or 32
|
|
||||||
# Helix keyboard : RGBLIGHT_ENABLE = no or yes
|
|
||||||
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
|
RGBLIGHT_ENABLE = no # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
|
||||||
SWAP_HANDS_ENABLE = no # Enable one-hand typing
|
SWAP_HANDS_ENABLE = no # Enable one-hand typing
|
||||||
|
|
||||||
|
define HELIX_CUSTOMISE_MSG
|
||||||
|
$(info Helix customize)
|
||||||
|
$(info - OLED_ENABLE=$(OLED_ENABLE))
|
||||||
|
$(info - LED_BACK_ENABLE=$(LED_BACK_ENABLE))
|
||||||
|
$(info - LED_UNDERGLOW_ENABLE=$(LED_UNDERGLOW_ENABLE))
|
||||||
|
$(info - LED_ANIMATION=$(LED_ANIMATIONS))
|
||||||
|
endef
|
||||||
|
|
||||||
|
# Helix keyboard customize
|
||||||
|
# you can edit follows 5 Variables
|
||||||
|
# jp: 以下の5つの変数を必要に応じて編集します。
|
||||||
|
HELIX_ROWS = 5 # Helix Rows is 4 or 5
|
||||||
|
OLED_ENABLE = no # OLED_ENABLE
|
||||||
|
LED_BACK_ENABLE = no # LED backlight (Enable WS2812 RGB underlight.)
|
||||||
|
LED_UNDERGLOW_ENABLE = no # LED underglow (Enable WS2812 RGB underlight.)
|
||||||
|
LED_ANIMATIONS = yes # LED animations
|
||||||
|
|
||||||
|
#### LED_BACK_ENABLE and LED_UNDERGLOW_ENABLE.
|
||||||
|
#### Do not enable these with audio at the same time.
|
||||||
|
|
||||||
|
# Uncomment these for checking
|
||||||
|
# jp: コンパイル時にカスタマイズの状態を表示したい時はコメントをはずします。
|
||||||
|
# $(eval $(call HELIX_CUSTOMISE_MSG))
|
||||||
|
# $(info )
|
||||||
|
|
||||||
|
ifneq ($(strip $(HELIX_ROWS)), 4)
|
||||||
|
ifneq ($(strip $(HELIX_ROWS)), 5)
|
||||||
|
$(error HELIX_ROWS = $(strip $(HELIX_ROWS)) is unexpected value)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
OPT_DEFS += -DHELIX_ROWS=$(strip $(HELIX_ROWS))
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_BACK_ENABLE)), yes)
|
||||||
|
RGBLIGHT_ENABLE = yes
|
||||||
|
OPT_DEFS += -DRGBLED_BACK
|
||||||
|
ifeq ($(strip $(LED_UNDERGLOW_ENABLE)), yes)
|
||||||
|
$(eval $(call HELIX_CUSTOMISE_MSG))
|
||||||
|
$(error LED_BACK_ENABLE and LED_UNDERGLOW_ENABLE both 'yes')
|
||||||
|
endif
|
||||||
|
else ifeq ($(strip $(LED_UNDERGLOW_ENABLE)), yes)
|
||||||
|
RGBLIGHT_ENABLE = yes
|
||||||
|
else
|
||||||
|
RGBLIGHT_ENABLE = no
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_ANIMATIONS)), yes)
|
||||||
|
OPT_DEFS += -DRGBLIGHT_ANIMATIONS
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(strip $(OLED_ENABLE)), yes)
|
||||||
|
OPT_DEFS += -DOLED_ENABLE
|
||||||
|
endif
|
||||||
|
|
||||||
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||||
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||||
|
|
||||||
ifndef QUANTUM_DIR
|
ifndef QUANTUM_DIR
|
||||||
include ../../../../Makefile
|
include ../../../../Makefile
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
# Uncomment these for debugging
|
||||||
|
# $(info -- RGBLIGHT_ENABLE=$(RGBLIGHT_ENABLE))
|
||||||
|
# $(info -- OPT_DEFS=$(OPT_DEFS))
|
||||||
|
# $(info )
|
||||||
@@ -34,4 +34,16 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// #define MASTER_RIGHT
|
// #define MASTER_RIGHT
|
||||||
// #define EE_HANDS
|
// #define EE_HANDS
|
||||||
|
|
||||||
|
// RGB Options
|
||||||
|
#undef RGBLED_NUM
|
||||||
|
#define RGBLED_NUM 10
|
||||||
|
#define RGBLIGHT_SLEEP
|
||||||
|
#define RGBLIGHT_ANIMATIONS
|
||||||
|
#define RGBLIGHT_EFFECT_SNAKE_LENGTH 1
|
||||||
|
#define RGBLIGHT_EFFECT_KNIGHT_LENGTH 1
|
||||||
|
|
||||||
|
// Typing Options
|
||||||
|
#define PREVENT_STUCK_MODIFIERS
|
||||||
|
#define QMK_KEYS_PER_SCAN 4
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -10,7 +10,7 @@ extern keymap_config_t keymap_config;
|
|||||||
#define _NUMBER 3 // F(3)
|
#define _NUMBER 3 // F(3)
|
||||||
#define _FUNCTION 4 // F(4)
|
#define _FUNCTION 4 // F(4)
|
||||||
#define _EMACS 5 // F(5)
|
#define _EMACS 5 // F(5)
|
||||||
#define _MACROS 6 // F(6)
|
#define _COMBOS 6 // F(6)
|
||||||
#define _MOUSE 7 // F(7)
|
#define _MOUSE 7 // F(7)
|
||||||
|
|
||||||
enum custom_keycodes {
|
enum custom_keycodes {
|
||||||
@@ -20,17 +20,17 @@ enum custom_keycodes {
|
|||||||
NUMBER,
|
NUMBER,
|
||||||
FUNCTION,
|
FUNCTION,
|
||||||
EMACS,
|
EMACS,
|
||||||
MACROS,
|
COMBOS,
|
||||||
MOUSE,
|
MOUSE,
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
|
|
||||||
[_DVORAK] = LAYOUT( \
|
[_DVORAK] = LAYOUT( \
|
||||||
KC_ESC, KC_QUOTE, F(7), KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_DELETE, \
|
KC_ESC, KC_QUOTE, LT(7, KC_COMMA), KC_DOT, KC_P, KC_Y, KC_F, KC_G, KC_C, KC_R, KC_L, KC_DELETE, \
|
||||||
KC_TAB, F(1), F(2), F(3), F(4), KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_ENTER, \
|
KC_TAB, LT(1, KC_A), LT(2, KC_O), LT(3, KC_E), LT(4, KC_U), KC_I, KC_D, KC_H, KC_T, KC_N, KC_S, KC_ENTER, \
|
||||||
KC_LSHIFT, KC_SCOLON, F(5), KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_MINUS, \
|
KC_LSHIFT, KC_SCOLON, LT(5, KC_Q), KC_J, KC_K, KC_X, KC_B, KC_M, KC_W, KC_V, KC_Z, KC_MINUS, \
|
||||||
F(10), F(6), KC_MENU, KC_LALT, KC_LGUI, KC_BSPACE, KC_SPACE, KC_RCTRL, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT \
|
F(1), LT(6, KC_LCTRL), KC_MENU, KC_LALT, KC_LGUI, KC_BSPACE, KC_SPACE, KC_RCTRL, KC_LEFT, KC_DOWN, KC_UP, KC_RIGHT \
|
||||||
),
|
),
|
||||||
|
|
||||||
[_ARROW] = LAYOUT( \
|
[_ARROW] = LAYOUT( \
|
||||||
@@ -42,7 +42,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|||||||
|
|
||||||
[_SYMBOL] = LAYOUT( \
|
[_SYMBOL] = LAYOUT( \
|
||||||
KC_TILD, KC_GRAVE, KC_NO, KC_EQUAL, KC_PLUS, KC_NO, KC_LBRACKET, KC_RBRACKET, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, \
|
KC_TILD, KC_GRAVE, KC_NO, KC_EQUAL, KC_PLUS, KC_NO, KC_LBRACKET, KC_RBRACKET, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, \
|
||||||
KC_NO, KC_NO, KC_TRNS, KC_SCOLON, KC_COLN, KC_NO, KC_LCBR, KC_RCBR, KC_DLR, KC_PERC, KC_CIRC, F(21), \
|
KC_NO, KC_NO, KC_TRNS, KC_SCOLON, KC_COLN, KC_NO, KC_LCBR, KC_RCBR, KC_DLR, KC_PERC, KC_CIRC, F(2), \
|
||||||
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_BSLASH, KC_SLASH, KC_EXLM, KC_AT, KC_HASH, KC_PIPE, \
|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_BSLASH, KC_SLASH, KC_EXLM, KC_AT, KC_HASH, KC_PIPE, \
|
||||||
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_ASTR, KC_SLASH, KC_MINUS, KC_PLUS, KC_EQUAL \
|
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_ASTR, KC_SLASH, KC_MINUS, KC_PLUS, KC_EQUAL \
|
||||||
),
|
),
|
||||||
@@ -56,9 +56,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|||||||
|
|
||||||
[_FUNCTION] = LAYOUT( \
|
[_FUNCTION] = LAYOUT( \
|
||||||
KC_PSCREEN, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, \
|
KC_PSCREEN, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, \
|
||||||
KC_NO, KC_NO, KC_NO, KC_NO, KC_TRNS, KC_NO, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, \
|
KC_NO, RGB_HUI, RGB_SAI, RGB_VAI, KC_TRNS, KC_NO, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, KC_F12, \
|
||||||
KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_AUDIO_MUTE, KC_AUDIO_VOL_DOWN, KC_AUDIO_VOL_UP, KC_MEDIA_PLAY_PAUSE, \
|
KC_NO, RGB_HUD, RGB_SAD, RGB_VAD, KC_NO, KC_NO, KC_NO, KC_NO, KC_AUDIO_MUTE, KC_AUDIO_VOL_DOWN, KC_AUDIO_VOL_UP, KC_MEDIA_PLAY_PAUSE, \
|
||||||
RESET, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_DELETE, KC_INSERT, KC_HOME, KC_PGDN, KC_PGUP, KC_END \
|
RESET, RGB_TOG, RGB_MOD, KC_NO, KC_NO, KC_NO, KC_DELETE, KC_INSERT, KC_HOME, KC_PGDN, KC_PGUP, KC_END \
|
||||||
),
|
),
|
||||||
|
|
||||||
[_EMACS] = LAYOUT( \
|
[_EMACS] = LAYOUT( \
|
||||||
@@ -68,7 +68,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|||||||
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 \
|
||||||
),
|
),
|
||||||
|
|
||||||
[_MACROS] = LAYOUT( \
|
[_COMBOS] = LAYOUT( \
|
||||||
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, 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, 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, \
|
||||||
@@ -93,29 +93,8 @@ enum function_id {
|
|||||||
int CAPSLOCKED = 0;
|
int CAPSLOCKED = 0;
|
||||||
|
|
||||||
const uint16_t PROGMEM fn_actions[] = {
|
const uint16_t PROGMEM fn_actions[] = {
|
||||||
|
|
||||||
// DVORAK 0
|
|
||||||
// ARROW 1, F(1)
|
|
||||||
// SYMBOL 2, F(2)
|
|
||||||
// NUMBER 3, F(3)
|
|
||||||
// FUNCTION 4, F(4)
|
|
||||||
// EMACS 5, F(5)
|
|
||||||
// MACROS 6, F(6)
|
|
||||||
// MOUSE 7, F(7)
|
|
||||||
|
|
||||||
// Layers
|
|
||||||
[1] = ACTION_LAYER_TAP_KEY(1, KC_A), // FN1 = Momentary Arrow layer on A.
|
|
||||||
[2] = ACTION_LAYER_TAP_KEY(2, KC_O), // FN2 = Momentary symbOl layer on O.
|
|
||||||
[3] = ACTION_LAYER_TAP_KEY(3, KC_E), // FN3 = Momentary numbEr layer on E.
|
|
||||||
[4] = ACTION_LAYER_TAP_KEY(4, KC_U), // FN4 = Momentary fUnction layer on U.
|
|
||||||
[5] = ACTION_LAYER_TAP_KEY(5, KC_Q), // FN5 = Momentary emaQs layer on Q.
|
|
||||||
[6] = ACTION_LAYER_TAP_KEY(6, KC_LCTRL), // FN6 = Momentary MACROS on ??? key.
|
|
||||||
[7] = ACTION_LAYER_TAP_KEY(7, KC_COMMA), // FN7 = Momentary MOUSE on , key.
|
|
||||||
|
|
||||||
// Special Keys
|
// Special Keys
|
||||||
[10] = ACTION_MODS_KEY(KC_LCTRL, KC_LALT), // FN10 = Ctrl + Alt.
|
[1] = ACTION_MODS_KEY(KC_LCTRL, KC_LALT), // FN10 = Ctrl + Alt.
|
||||||
|
|
||||||
// Symbols
|
// Symbols
|
||||||
[21] = ACTION_MODS_KEY(MOD_LSFT, KC_SLASH), // FN21 = Question mark.
|
[2] = ACTION_MODS_KEY(MOD_LSFT, KC_SLASH), // FN21 = Question mark.
|
||||||
|
|
||||||
};
|
};
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
BOOTMAGIC_ENABLE = no # 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 = no # Enable keyboard backlight functionality
|
||||||
|
MIDI_ENABLE = no # MIDI controls
|
||||||
|
AUDIO_ENABLE = no # Audio output on port C6
|
||||||
|
UNICODE_ENABLE = yes # Unicode
|
||||||
|
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
|
||||||
|
RGBLIGHT_ENABLE = yes # Enable WS2812 RGB underlight. Do not enable this with audio at the same time.
|
||||||
|
SUBPROJECT_rev1 = no
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"keyboard_name": "Pearl",
|
||||||
|
"url": "",
|
||||||
|
"maintainer": "qmk",
|
||||||
|
"bootloader": "",
|
||||||
|
"width": 13,
|
||||||
|
"height": 4,
|
||||||
|
"layouts": {
|
||||||
|
"LAYOUT": {
|
||||||
|
"layout": [{"label":"Esc", "x":0, "y":0}, {"label":"Q", "x":1, "y":0}, {"label":"W", "x":2, "y":0}, {"label":"E", "x":3, "y":0}, {"label":"R", "x":4, "y":0}, {"label":"T", "x":5, "y":0}, {"label":"Y", "x":6, "y":0}, {"label":"U", "x":7, "y":0}, {"label":"I", "x":8, "y":0}, {"label":"O", "x":9, "y":0}, {"label":"P", "x":10, "y":0}, {"label":"{", "x":11, "y":0}, {"label":"Backspace", "x":12, "y":0}, {"label":"Tab", "x":0, "y":1, "w":1.5}, {"label":"A", "x":1.5, "y":1}, {"label":"S", "x":2.5, "y":1}, {"label":"D", "x":3.5, "y":1}, {"label":"F", "x":4.5, "y":1}, {"label":"G", "x":5.5, "y":1}, {"label":"H", "x":6.5, "y":1}, {"label":"J", "x":7.5, "y":1}, {"label":"K", "x":8.5, "y":1}, {"label":"L", "x":9.5, "y":1}, {"label":":", "x":10.5, "y":1}, {"label":"\\", "x":11.5, "y":1, "w":1.5}, {"label":"Caps Lock", "x":0, "y":2, "w":1.75}, {"label":"Z", "x":1.75, "y":2}, {"label":"X", "x":2.75, "y":2}, {"label":"C", "x":3.75, "y":2}, {"label":"V", "x":4.75, "y":2}, {"label":"B", "x":5.75, "y":2}, {"label":"N", "x":6.75, "y":2}, {"label":"M", "x":7.75, "y":2}, {"label":"<", "x":8.75, "y":2}, {"label":">", "x":9.75, "y":2}, {"label":"?", "x":10.75, "y":2}, {"label":"Shift", "x":11.75, "y":2, "w":1.25}, {"label":"Alt", "x":1.13, "y":3}, {"label":"Ctrl", "x":2.13, "y":3, "w":1.25}, {"label":"Win", "x":3.375, "y":3, "w":1.25}, {"label":"Shift", "x":4.625, "y":3, "w":2.25}, {"x":6.875, "y":3, "w":1.25}, {"x":8.125, "y":3, "w":1.5}, {"label":"Menu", "x":9.625, "y":3}, {"label":"Fn", "x":10.63, "y":3, "w":1.25}]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,16 +15,16 @@ You should have received a copy of the GNU General Public License
|
|||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "pearl.h"
|
#include QMK_KEYBOARD_H
|
||||||
|
|
||||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
[0] = KEYMAP(
|
[0] = LAYOUT(
|
||||||
KC_GESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_BSPC,
|
KC_GESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_BSPC,
|
||||||
KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,
|
KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,
|
||||||
MT(MOD_LSFT, KC_CAPS), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT,
|
MT(MOD_LSFT, KC_CAPS), 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_LALT, KC_LGUI, KC_LSFT, KC_SPC, KC_SPC, KC_APP, MO(1)
|
KC_LCTL, KC_LALT, KC_LGUI, KC_LSFT, KC_SPC, KC_SPC, KC_APP, MO(1)
|
||||||
),
|
),
|
||||||
[1] = KEYMAP(
|
[1] = LAYOUT(
|
||||||
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_EQL, KC_SLEP,
|
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_EQL, KC_SLEP,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_QUOT, KC_BSLS,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_UP, KC_QUOT, KC_BSLS,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS,
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
#include "pearl.h"
|
#include QMK_KEYBOARD_H
|
||||||
|
|
||||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
[0] = KEYMAP(
|
[0] = LAYOUT(
|
||||||
KC_GESC, 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_GESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_LBRC, KC_RBRC,
|
||||||
LT(2, KC_TAB), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, LT(2,KC_ENT),
|
LT(2, KC_TAB), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, LT(2,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_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_BSPC, KC_NO, LT(1, KC_SPC), MO(3), KC_RALT
|
KC_LCTL, KC_LGUI, KC_LALT, KC_BSPC, KC_NO, LT(1, KC_SPC), MO(3), KC_RALT
|
||||||
),
|
),
|
||||||
[1] = KEYMAP(
|
[1] = LAYOUT(
|
||||||
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_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_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_QUOT, KC_TRNS,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_QUOT, KC_TRNS,
|
||||||
KC_TRNS, RGB_TOG, RGB_SMOD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BSLS, KC_TRNS,
|
KC_TRNS, RGB_TOG, RGB_SMOD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_BSLS, KC_TRNS,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_DEL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_DEL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
|
||||||
),
|
),
|
||||||
[2] = KEYMAP(
|
[2] = LAYOUT(
|
||||||
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_UNDS, KC_PLUS,
|
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, KC_UNDS, KC_PLUS,
|
||||||
KC_TRNS, RGB_SAI, RGB_SAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_DQUO, KC_TRNS,
|
KC_TRNS, RGB_SAI, RGB_SAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_HOME, KC_PGDN, KC_PGUP, KC_END, KC_DQUO, KC_TRNS,
|
||||||
KC_TRNS, RGB_HUI, RGB_HUD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PIPE, KC_TRNS,
|
KC_TRNS, RGB_HUI, RGB_HUD, RGB_VAI, RGB_VAD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_PIPE, KC_TRNS,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_DEL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_DEL, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS
|
||||||
),
|
),
|
||||||
[3] = KEYMAP(
|
[3] = LAYOUT(
|
||||||
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS, RESET,
|
KC_TRNS, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_TRNS, RESET,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||||
KC_TRNS, BL_TOGG, KC_TRNS, BL_INC, BL_DEC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
KC_TRNS, BL_TOGG, KC_TRNS, BL_INC, BL_DEC, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||||
|
|||||||
@@ -23,40 +23,40 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#define _FN2 4
|
#define _FN2 4
|
||||||
#define LIGHT 5
|
#define LIGHT 5
|
||||||
|
|
||||||
#include "pearl.h"
|
#include QMK_KEYBOARD_H
|
||||||
|
|
||||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
[COLEMAK] = KEYMAP(
|
[COLEMAK] = LAYOUT(
|
||||||
KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_NO, KC_BSPC,
|
KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_SCLN, KC_NO, KC_BSPC,
|
||||||
LGUI_T(KC_ESC), KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT,
|
LGUI_T(KC_ESC), KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, KC_QUOT,
|
||||||
LSFT_T(KC_DEL), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, RSFT_T(KC_ENT),
|
LSFT_T(KC_DEL), KC_Z, KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH, RSFT_T(KC_ENT),
|
||||||
KC_LCTL, KC_LGUI, KC_LALT, LT(_FN1, KC_SPC), KC_NO, LT(_FN2, KC_SPC), TG(QWERTY), TG(WIN)
|
KC_LCTL, KC_LGUI, KC_LALT, LT(_FN1, KC_SPC), KC_NO, LT(_FN2, KC_SPC), TG(QWERTY), TG(WIN)
|
||||||
),
|
),
|
||||||
[QWERTY] = KEYMAP(
|
[QWERTY] = LAYOUT(
|
||||||
KC_TRNS, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_NO, KC_TRNS,
|
KC_TRNS, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_NO, KC_TRNS,
|
||||||
KC_TRNS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_TRNS,
|
KC_TRNS, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_TRNS,
|
||||||
KC_TRNS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_TRNS,
|
KC_TRNS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_TRNS,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS
|
||||||
),
|
),
|
||||||
[WIN] = KEYMAP(
|
[WIN] = LAYOUT(
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS,
|
||||||
LCTL_T(KC_ESC), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
LCTL_T(KC_ESC), KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS,
|
||||||
KC_LGUI, KC_LALT, KC_LCTL, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS
|
KC_LGUI, KC_LALT, KC_LCTL, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS
|
||||||
),
|
),
|
||||||
[_FN1] = KEYMAP(
|
[_FN1] = LAYOUT(
|
||||||
KC_GRV, KC_MNXT, KC_NO, KC_PIPE, KC_PLUS, KC_LBRC, KC_RBRC, KC_HOME, KC_UP, KC_END, KC_PGUP, KC_NO, KC_TRNS,
|
KC_GRV, KC_MNXT, KC_NO, KC_PIPE, KC_PLUS, KC_LBRC, KC_RBRC, KC_HOME, KC_UP, KC_END, KC_PGUP, KC_NO, KC_TRNS,
|
||||||
KC_TRNS, KC_MPLY, KC_SPC, KC_UNDS, KC_EQUAL, KC_LPRN, KC_RPRN, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDOWN, KC_TRNS,
|
KC_TRNS, KC_MPLY, KC_SPC, KC_UNDS, KC_EQUAL, KC_LPRN, KC_RPRN, KC_LEFT, KC_DOWN, KC_RGHT, KC_PGDOWN, KC_TRNS,
|
||||||
KC_TRNS, KC_MPRV, KC_NO, KC_BSLS, KC_MINUS, KC_LCBR, KC_RCBR, KC_NO, KC_MUTE, KC_VOLU, KC_VOLD, KC_CAPS,
|
KC_TRNS, KC_MPRV, KC_NO, KC_BSLS, KC_MINUS, KC_LCBR, KC_RCBR, KC_NO, KC_MUTE, KC_VOLU, KC_VOLD, KC_CAPS,
|
||||||
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS
|
KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS
|
||||||
),
|
),
|
||||||
[_FN2] = KEYMAP(
|
[_FN2] = LAYOUT(
|
||||||
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LBRC, KC_RBRC, KC_NO, KC_TRNS,
|
KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_LBRC, KC_RBRC, KC_NO, KC_TRNS,
|
||||||
KC_TRNS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_TRNS,
|
KC_TRNS, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_TRNS,
|
||||||
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_F9, KC_F10, KC_F11, KC_F12, KC_CAPS,
|
KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_F9, KC_F10, KC_F11, KC_F12, KC_CAPS,
|
||||||
TG(LIGHT), KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS
|
TG(LIGHT), KC_TRNS, KC_TRNS, KC_TRNS, KC_NO, KC_TRNS, KC_TRNS, KC_TRNS
|
||||||
),
|
),
|
||||||
[LIGHT] = KEYMAP(
|
[LIGHT] = LAYOUT(
|
||||||
RESET, KC_NO, BL_ON, BL_INC, BL_BRTG, RGB_M_P, RGB_M_B, RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, KC_NO, KC_NO,
|
RESET, KC_NO, BL_ON, BL_INC, BL_BRTG, RGB_M_P, RGB_M_B, RGB_MOD, RGB_HUI, RGB_SAI, RGB_VAI, KC_NO, KC_NO,
|
||||||
KC_NO, KC_NO, BL_TOGG, BL_STEP, KC_NO, RGB_M_SN, RGB_M_K, RGB_TOG, RGB_HUD, RGB_SAD, RGB_VAD, KC_NO,
|
KC_NO, KC_NO, BL_TOGG, BL_STEP, KC_NO, RGB_M_SN, RGB_M_K, RGB_TOG, RGB_HUD, RGB_SAD, RGB_VAD, KC_NO,
|
||||||
KC_NO, KC_NO, BL_OFF, BL_DEC, KC_NO, KC_NO, KC_NO, RGB_RMOD, RGB_M_SW, RGB_M_R, RGB_M_G, KC_NO,
|
KC_NO, KC_NO, BL_OFF, BL_DEC, KC_NO, KC_NO, KC_NO, RGB_RMOD, RGB_M_SW, RGB_M_R, RGB_M_G, KC_NO,
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
#include "pearl.h"
|
#include QMK_KEYBOARD_H
|
||||||
|
|
||||||
#define ____ KC_TRNS
|
#define ____ KC_TRNS
|
||||||
|
|
||||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
// BASE LAYER
|
// BASE LAYER
|
||||||
[0] = KEYMAP(
|
[0] = LAYOUT(
|
||||||
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_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,
|
||||||
MO(2), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,
|
MO(2), KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_ENT,
|
||||||
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MO(3),
|
KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, MO(3),
|
||||||
KC_LCTL, KC_LALT, KC_BSPC, MO(1), MO(1), KC_SPC, KC_RALT, KC_LGUI
|
KC_LCTL, KC_LALT, KC_BSPC, MO(1), MO(1), KC_SPC, KC_RALT, KC_LGUI
|
||||||
),
|
),
|
||||||
// BASE LAYER TWO (Fn1)
|
// BASE LAYER TWO (Fn1)
|
||||||
[1] = KEYMAP(
|
[1] = LAYOUT(
|
||||||
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_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_QUOT, KC_BSLS,
|
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, KC_QUOT, KC_BSLS,
|
||||||
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, KC_RSFT,
|
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, KC_RSFT,
|
||||||
____, ____, ____, ____, ____, ____, ____, ____
|
____, ____, ____, ____, ____, ____, ____, ____
|
||||||
),
|
),
|
||||||
// FROW LAYER AND ARROWS (Fn2)
|
// FROW LAYER AND ARROWS (Fn2)
|
||||||
[2] = KEYMAP(
|
[2] = LAYOUT(
|
||||||
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_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_UP, ____, ____,
|
____, ____, ____, ____, ____, ____, ____, ____, ____, KC_UP, ____, ____,
|
||||||
____, ____, ____, ____, ____, ____, ____, ____, KC_LEFT, KC_DOWN,KC_RGHT, MO(4),
|
____, ____, ____, ____, ____, ____, ____, ____, KC_LEFT, KC_DOWN,KC_RGHT, MO(4),
|
||||||
____, ____, ____, ____, ____, ____, ____, ____
|
____, ____, ____, ____, ____, ____, ____, ____
|
||||||
),
|
),
|
||||||
// MEDIA AND RGB (Fn3)
|
// MEDIA AND RGB (Fn3)
|
||||||
[3] = KEYMAP(
|
[3] = LAYOUT(
|
||||||
____, ____, ____, ____, ____, ____, ____, ____, ____, KC_MPRV,KC_MPLY, KC_MNXT, KC_DEL,
|
____, ____, ____, ____, ____, ____, ____, ____, ____, KC_MPRV,KC_MPLY, KC_MNXT, KC_DEL,
|
||||||
____, ____, ____, RGB_HUI, RGB_SAI,RGB_VAI,____, ____, ____, ____, ____, ____,
|
____, ____, ____, RGB_HUI, RGB_SAI,RGB_VAI,____, ____, ____, ____, ____, ____,
|
||||||
____, RGB_MOD, RGB_TOG, RGB_HUD, RGB_SAD,RGB_VAD,____, ____, ____, ____, ____, ____,
|
____, RGB_MOD, RGB_TOG, RGB_HUD, RGB_SAD,RGB_VAD,____, ____, ____, ____, ____, ____,
|
||||||
____, ____, ____, ____, ____, ____, ____, ____
|
____, ____, ____, ____, ____, ____, ____, ____
|
||||||
),
|
),
|
||||||
// UTIL (Fn1+Fn3)
|
// UTIL (Fn1+Fn3)
|
||||||
[4] = KEYMAP(
|
[4] = LAYOUT(
|
||||||
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, KC_PSCR, ____,
|
____, ____, ____, ____, ____, ____, ____, ____, ____, ____, ____, KC_PSCR, ____,
|
||||||
____, ____, ____, ____, ____, ____, ____, ____, ____, KC_PGUP,____, ____,
|
____, ____, ____, ____, ____, ____, ____, ____, ____, KC_PGUP,____, ____,
|
||||||
____, ____, ____, ____, ____, ____, ____, ____, KC_HOME, KC_PGDN,KC_END, ____,
|
____, ____, ____, ____, ____, ____, ____, ____, KC_HOME, KC_PGDN,KC_END, ____,
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
#include "quantum.h"
|
#include "quantum.h"
|
||||||
#include "pearl.h"
|
#include "pearl.h"
|
||||||
|
|
||||||
#define KEYMAP( \
|
#define LAYOUT( \
|
||||||
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C,\
|
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0A, K0B, K0C,\
|
||||||
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \
|
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1A, K1B, \
|
||||||
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B,\
|
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2A, K2B,\
|
||||||
|
|||||||
@@ -34,12 +34,13 @@ enum planck_keycodes {
|
|||||||
COLEMAK,
|
COLEMAK,
|
||||||
DVORAK,
|
DVORAK,
|
||||||
PLOVER,
|
PLOVER,
|
||||||
LOWER,
|
|
||||||
RAISE,
|
|
||||||
BACKLIT,
|
BACKLIT,
|
||||||
EXT_PLV
|
EXT_PLV
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define LOWER MO(_LOWER)
|
||||||
|
#define RAISE MO(_RAISE)
|
||||||
|
|
||||||
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
|
|
||||||
/* Qwerty
|
/* Qwerty
|
||||||
@@ -177,6 +178,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
|||||||
float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND);
|
float plover_gb_song[][2] = SONG(PLOVER_GOODBYE_SOUND);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uint32_t layer_state_set_user(uint32_t state) {
|
||||||
|
return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST);
|
||||||
|
}
|
||||||
|
|
||||||
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
switch (keycode) {
|
switch (keycode) {
|
||||||
case QWERTY:
|
case QWERTY:
|
||||||
@@ -198,26 +203,6 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
break;
|
break;
|
||||||
case LOWER:
|
|
||||||
if (record->event.pressed) {
|
|
||||||
layer_on(_LOWER);
|
|
||||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
|
||||||
} else {
|
|
||||||
layer_off(_LOWER);
|
|
||||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case RAISE:
|
|
||||||
if (record->event.pressed) {
|
|
||||||
layer_on(_RAISE);
|
|
||||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
|
||||||
} else {
|
|
||||||
layer_off(_RAISE);
|
|
||||||
update_tri_layer(_LOWER, _RAISE, _ADJUST);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
case BACKLIT:
|
case BACKLIT:
|
||||||
if (record->event.pressed) {
|
if (record->event.pressed) {
|
||||||
register_code(KC_RSFT);
|
register_code(KC_RSFT);
|
||||||
|
|||||||
@@ -42,8 +42,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
* ROW2COL = ROW = Anode (+), COL = Cathode (-, marked on diode)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
#define MATRIX_ROW_PINS { D3, F1, C7, F2, C6, F3, C5, F4, C4, F5, C3, F6, C2, F7, C1 }
|
#define MATRIX_ROW_PINS { D5, F1, C7, F2, C6, F3, C5, F4, C4, F5, C3, F6, C2, F7, C1 }
|
||||||
#define MATRIX_COL_PINS { D4, D5, D7, B7, D0, D1, D2, C0, F0, B4, B5, B6, E1, E7, E0 }
|
#define MATRIX_COL_PINS { D6, D7, E0, B7, D2, D3, D4, E6, F0, B4, B5, B6, C0, E7, E1 }
|
||||||
#define UNUSED_PINS
|
#define UNUSED_PINS
|
||||||
|
|
||||||
/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
|
/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
|
||||||
@@ -53,6 +53,14 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||||||
// #define BACKLIGHT_BREATHING
|
// #define BACKLIGHT_BREATHING
|
||||||
// #define BACKLIGHT_LEVELS 3
|
// #define BACKLIGHT_LEVELS 3
|
||||||
|
|
||||||
|
// ws2812 options
|
||||||
|
//#define RGB_DI_PIN A0 // pin the DI on the ws2812 is hooked-up to
|
||||||
|
//#define RGBLIGHT_ANIMATIONS // run RGB animations
|
||||||
|
//#define RGBLED_NUM 6 // number of LEDs
|
||||||
|
//#define RGBLIGHT_HUE_STEP 12 // units to step when in/decreasing hue
|
||||||
|
//#define RGBLIGHT_SAT_STEP 25 // units to step when in/decresing saturation
|
||||||
|
//#define RGBLIGHT_VAL_STEP 12 // units to step when in/decreasing value (brightness)
|
||||||
|
|
||||||
|
|
||||||
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
||||||
#define DEBOUNCING_DELAY 5
|
#define DEBOUNCING_DELAY 5
|
||||||
|
|||||||
@@ -0,0 +1,420 @@
|
|||||||
|
#include <FastGPIO.h>
|
||||||
|
#include <TimerOne.h>
|
||||||
|
|
||||||
|
int iByte;
|
||||||
|
byte col = 0;
|
||||||
|
byte leds[12][4];
|
||||||
|
byte pass = 1;
|
||||||
|
int fadecount = 1;
|
||||||
|
const int fadelimit = 3000;
|
||||||
|
const int fadelimitshort = 1000;
|
||||||
|
byte mode = 4;
|
||||||
|
byte brightness = 2;
|
||||||
|
boolean changemode = 0;
|
||||||
|
int rain = 0;
|
||||||
|
const int rainlimit = 5000;
|
||||||
|
const int rainfade = 5000;
|
||||||
|
byte rx = 0;
|
||||||
|
byte ry = 0;
|
||||||
|
|
||||||
|
// pin[xx] on led matrix connected to nn on Arduino (-1 is dummy to make array start at pos 1)
|
||||||
|
int pins[17] = {
|
||||||
|
-1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 16, 14, 15, 18, 19, 20, 21
|
||||||
|
};
|
||||||
|
|
||||||
|
// col[xx] of leds = pin yy on led matrix
|
||||||
|
int cols[12] = {
|
||||||
|
pins[8], pins[7], pins[6], pins[5], pins[9], pins[10], pins[11], pins[12], pins[13], pins[14], pins[15], pins[16]
|
||||||
|
};
|
||||||
|
|
||||||
|
// row[xx] of leds = pin yy on led matrix
|
||||||
|
int rows[4] = {
|
||||||
|
pins[1], pins[2], pins[3], pins[4]
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define DELAY 0
|
||||||
|
extern byte leds[12][4];
|
||||||
|
|
||||||
|
void setup() {
|
||||||
|
Serial1.begin(9600);
|
||||||
|
setupLeds();
|
||||||
|
for (int s = 0; s < 5; s++) {
|
||||||
|
for ( int r = 1; r < 9; r++) {
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
leds[i][j] = 1;
|
||||||
|
for (int p = 0; p < 25; p++) {
|
||||||
|
}
|
||||||
|
leds[i][j] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( int r = 9; r > 0; r--) {
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
leds[i][j] = 1;
|
||||||
|
for (int p = 0; p < 25; p++) {
|
||||||
|
}
|
||||||
|
leds[i][j] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void loop() {
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case 0:
|
||||||
|
//Blacklight
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
leds[i][j] = brightness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkserial();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
//Breathing
|
||||||
|
for ( int r = 1; r < 9; r++) {
|
||||||
|
checkserial();
|
||||||
|
if (changemode == 0) {
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
leds[i][j] = 1;
|
||||||
|
for (int p = 0; p < 25; p++) {
|
||||||
|
}
|
||||||
|
leds[i][j] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( int r = 9; r > 0; r--) {
|
||||||
|
checkserial();
|
||||||
|
if (changemode == 0) {
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
leds[i][j] = 1;
|
||||||
|
for (int p = 0; p < 25; p++) {
|
||||||
|
}
|
||||||
|
leds[i][j] = r;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for ( int r = 1; r < 30; r++) {
|
||||||
|
checkserial();
|
||||||
|
if (changemode == 0) {
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
delayMicroseconds(65000);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
//Random
|
||||||
|
leds[random(12)][random(4)] = random(8);
|
||||||
|
delayMicroseconds(10000);
|
||||||
|
checkserial();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
//Rain
|
||||||
|
rain++;
|
||||||
|
if (rain > rainlimit) {
|
||||||
|
rain = 0;
|
||||||
|
rx = random(12);
|
||||||
|
ry = random(4);
|
||||||
|
if (leds[rx][ry] == 0) {
|
||||||
|
leds[rx][ry] = 18;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fadecount++;
|
||||||
|
if (fadecount > rainfade) {
|
||||||
|
fadecount = 1;
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
if (leds[i][j] > 0) {
|
||||||
|
leds[i][j] = leds[i][j] - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkserial();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
//Reactive
|
||||||
|
fadecount++;
|
||||||
|
if (fadecount > fadelimit) {
|
||||||
|
fadecount = 1;
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
if (leds[i][j] > 0) {
|
||||||
|
leds[i][j] = leds[i][j] - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkserial();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
//Reactive Target
|
||||||
|
fadecount++;
|
||||||
|
if (fadecount > fadelimitshort) {
|
||||||
|
fadecount = 1;
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
if (leds[i][j] > 0) {
|
||||||
|
leds[i][j] = leds[i][j] - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkserial();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mode = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
changemode = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void checkserial() {
|
||||||
|
if (Serial1.available() > 0) {
|
||||||
|
iByte = Serial1.read();
|
||||||
|
if (iByte == 100) {
|
||||||
|
brightness++;
|
||||||
|
if (brightness > 9) {
|
||||||
|
brightness = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (iByte == 101) {
|
||||||
|
mode++;
|
||||||
|
}
|
||||||
|
if (iByte < 100) {
|
||||||
|
if (mode == 4) {
|
||||||
|
byte row = iByte / 16;
|
||||||
|
byte col = iByte % 16;
|
||||||
|
leds[col][row] = 18;
|
||||||
|
}
|
||||||
|
if (mode == 5) {
|
||||||
|
byte row = iByte / 16;
|
||||||
|
byte col = iByte % 16;
|
||||||
|
for (byte i = 0; i < 12; i++) {
|
||||||
|
leds[i][row] = 18;
|
||||||
|
}
|
||||||
|
for (byte p = 0; p < 4; p++) {
|
||||||
|
leds[col][p] = 18;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupLeds() {
|
||||||
|
// sets the pins as output
|
||||||
|
FastGPIO::Pin<2>::setOutputLow();
|
||||||
|
FastGPIO::Pin<3>::setOutputLow();
|
||||||
|
FastGPIO::Pin<4>::setOutputLow();
|
||||||
|
FastGPIO::Pin<5>::setOutputLow();
|
||||||
|
FastGPIO::Pin<6>::setOutputLow();
|
||||||
|
FastGPIO::Pin<7>::setOutputLow();
|
||||||
|
FastGPIO::Pin<8>::setOutputLow();
|
||||||
|
FastGPIO::Pin<9>::setOutputLow();
|
||||||
|
FastGPIO::Pin<10>::setOutputLow();
|
||||||
|
FastGPIO::Pin<16>::setOutputLow();
|
||||||
|
FastGPIO::Pin<14>::setOutputLow();
|
||||||
|
FastGPIO::Pin<15>::setOutputLow();
|
||||||
|
FastGPIO::Pin<18>::setOutputLow();
|
||||||
|
FastGPIO::Pin<19>::setOutputLow();
|
||||||
|
FastGPIO::Pin<20>::setOutputLow();
|
||||||
|
FastGPIO::Pin<21>::setOutputLow();
|
||||||
|
|
||||||
|
// set up Cols
|
||||||
|
FastGPIO::Pin<6>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<7>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<8>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<9>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<10>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<16>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<14>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<15>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<18>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<19>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<20>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<21>::setOutputValueLow();
|
||||||
|
|
||||||
|
// set up Rows
|
||||||
|
FastGPIO::Pin<2>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<3>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<4>::setOutputValueLow();
|
||||||
|
FastGPIO::Pin<5>::setOutputValueLow();
|
||||||
|
|
||||||
|
clearLeds();
|
||||||
|
Timer1.initialize(25);
|
||||||
|
Timer1.attachInterrupt(display);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearLeds() {
|
||||||
|
// Clear display array
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
leds[i][j] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onLeds() {
|
||||||
|
// Clear display array
|
||||||
|
for (int i = 0; i < 12; i++) {
|
||||||
|
for (int j = 0; j < 4; j++) {
|
||||||
|
leds[i][j] = 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interrupt routine
|
||||||
|
void display() {
|
||||||
|
|
||||||
|
switch (col) { // Turn whole previous column off
|
||||||
|
case 0:
|
||||||
|
FastGPIO::Pin<6>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
FastGPIO::Pin<7>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
FastGPIO::Pin<8>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
FastGPIO::Pin<9>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
FastGPIO::Pin<10>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
FastGPIO::Pin<16>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
FastGPIO::Pin<14>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
FastGPIO::Pin<15>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
FastGPIO::Pin<18>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
FastGPIO::Pin<19>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
FastGPIO::Pin<20>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
FastGPIO::Pin<21>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
col++;
|
||||||
|
if (col == 12) {
|
||||||
|
col = 0;
|
||||||
|
pass++;
|
||||||
|
if (pass > 8) {
|
||||||
|
pass = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int row = 0; row < 4; row++) {
|
||||||
|
if (leds[col][row] > pass) {
|
||||||
|
switch (row) { // Turn on this led
|
||||||
|
case 0:
|
||||||
|
FastGPIO::Pin<2>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
FastGPIO::Pin<3>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
FastGPIO::Pin<4>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
FastGPIO::Pin<5>::setOutputValueLow();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
switch (row) { // Turn off this led
|
||||||
|
case 0:
|
||||||
|
FastGPIO::Pin<2>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
FastGPIO::Pin<3>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
FastGPIO::Pin<4>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
FastGPIO::Pin<5>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
switch (col) { // Turn column on
|
||||||
|
case 0:
|
||||||
|
FastGPIO::Pin<6>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
FastGPIO::Pin<7>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
FastGPIO::Pin<8>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
FastGPIO::Pin<9>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
FastGPIO::Pin<10>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
FastGPIO::Pin<16>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
FastGPIO::Pin<14>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
FastGPIO::Pin<15>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
FastGPIO::Pin<18>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
FastGPIO::Pin<19>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 10:
|
||||||
|
FastGPIO::Pin<20>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
FastGPIO::Pin<21>::setOutputValueHigh();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Carlos Filoteo
|
||||||
|
|
||||||
|
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 0x0000
|
||||||
|
#define DEVICE_VER 0x0001
|
||||||
|
#define MANUFACTURER 40percent.club
|
||||||
|
#define PRODUCT ut47
|
||||||
|
#define DESCRIPTION An awesome 40% keyboard
|
||||||
|
|
||||||
|
/* key matrix size */
|
||||||
|
#define MATRIX_ROWS 4
|
||||||
|
#define MATRIX_COLS 12
|
||||||
|
|
||||||
|
#define MATRIX_ROW_PINS { D1, D0, D4, C6 }
|
||||||
|
#define MATRIX_COL_PINS { D7, E6, B4, B5, B6, B2, B3, B1, F7, F6, F5, F4 }
|
||||||
|
#define UNUSED_PINS
|
||||||
|
|
||||||
|
/* COL2ROW, ROW2COL, or CUSTOM_MATRIX */
|
||||||
|
#define DIODE_DIRECTION COL2ROW
|
||||||
|
|
||||||
|
// #define BACKLIGHT_PIN B7
|
||||||
|
// #define BACKLIGHT_BREATHING
|
||||||
|
// #define BACKLIGHT_LEVELS 3
|
||||||
|
|
||||||
|
/* Debounce reduces chatter (unintended double-presses) - set 0 if debouncing is not needed */
|
||||||
|
#define DEBOUNCING_DELAY 5
|
||||||
|
|
||||||
|
/* define if matrix has ghost (lacks anti-ghosting diodes) */
|
||||||
|
//#define MATRIX_HAS_GHOST
|
||||||
|
|
||||||
|
/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */
|
||||||
|
#define LOCKING_SUPPORT_ENABLE
|
||||||
|
/* Locking resynchronize hack */
|
||||||
|
#define LOCKING_RESYNC_ENABLE
|
||||||
|
|
||||||
|
/* key combination for magic key command */
|
||||||
|
#define IS_COMMAND() ( \
|
||||||
|
keyboard_report->mods == (MOD_BIT(KC_LSHIFT) | MOD_BIT(KC_RSHIFT)) \
|
||||||
|
)
|
||||||
|
|
||||||
|
/* Enable GNAP matrix serial output */
|
||||||
|
#define GNAP_ENABLE
|
||||||
|
|
||||||
|
/* USART configuration */
|
||||||
|
#ifdef __AVR_ATmega32U4__
|
||||||
|
# define SERIAL_UART_BAUD 9600
|
||||||
|
# define SERIAL_UART_DATA UDR1
|
||||||
|
# define SERIAL_UART_UBRR (F_CPU / (16UL * SERIAL_UART_BAUD) - 1)
|
||||||
|
# define SERIAL_UART_RXD_VECT USART1_RX_vect
|
||||||
|
# define SERIAL_UART_TXD_READY (UCSR1A & _BV(UDRE1))
|
||||||
|
# define SERIAL_UART_INIT() do { \
|
||||||
|
/* baud rate */ \
|
||||||
|
UBRR1L = SERIAL_UART_UBRR; \
|
||||||
|
/* baud rate */ \
|
||||||
|
UBRR1H = SERIAL_UART_UBRR >> 8; \
|
||||||
|
/* enable TX */ \
|
||||||
|
UCSR1B = _BV(TXEN1); \
|
||||||
|
/* 8-bit data */ \
|
||||||
|
UCSR1C = _BV(UCSZ11) | _BV(UCSZ10); \
|
||||||
|
sei(); \
|
||||||
|
} while(0)
|
||||||
|
# else
|
||||||
|
# error "USART configuration is needed."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/* Copyright 2018 Carlos Filoteo
|
||||||
|
*
|
||||||
|
* 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_USER_H
|
||||||
|
#define CONFIG_USER_H
|
||||||
|
|
||||||
|
#include "config_common.h"
|
||||||
|
|
||||||
|
// place overrides here
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/* Copyright 2018 Carlos Filoteo
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
#ifdef LED_ENABLE
|
||||||
|
#include "protocol/serial.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define _______ KC_TRNS
|
||||||
|
#define LT3_TAB LT(3, KC_TAB)
|
||||||
|
#define MT_RSFT_ENT MT(MOD_RSFT, KC_ENT)
|
||||||
|
|
||||||
|
enum custom_keycodes {
|
||||||
|
LED_TOG = SAFE_RANGE,
|
||||||
|
LED_CHG
|
||||||
|
};
|
||||||
|
|
||||||
|
const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
|
||||||
|
|
||||||
|
LAYOUT(
|
||||||
|
KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BSPC,
|
||||||
|
LT3_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, 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, MT_RSFT_ENT,
|
||||||
|
KC_LCTL, KC_LALT, KC_LGUI, KC_APP, MO(2), KC_SPC, MO(1), KC_LEFT, KC_DOWN, KC_UP, KC_RGHT
|
||||||
|
),
|
||||||
|
|
||||||
|
LAYOUT(
|
||||||
|
KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_DELETE,
|
||||||
|
_______, _______, _______, _______, _______, _______, _______, KC_MINS, KC_EQL, KC_LBRC, KC_RBRC, KC_BSLS,
|
||||||
|
_______, KC_F11, KC_F12, KC_F13, KC_F14, KC_F15, KC_F16, KC_F17, KC_F18, KC_F19, KC_F20, _______,
|
||||||
|
_______, _______, _______, KC_CAPS, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END
|
||||||
|
),
|
||||||
|
|
||||||
|
LAYOUT(
|
||||||
|
KC_FN6, KC_FN7, KC_FN8, KC_FN9, KC_FN10, KC_FN11, KC_FN12, KC_FN13, KC_FN14, KC_FN15, KC_FN16, KC_DELETE,
|
||||||
|
_______, _______, _______, _______, _______, _______, _______, KC_FN17, KC_FN18, KC_FN19, KC_FN20, KC_FN21,
|
||||||
|
_______, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______,
|
||||||
|
_______, _______, _______, KC_CAPS, _______, _______, _______, KC_HOME, KC_PGDN, KC_PGUP, KC_END
|
||||||
|
),
|
||||||
|
|
||||||
|
LAYOUT( /* Tab */
|
||||||
|
KC_ESC, KC_CALC, KC_WHOM, KC_MAIL, KC_MYCM, _______, _______, _______, _______, _______, KC_PSCR, _______,
|
||||||
|
_______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||||
|
_______, LED_TOG, LED_CHG, _______, _______, _______, _______, _______, _______, _______, _______, _______,
|
||||||
|
_______, _______, _______, _______, _______, _______, _______, KC_MS_L, KC_MS_D, KC_MS_U, KC_MS_R
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
//LED keymap functions
|
||||||
|
#ifdef LED_ENABLE
|
||||||
|
void led_chmode(void) {
|
||||||
|
serial_send(101);
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_toggle(void) {
|
||||||
|
serial_send(100);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
if (record->event.pressed) {
|
||||||
|
switch(keycode) {
|
||||||
|
case LED_TOG:
|
||||||
|
#ifdef LED_ENABLE
|
||||||
|
led_toggle();
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
case LED_CHG:
|
||||||
|
#ifdef LED_ENABLE
|
||||||
|
led_chmode();
|
||||||
|
#endif
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# UT47 default keymap
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
[KLE](http://www.keyboard-layout-editor.com/##@@_y:0%3B&=Esc&=Q&=W&=E&=R&=T&=Y&=U&=I&=O&=P&_w:1.5%3B&=Back%20Space&_x:0.25&a:4&f:4&w:4&h:4&d:true%3B&=%3Cb%3EGNAP!%3C%2F%2Fb%3E%3Cp%3E%3Cp%3EMinimum%20stagger%3Cp%3E47%20key%20layout%3B&@_a:7&f:3&w:1.25%3B&=Tab&=A&=S&=D&=F&=G&=H&=J&=K&=L&=%2F%3B&_w:1.25%3B&=%27%3B&@_w:1.5%3B&=Shift&=Z&=X&=C&=V&=B&=N&=M&=,&=.&=%2F%2F&=Return%3B&@=Ctrl&=Alt&=Super&=Menu&_w:1.25%3B&=%2F&dArr%2F%3B&_w:2%3B&=&_w:1.25%3B&=%2F&uArr%2F%3B&=%2F&larr%2F%3B&=%2F&darr%2F%3B&=%2F&uarr%2F%3B&=%2F&rarr%2F%3B%3B&=undefined)
|
||||||
|
|
||||||
|
### LED Controls
|
||||||
|
|
||||||
|
Use <kbd>TAB</kbd>+<kbd>Z</kbd> to cycle through brightness (8 steps)
|
||||||
|
|
||||||
|
Use <kbd>TAB</kbd>+<kbd>X</kbd> to cycle through the following LED modes:
|
||||||
|
|
||||||
|
- solid
|
||||||
|
- breathing
|
||||||
|
- random
|
||||||
|
- rain
|
||||||
|
- reactive
|
||||||
|
- poptang
|
||||||
|
- off
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2012 Jun Wako <[email protected]>
|
||||||
|
|
||||||
|
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 <avr/io.h>
|
||||||
|
#include "stdint.h"
|
||||||
|
#include "led.h"
|
||||||
|
|
||||||
|
|
||||||
|
void led_set(uint8_t usb_led)
|
||||||
|
{
|
||||||
|
if (usb_led & (1<<USB_LED_CAPS_LOCK)) {
|
||||||
|
// output low
|
||||||
|
DDRB |= (1<<0);
|
||||||
|
PORTB &= ~(1<<0);
|
||||||
|
DDRD |= (1<<5);
|
||||||
|
PORTD &= ~(1<<5);
|
||||||
|
} else {
|
||||||
|
// Hi-Z
|
||||||
|
DDRB &= ~(1<<0);
|
||||||
|
PORTB &= ~(1<<0);
|
||||||
|
DDRD &= ~(1<<5);
|
||||||
|
PORTD &= ~(1<<5);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 Carlos Filoteo
|
||||||
|
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* scan matrix
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <avr/io.h>
|
||||||
|
#include <util/delay.h>
|
||||||
|
#include "print.h"
|
||||||
|
#include "debug.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "matrix.h"
|
||||||
|
#include "protocol/serial.h"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef DEBOUNCE
|
||||||
|
# define DEBOUNCE 5
|
||||||
|
#endif
|
||||||
|
static uint8_t debouncing = DEBOUNCE;
|
||||||
|
|
||||||
|
/* 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 read_cols(void);
|
||||||
|
static void init_cols(void);
|
||||||
|
static void unselect_rows(void);
|
||||||
|
static void select_row(uint8_t row);
|
||||||
|
|
||||||
|
|
||||||
|
inline
|
||||||
|
uint8_t matrix_rows(void)
|
||||||
|
{
|
||||||
|
return MATRIX_ROWS;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline
|
||||||
|
uint8_t matrix_cols(void)
|
||||||
|
{
|
||||||
|
return MATRIX_COLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_init(void)
|
||||||
|
{
|
||||||
|
// initialize row and col
|
||||||
|
unselect_rows();
|
||||||
|
init_cols();
|
||||||
|
|
||||||
|
// initialize matrix state: all keys off
|
||||||
|
for (uint8_t i=0; i < MATRIX_ROWS; i++) {
|
||||||
|
matrix[i] = 0;
|
||||||
|
matrix_debouncing[i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
serial_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t matrix_scan(void)
|
||||||
|
{
|
||||||
|
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||||
|
select_row(i);
|
||||||
|
_delay_us(30); // without this wait read unstable value.
|
||||||
|
matrix_row_t cols = read_cols();
|
||||||
|
if (matrix_debouncing[i] != cols) {
|
||||||
|
matrix_debouncing[i] = cols;
|
||||||
|
if (debouncing) {
|
||||||
|
debug("bounce!: "); debug_hex(debouncing); debug("\n");
|
||||||
|
}
|
||||||
|
debouncing = DEBOUNCE;
|
||||||
|
}
|
||||||
|
unselect_rows();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (debouncing) {
|
||||||
|
if (--debouncing) {
|
||||||
|
_delay_ms(1);
|
||||||
|
} else {
|
||||||
|
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||||
|
matrix[i] = matrix_debouncing[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool matrix_is_modified(void)
|
||||||
|
{
|
||||||
|
if (debouncing) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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("\nr/c 0123456789ABCDEF\n");
|
||||||
|
for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
|
||||||
|
phex(row); print(": ");
|
||||||
|
pbin_reverse16(matrix_get_row(row));
|
||||||
|
print("\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t matrix_key_count(void)
|
||||||
|
{
|
||||||
|
uint8_t count = 0;
|
||||||
|
for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
|
||||||
|
count += bitpop16(matrix[i]);
|
||||||
|
}
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Column pin configuration
|
||||||
|
* col: 0 1 2 3 4 5 6 7 8 9 10 11
|
||||||
|
* pin: D7 E6 B4 B5 B6 B2 B3 B1 F7 F6 F5 F4
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void init_cols(void)
|
||||||
|
{
|
||||||
|
// Input with pull-up(DDR:0, PORT:1)
|
||||||
|
DDRF &= ~(1<<4 | 1<<5 | 1<<6 | 1<<7);
|
||||||
|
PORTF |= (1<<4 | 1<<5 | 1<<6 | 1<<7);
|
||||||
|
DDRE &= ~(1<<6);
|
||||||
|
PORTE |= (1<<6);
|
||||||
|
DDRD &= ~(1<<7);
|
||||||
|
PORTD |= (1<<7);
|
||||||
|
DDRB &= ~(1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6);
|
||||||
|
PORTB |= (1<<1 | 1<<2 | 1<<3 | 1<<4 | 1<<5 | 1<<6);
|
||||||
|
}
|
||||||
|
|
||||||
|
static matrix_row_t read_cols(void)
|
||||||
|
{
|
||||||
|
return (PIND&(1<<7) ? 0 : (1<<0)) |
|
||||||
|
(PINE&(1<<6) ? 0 : (1<<1)) |
|
||||||
|
(PINB&(1<<4) ? 0 : (1<<2)) |
|
||||||
|
(PINB&(1<<5) ? 0 : (1<<3)) |
|
||||||
|
(PINB&(1<<6) ? 0 : (1<<4)) |
|
||||||
|
(PINB&(1<<2) ? 0 : (1<<5)) |
|
||||||
|
(PINB&(1<<3) ? 0 : (1<<6)) |
|
||||||
|
(PINB&(1<<1) ? 0 : (1<<7)) |
|
||||||
|
(PINF&(1<<7) ? 0 : (1<<8)) |
|
||||||
|
(PINF&(1<<6) ? 0 : (1<<9)) |
|
||||||
|
(PINF&(1<<5) ? 0 : (1<<10)) |
|
||||||
|
(PINF&(1<<4) ? 0 : (1<<11));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Row pin configuration
|
||||||
|
* row: 0 1 2 3
|
||||||
|
* pin: D1 D0 D4 C6
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void unselect_rows(void)
|
||||||
|
{
|
||||||
|
// Hi-Z(DDR:0, PORT:0) to unselect
|
||||||
|
DDRD &= ~0b00010011;
|
||||||
|
PORTD &= ~0b00010011;
|
||||||
|
DDRC &= ~0b01000000;
|
||||||
|
PORTC &= ~0b01000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void select_row(uint8_t row)
|
||||||
|
{
|
||||||
|
// Output low(DDR:1, PORT:0) to select
|
||||||
|
switch (row) {
|
||||||
|
case 0:
|
||||||
|
DDRD |= (1<<1);
|
||||||
|
PORTD &= ~(1<<1);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
DDRD |= (1<<0);
|
||||||
|
PORTD &= ~(1<<0);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
DDRD |= (1<<4);
|
||||||
|
PORTD &= ~(1<<4);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
DDRC |= (1<<6);
|
||||||
|
PORTC &= ~(1<<6);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# ut47
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
Somewhere between ortholinear and standard offset. Created to have all the same functions on a Planck in a keyboard but with a more conventional keyboard row stagger.
|
||||||
|
|
||||||
|
Keyboard Maintainer: [filoxo](https://github.com/filoxo), [network_operations]
|
||||||
|
|
||||||
|
Hardware Supported: [PCB design](http://www.40percent.club/2016/10/gnap-20-plateless.html), Arduino Pro Micro
|
||||||
|
|
||||||
|
Hardware Availability: [How to order](http://www.40percent.club/2017/03/ordering-pcb.html)
|
||||||
|
|
||||||
|
### Instructions
|
||||||
|
|
||||||
|
To flash the UT47 without LEDs (single controller), run:
|
||||||
|
|
||||||
|
make ut47:default
|
||||||
|
|
||||||
|
To enable the UT47 LEDs (dual controller), run this for the main controller:
|
||||||
|
|
||||||
|
make ut47:default LED_ENABLE=yes
|
||||||
|
|
||||||
|
Or you can add `LED_ENABLE = yes` to *rules.mk*
|
||||||
|
|
||||||
|
And then flash [LED_controls.ino](LED_controls.ino) to the second controller using [Arduino IDE](https://www.arduino.cc/en/Main/Software) or similar. NOTE: Arduino IDE will require importing additional libraries to compile.
|
||||||
|
|
||||||
|
<small>The reason this is an "opt-in" feature is to prevent sending serial communication over the pin, in case it ends up being used for something else (like RGB underglow).</small>
|
||||||
|
|
||||||
|
### Layout
|
||||||
|
|
||||||
|
Go to the [default layout README](keymaps/default/readme.md) for more information.
|
||||||
|
|
||||||
|
### Additional info
|
||||||
|
|
||||||
|
Credit: Forked from [di0ib TMK version](https://github.com/di0ib/tmk_keyboard/tree/master/keyboard/gnap)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### Build Guide
|
||||||
|
|
||||||
|
[u/network_operations' build guide thread](https://www.reddit.com/r/MechanicalKeyboards/comments/7wqktu/gnap_the_cheap_40/)
|
||||||
@@ -0,0 +1,70 @@
|
|||||||
|
# MCU name
|
||||||
|
#MCU = at90usb1286
|
||||||
|
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)
|
||||||
|
|
||||||
|
# Interrupt driven control endpoint task(+60)
|
||||||
|
OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT
|
||||||
|
|
||||||
|
# Bootloader
|
||||||
|
BOOTLOADER = caterina
|
||||||
|
|
||||||
|
# custom matrix setup
|
||||||
|
CUSTOM_MATRIX = yes
|
||||||
|
SRC += matrix.c protocol/serial_uart.c
|
||||||
|
|
||||||
|
# Build Options
|
||||||
|
# change yes to no to disable
|
||||||
|
#
|
||||||
|
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
|
||||||
|
# Do not enable SLEEP_LED_ENABLE. it uses the same timer as BACKLIGHT_ENABLE
|
||||||
|
SLEEP_LED_ENABLE = no # Breathing sleep LED during USB suspend
|
||||||
|
# if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work
|
||||||
|
NKRO_ENABLE = yes # USB Nkey Rollover
|
||||||
|
BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality on B7 by default
|
||||||
|
MIDI_ENABLE = no # MIDI support (+2400 to 4200, depending on config)
|
||||||
|
UNICODE_ENABLE = no # Unicode
|
||||||
|
BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID
|
||||||
|
AUDIO_ENABLE = no # Audio output on port C6
|
||||||
|
FAUXCLICKY_ENABLE = no # Use buzzer to emulate clicky switches
|
||||||
|
|
||||||
|
ifeq ($(strip $(LED_ENABLE)), yes)
|
||||||
|
OPT_DEFS += -DLED_ENABLE
|
||||||
|
SRC += led.c
|
||||||
|
endif
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
/* Copyright 2018 Carlos Filoteo
|
||||||
|
*
|
||||||
|
* 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 "ut47.h"
|
||||||
|
#ifdef LED_ENABLE
|
||||||
|
#include "protocol/serial.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void matrix_init_kb(void) {
|
||||||
|
// put your keyboard start-up code here
|
||||||
|
// runs once when the firmware starts up
|
||||||
|
|
||||||
|
matrix_init_user();
|
||||||
|
}
|
||||||
|
|
||||||
|
void matrix_scan_kb(void) {
|
||||||
|
// put your looping keyboard code here
|
||||||
|
// runs every cycle (a lot)
|
||||||
|
|
||||||
|
matrix_scan_user();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool process_record_kb(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
// put your per-action keyboard code here
|
||||||
|
// runs for every action, just before processing by the firmware
|
||||||
|
if (record->event.pressed) {
|
||||||
|
#ifdef LED_ENABLE
|
||||||
|
serial_send((record->event.key.row*16)+record->event.key.col);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return process_record_user(keycode, record);
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_set_kb(uint8_t usb_led) {
|
||||||
|
// put your keyboard LED indicator (ex: Caps Lock LED) toggling code here
|
||||||
|
|
||||||
|
led_set_user(usb_led);
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
/* Copyright 2018 Carlos Filoteo
|
||||||
|
*
|
||||||
|
* 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 UT47_H
|
||||||
|
#define UT47_H
|
||||||
|
|
||||||
|
#include "quantum.h"
|
||||||
|
|
||||||
|
#define LAYOUT( \
|
||||||
|
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0a, K0b, \
|
||||||
|
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1a, K1b, \
|
||||||
|
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2a, K2b, \
|
||||||
|
K30, K31, K32, K33, K34, K35, K37, K38, K39, K3a, K3b \
|
||||||
|
) \
|
||||||
|
{ \
|
||||||
|
{ K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0a, K0b }, \
|
||||||
|
{ K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1a, K1b }, \
|
||||||
|
{ K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2a, K2b }, \
|
||||||
|
{ K30, K31, K32, K33, K34, KC_NO, K35, K37, K38, K39, K3a, K3b } \
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LAYOUT_kc( \
|
||||||
|
K00, K01, K02, K03, K04, K05, K06, K07, K08, K09, K0a, K0b, \
|
||||||
|
K10, K11, K12, K13, K14, K15, K16, K17, K18, K19, K1a, K1b, \
|
||||||
|
K20, K21, K22, K23, K24, K25, K26, K27, K28, K29, K2a, K2b, \
|
||||||
|
K30, K31, K32, K33, K34, K35, K37, K38, K39, K3a, K3b \
|
||||||
|
) \
|
||||||
|
LAYOUT( \
|
||||||
|
KC_##K00, KC_##K01, KC_##K02, KC_##K03, KC_##K04, KC_##K05, KC_##K06, KC_##K07, KC_##K08, KC_##K09, KC_##K0a, KC_##K0b, \
|
||||||
|
KC_##K10, KC_##K11, KC_##K12, KC_##K13, KC_##K14, KC_##K15, KC_##K16, KC_##K17, KC_##K18, KC_##K19, KC_##K1a, KC_##K1b, \
|
||||||
|
KC_##K20, KC_##K21, KC_##K22, KC_##K23, KC_##K24, KC_##K25, KC_##K26, KC_##K27, KC_##K28, KC_##K29, KC_##K2a, KC_##K2b, \
|
||||||
|
KC_##K30, KC_##K31, KC_##K32, KC_##K33, KC_##K34, KC_NO,KC_##K35, KC_##K37, KC_##K38, KC_##K39, KC_##K3a, KC_##K3b \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define LAYOUT_kc_ut47 LAYOUT_kc
|
||||||
|
|
||||||
|
#endif
|
||||||
+7
-5
@@ -780,12 +780,14 @@ void set_single_persistent_default_layer(uint8_t default_layer) {
|
|||||||
default_layer_set(1U<<default_layer);
|
default_layer_set(1U<<default_layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t update_tri_layer_state(uint32_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
||||||
|
uint32_t mask12 = (1UL << layer1) | (1UL << layer2);
|
||||||
|
uint32_t mask3 = 1UL << layer3;
|
||||||
|
return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3);
|
||||||
|
}
|
||||||
|
|
||||||
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) {
|
||||||
if (IS_LAYER_ON(layer1) && IS_LAYER_ON(layer2)) {
|
layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3));
|
||||||
layer_on(layer3);
|
|
||||||
} else {
|
|
||||||
layer_off(layer3);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void tap_random_base64(void) {
|
void tap_random_base64(void) {
|
||||||
|
|||||||
@@ -142,6 +142,7 @@ void send_char(char ascii_code);
|
|||||||
|
|
||||||
// For tri-layer
|
// For tri-layer
|
||||||
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
|
void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3);
|
||||||
|
uint32_t update_tri_layer_state(uint32_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3);
|
||||||
|
|
||||||
void set_single_persistent_default_layer(uint8_t default_layer);
|
void set_single_persistent_default_layer(uint8_t default_layer);
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user